ISAPI Ext. Как разумно формировать HTTP контент (VC++)?
От: creasysee  
Дата: 05.12.07 18:40
Оценка:
Вопрос касается именно ISAPI Extension dll, а не ATL Server, где с использованием HelloWorld.srf более менее все ясно.
В вольшинстве случаев примеры ISAPI приложений содержат код, который формирует HTML код для отправки клиенту непосредственно в функциях. Например MSDN:
DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB)
{
    ...
    char szStatus[]  = "200 OK";
    char szContent[] = "<html><body>Hello World from ISAPI.</body>
                       </html>";
    ...

На больших проектах это вносит определенную проблему.
До определенной степени достаточно следующей реализации:
const CString sHead = "<html><head>";
const CString sScriptStart = "<script language=JavaScript>";
const CString sScriptEnd = "</script>";
const CString sBody = "</head><body>";
const CString sBodyEnd = "</body></html>";

void CmyisapiExtension::Func1(CHttpServerContext* pCtxt, LPCTSTR sString1, long lNum1)
{
    StartContent(pCtxt);
    ModifyHeader(pCtxt);
        CMyClass x;
        CString res = x.GetFunc1(sString1, lNum1);
    *pCtxt << sHead + sScriptStart + "function onButtClick(){ ляляля уже проблема }"
             + sScriptEnd + sBody + "Получен результат: " + res + sBodyEnd; 
    EndContent(pCtxt);
}

Но когда проект уже перерос возможность так себя строить, как быть? Кто как решает эти вопросы?

Первое что приходит на ум — использовать HTML-ресурсы вида IDR_HTML1 с содержимым вида:
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<TITLE></TITLE>
</HEAD>
<BODY>
%Res%
</BODY>
</HTML>

И как то использовать этот вариант, но как?
Или некий класс работы с шаблонами, и грузить шаблоны по мере работы?
Re: ISAPI Ext. Как разумно формировать HTTP контент (VC++)?
От: astral_marine  
Дата: 05.12.07 19:44
Оценка:
C>Или некий класс работы с шаблонами, и грузить шаблоны по мере работы?

Да, можно вынести во внешние шаблоны, и парсить по мере необходимости. Так не прийдется лезть в код что бы поменять какой-нибудь цвет, в программе же будет хранится только логика работы приложения.
Re: ISAPI Ext. Как разумно формировать HTTP контент (VC++)?
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.12.07 05:53
Оценка:
Здравствуйте, creasysee, Вы писали:

C>Вопрос касается именно ISAPI Extension dll, а не ATL Server, где с использованием HelloWorld.srf более менее все ясно.

C>В вольшинстве случаев примеры ISAPI приложений содержат код, который формирует HTML код для отправки клиенту непосредственно в функциях. Например MSDN:
Вообще-то именно по этой причине генераторы, основанные на шаблонной разметке, вытеснили императивные генераторы. PHP, JSP, ASP[.NET] и так далее позволяют гораздо лучше разделять разметку и логику.
Поэтому вопрос номер 1: вам точно нужен ISAPI?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: ISAPI Ext. Как разумно формировать HTTP контент (VC++
От: creasysee  
Дата: 07.12.07 16:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вообще-то именно по этой причине генераторы, основанные на шаблонной разметке, вытеснили императивные генераторы. PHP, JSP, ASP[.NET] и так далее позволяют гораздо лучше разделять разметку и логику.

S>Поэтому вопрос номер 1: вам точно нужен ISAPI?

Да. Очень критична скорость обработки и ответа сервера при взаимодействии с существующими библиотеками на VC++. Нужно именно на C++ и именно ISAPI Ext.
Поэтому для ускорения думаю сделать следующее:
1. Пропарсить исходные HTML страницы из внешних файлов и разделить на блоки, от начала страницы до первого параметра замены (типа {{var1}}), от текущего параметра до следующего.
2. Каждый фрагмент положить в <map>, индексируя именем параметра. Каждый <map> будет создан для свой страницы.
3. Сделать это все в конструкторе ISAPI. Отожрет может несколько метров, но терпимо.

Тогда работа функции будет выглядеть примерно следующим образом:
void CmyisapiExtension::Show(CHttpServerContext* pCtxt, LPCTSTR sParam1, long lParam2) {
    // Вычисление данных ... var1, var2, ..., var10
        StartContent(pCtxt);
    *pCtxt << m_Map_Show.find("var1")->second + var1;
        *pCtxt << m_Map_Show.find("var2")->second + var2;
        ...
    *pCtxt << m_Map_Show.find("var10")->second + var10;
        *pCtxt << m_Map_Show.find("end")->second + var10;
    EndContent(pCtxt);
}

Недостатки:
1. Писать парсер, хоть и простой.
2. Проблема с повторами имен параметров в HTML. Можно как-то обойти, если пошевелить мозгами.
Достоинства:
1. Быстро.

Пытался использовать CStencil из ATL сервера — громоздко.
Может есть более удобные способы?
Re[3]: ISAPI Ext. Как разумно формировать HTTP контент (VC++
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.12.07 07:21
Оценка: 6 (1)
Здравствуйте, creasysee, Вы писали:

C>Здравствуйте, Sinclair, Вы писали:


S>>Вообще-то именно по этой причине генераторы, основанные на шаблонной разметке, вытеснили императивные генераторы. PHP, JSP, ASP[.NET] и так далее позволяют гораздо лучше разделять разметку и логику.

S>>Поэтому вопрос номер 1: вам точно нужен ISAPI?

C>Да. Очень критична скорость обработки и ответа сервера при взаимодействии с существующими библиотеками на VC++. Нужно именно на C++ и именно ISAPI Ext.

Ну, ребята, я бы на вашем месте всё же обратился бы к профайлеру.

Немного теории:
1. Быстрее всего грузятся страницы из локального кэша. Поэтому самый охрененный performance boost дает хидер Content-Expiration
2. К сожалению, очень редко удается заранее спрогнозировать изменение динамического контента. Поэтому следующим по скорости отдачи идет 304 Not Modified (в предположении, что есть недорогой способ определить, обновился ли результат запроса)
3. Хитрые люди еще и складывают ответы в кэш сервера. Тогда те, кто их уже получал, получат 304, а те, кто пришел в первый раз, получат готовый контент из кэша.
4. И только если ничего из этого не получилось, нужно заняться собственно "вычислением" ответа.

В вычислении ответа важна скорострельность в подготовке фрагментов.
По моему опыту, при подготовке респонса дороже всего стоит обращение к СУБД, дальше идет стоимость протаскивания респонса через сокет. Собственно, скорость прокладки между первым и вторым большой роли не играет.
Если ты уверен, что у тебя именно такой редкий случай, то быстрее всего работает вот такой код:
*pCtxt << "<html><head><title>Превед</title></head><body>Данное 1 = " << var1 << "</body></html>";

Примечание: я сам ISAPI Extension никогда не писал, опираюсь на общие соображения.
Мап тебе никакой не нужен. Если шаблоны статические, то надо просто сделать примитивный генератор кода на основе парсера .csp-файлов. Повторы роли не играют.
Можно пойти по стандартному пути: используешь <% %> для встраиваемого кода, <%= somexpression%> превращается в *pCtxt << somexpression;
Рекомендую поискать стандартные решения.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.