Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Web интерфейс программы 
:(
    Опции темы
TheDestroyer
Дата 21.5.2009, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Продолжаю разбирать пример xvr:
На сколько я понял web_server.h и web_server.cpp - реализация поддержки http протокола, tcp_server.h и tcp_server.cpp - реализация сокетов и многопоточности.
То, чего нехватает (лишнее) - убрал из StdAfx.cpp (класс InitSeqBuilder), остальное в utils пока не мешает, уберу позже.
Проблему с нераспознанием типа решил установкой #include <winsock2.h> перед #include <windows.h> в utils.h
Теперь много ошибок при компиляции типа: 
Код

1>Компоновка...
1>tcp_server.obj : error LNK2019: ссылка на неразрешенный внешний символ __imp__setsockopt@20 в функции "public: bool __thiscall TCP_Server::do_init(int)" (?do_init@TCP_Server@@QAE_NH@Z)
1>web_server.obj : error LNK2001: неразрешенный внешний символ "__imp__setsockopt@20"
1>tcp_server.obj : error LNK2019: ссылка на неразрешенный внешний символ __imp__listen@8 в функции "public: bool __thiscall TCP_Server::do_init(int)" (?do_init@TCP_Server@@QAE_NH@Z)

т.е. не принимает функции setsockopt, listen,... Как это поправить?


Еще несколько вопросов:
1. Что описывает класс HTTP_SendAns? Его функции вижу, а как это одним словом называется не пойму..
2. Что означает последний параметр в функции send_file_data(d,find_file_type(get_file_ext(fname)),false); ? Похоже, что в хэдер будет добавлено Last-Modified: %s. Last-Modified — время последнего изменения пересылаемых данных. В каком случае это может пригодиться?
3. Мой сайт построен так, что он состоит не из отдельных html страничек, а из php файлов, которые выдают информацию на страницу в зависимости от запросов пользователя. Используется довольно много Javascript и Ajax. В данном случае вместо php используется C++. Вопрос: место куда лучше вставить динамическую генерацию кода страничек этоHTTP_SendAns::send_file1(string fname) ? Т.к. там 
string d=find_resource("web\\"+fname);
в переменной d, как я понял хранится код странички, которую сервер отошлет пользователю. Получается здесь надо вставить мою функцию, которая будет динамически создавать сожержимое страницы. Но для генерации этого содержимого надо знать переменные POST и GET запросов, хорошо бы знать cookies для идентификации пользователя (как сессии в php) и хранения некоторых его переменных. В каком месте доступны эти переменные ( POST и GET запросов) и есть ли здесь реализация cookies?


Это сообщение отредактировал(а) TheDestroyer - 21.5.2009, 00:29
PM MAIL   Вверх
Andrey44
Дата 21.5.2009, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 2
Всего: 26



Цитата

т.е. не принимает функции setsockopt, listen,... Как это поправить?

Код

#pragma comment(lib, "Ws2_32.lib")



--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
xvr
Дата 21.5.2009, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(TheDestroyer @ 21.5.2009,  00:26)
Продолжаю разбирать пример xvr:
На сколько я понял web_server.h и web_server.cpp - реализация поддержки http протокола, tcp_server.h и tcp_server.cpp - реализация сокетов и многопоточности.

Угу

Цитата

т.е. не принимает функции setsockopt, listen,... Как это поправить?
Уже ответили - прилинковать Ws2_32.lib

Цитата

Еще несколько вопросов:
1. Что описывает класс HTTP_SendAns? Его функции вижу, а как это одним словом называется не пойму..
Класс отвечает за формирование ответа

Цитата

2. Что означает последний параметр в функции send_file_data(d,find_file_type(get_file_ext(fname)),false); ? 

Код

void HTTP_SendAns::send_file_data(string data, string type, bool dynamic)
Если dynamic заданно как true, то отправленные данные будут помеченны как только что измененные (через Last-Modified). Что отключит их кэширование в браузере и по дороге. Предназначенно для отправки динамически сгенерированных форм, которые потенциально могут выдывать разные страницы при каждом вызове
Цитата

3. Мой сайт построен так, что он состоит не из отдельных html страничек, а из php файлов, которые выдают информацию на страницу в зависимости от запросов пользователя. Используется довольно много Javascript и Ajax. 
Ой, на такое не расчитанно.
Цитата

В данном случае вместо php используется C++. Вопрос: место куда лучше вставить динамическую генерацию кода страничек 
Поддерживается .asp, очень обрезанный и только JacaScript. 
Занимается этим функция void send_asp(HTTP_SendAns &A, string s);, но она в эти исходники не входит. Поддержка JS довольно сильно переплетена с остальной частью программы, если надо, могу попробовать ее оторвать  smile 
Цитата

этоHTTP_SendAns::send_file1(string fname) ? 
Почти, это
Код

void WEB_Server::process_file(HTTP_SendAns &A, string fname)
{
 if (get_file_ext(fname)!=".asp") A.send_file(fname); else
  {
   string data=A.send_file1(fname);
   if (!data.empty()) send_asp(A,data);
  }
}
строки 5,6
Цитата

Т.к. там string d=find_resource("web\\"+fname); в переменной d, как я понял хранится код странички, которую сервер отошлет пользователю.
Да
Цитата

Получается здесь надо вставить мою функцию, которая будет динамически создавать сожержимое страницы. 
Да
Цитата

Но для генерации этого содержимого надо знать переменные POST и GET запросов, 
Угу, поле A.reg содержит HTTP_ReadReq, содержащий распарсенный запрос
Переменные и методы в нем:
Код

header_only - true, если пришел запрос HEAD, т.е. не нужно формировать тело страницы
get_hdr - Возвращает запись из заголовка HTTP запроса по ID 
get_cgi - Возвращает параметр из POST запроса и/или параметр из URL (после знака '?')
is_hdr_exist и is_cgi_exist - Проверяют наличие заданного параметра в заголовке HTTP и теле запроса соотвественно

Цитата

хорошо бы знать cookies для идентификации пользователя (как сессии в php) и хранения некоторых его переменных. 
Cookie придется реализовывать вручную, доступ к заголовкам запроса и ответа есть, так что Cookie (RFC2965) и Set-Cookie (RFC2109)

PM MAIL   Вверх
TheDestroyer
Дата 21.5.2009, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Спасибо за ответы. 
Удалось скомпилировать консольное приложение, поставив заглушки на недостающие функции, прилинковав Ws2_32.lib и создав главную функцию int _tmain(int argc, _TCHAR* argv[]) в web_server.cpp
Пытаюсь запустить сервер, делаю так:
Код

int _tmain(int argc, _TCHAR* argv[])
{
    web_server.do_init(80);
      // далее логично вызвать    
      // web_server.run();
      // но это частная переменная класса TCP_Server
    return 0;
}

Как правильно инициализировать и запустить веб сервер?

Функцию find_resource сделал такой, чтобы хоть что-то вывело клиенту:
Код

string find_resource(string name)
{
return "hello, <br> check";
}

Цитата(xvr @  21.5.2009,  12:24 Найти цитируемый пост)
Поддерживается .asp, очень обрезанный и только JacaScript. 

Как JavaScript поддерживается на стороне сервера?

PM MAIL   Вверх
xvr
Дата 21.5.2009, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(TheDestroyer @ 21.5.2009,  14:42)
Спасибо за ответы. 
Удалось скомпилировать консольное приложение, поставив заглушки на недостающие функции, прилинковав Ws2_32.lib и создав главную функцию int _tmain(int argc, _TCHAR* argv[]) в web_server.cpp
Пытаюсь запустить сервер, делаю так:
Код

int _tmain(int argc, _TCHAR* argv[])
{
    web_server.do_init(80);
      // далее логично вызвать    
      // web_server.run();
      // но это частная переменная класса TCP_Server
    return 0;
}

Как правильно инициализировать и запустить веб сервер?

web_server.do_init достаточно - он запускает run в нитке. (Макросы MAIN_FUNC и RUN_MAIN из StdAfx.h)
После do_init нужно повиснуть (например в for(;;) Sleep(1000);}. Или крутить цикл оконных сообщений, или что нибудь еще  smile 
Цитата


Функцию find_resource сделал такой, чтобы хоть что-то вывело клиенту:
Код

string find_resource(string name)
{
return "hello, <br> check";
}

Ок
Цитата

Цитата(xvr @  21.5.2009,  12:24 Найти цитируемый пост)
Поддерживается .asp, очень обрезанный и только JacaScript. 

Как JavaScript поддерживается на стороне сервера?
Используется встроенный в Windows интерпретатор JavaScript.
PM MAIL   Вверх
TheDestroyer
Дата 23.5.2009, 01:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Цитата(xvr @  21.5.2009,  15:04 Найти цитируемый пост)
Используется встроенный в Windows интерпретатор JavaScript. 

А что может делать JavaScript на стороне сервера?

Удалось получить тестовую строку на клиенте!
Код

Для этого в код перед созданием сокета пришлось добавить
 // инициализация WSAStartup (из MSDN)
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
 wVersionRequested = MAKEWORD(2, 2);
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
        /* Tell the user that we could not find a usable */
        /* Winsock DLL.                                  */
        printf("WSAStartup failed with error: %d\n", err);
        return 1;
    }

 sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); // создание сокета

Похоже, это та часть, которую надо будет менять для компиляции этого исходника под linux?

Разбираюсь с  переменными, которые  присылаются на сервер через GET и POST запросы.

Поставил такой html код на выдачу клиенту:
Код

string find_resource(string name)
{
string page="";
page = page+ 
"<html>\
 <head>\
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\">\
  <title>Тег FORM</title>\
 </head>\
 <body>\
 <form action=\"/html/example/handler.php\">\
  <p><b>Как по вашему мнению расшифровывается аббревиатура &quot;ОС&quot;?</b></p>\
  <p><input type=\"radio\" name=\"answer\" value=\"a1\">Офицерский состав<Br>\
  <input type=\"radio\" name=\"answer\" value=\"a2\">Операционная система<Br>\
  <input type=\"radio\" name=\"answer\" value=\"a3\">Большой полосатый мух</p>\
  <p><input type=\"submit\"></p>\
 </form>\
 </body>\
</html>";
return page;

Не удается получить значения переменных param1, param2. Как их правильно получить? A.req.get_cgi не возвращает эти параметры. 
a1,a2 или a3 передаются в A.req.cgi_lines[1], т.е. все параметры с формы будут всегда в A.req.cgi_lines ?

PM MAIL   Вверх
xvr
Дата 23.5.2009, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(TheDestroyer @ 23.5.2009,  01:33)
Цитата(xvr @  21.5.2009,  15:04 Найти цитируемый пост)
Используется встроенный в Windows интерпретатор JavaScript. 

А что может делать JavaScript на стороне сервера?

Формировать из .asp html  smile Обрабатывать он может что угодно. Для этого в глобальное пространство имен JS добавляются необходимые переменные, функции и объекты. Они собственно и обеспечивают весь функционал. Так же можно пользоваться любыми ActiveX контролами.

Цитата

Удалось получить тестовую строку на клиенте!
Для этого в код перед созданием сокета пришлось добавить
 // инициализация WSAStartup (из MSDN)
 
Угу, у моего сервера main выглядит так:
Код

extern "C" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int)
{
 setlocale( LC_ALL, ".ACP" );

 WSADATA dat;
 WSAStartup(MAKEWORD(2,0),&dat);
 CoInitializeEx(0,COINIT_MULTITHREADED);
 InitOrder::do_initialize();

 MSG msg;
 while(GetMessage(&msg,0,0,0)) DispatchMessage(&msg);

 InitOrder::do_terminate();
 CoUninitialize();
 WSACleanup();

 return 0;
}


Цитата

 sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); // создание сокета
Это лишнее  smile 
Цитата

Похоже, это та часть, которую надо будет менять для компиляции этого исходника под linux?
Не только, в tcp_server.* есть некоторое количество функций WSA*, их надо будет заменить на эквивалентные из Linux. Так же там используется ожидание событий на сокете через Event'ы Windows. Linux этого не поддерживает. Придется делать либо неблокирующие сокеты либо ожидание через select/poll (или и то и другое)

Цитата

Разбираюсь с  переменными, которые  присылаются на сервер через GET и POST запросы.

Поставил такой html код на выдачу клиенту:
Код

string find_resource(string name)
{
string page="";
page = page+ 
"<html>\
 <head>\
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\">\
  <title>Тег FORM</title>\
 </head>\
 <body>\
 <form action=\"/html/example/handler.php\">\
  <p><b>Как по вашему мнению расшифровывается аббревиатура &quot;ОС&quot;?</b></p>\
  <p><input type=\"radio\" name=\"answer\" value=\"a1\">Офицерский состав<Br>\
  <input type=\"radio\" name=\"answer\" value=\"a2\">Операционная система<Br>\
  <input type=\"radio\" name=\"answer\" value=\"a3\">Большой полосатый мух</p>\
  <p><input type=\"submit\"></p>\
 </form>\
 </body>\
</html>";
return page;

Не удается получить значения переменных param1, param2. 
А кто собственно такие param1 & parm2?
Цитата

Как их правильно получить? A.req.get_cgi не возвращает эти параметры. 
a1,a2 или a3 передаются в A.req.cgi_lines[1], т.е. все параметры с формы будут всегда в A.req.cgi_lines ?
Если в WEB браузере загрузить эту страницу, а потом сделать 'submit' ее на ваш сервер (я так понимаю это и делается), то в через get_cgi будет доступен параметр 'answer' со значением 'a1', 'a2' или 'a3', в зависимости от того, что выбрал пользователь на странице

PM MAIL   Вверх
TheDestroyer
Дата 24.5.2009, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Цитата(xvr @  23.5.2009,  09:17 Найти цитируемый пост)
А кто собственно такие param1 & parm2?

Да, помимо опечатки, еще идея неверная была. Теперь клиенту отправляется это:
Код

page = page+ 
"<html>\
 <head>\
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\">\
  <title>Тег FORM</title>\
 </head>\
 <body>\
 <form action=\"/html/example/handler.php?param1=123&param2=321\" method=\"post\">\
  <p><b>Как по вашему мнению расшифровывается аббревиатура &quot;ОС&quot;?</b></p>\
  <p><input type=\"radio\" name=\"answer\" value=\"a1\">Офицерский состав<Br>\
  <input type=\"radio\" name=\"answer\" value=\"a2\">Операционная система<Br>\
  <input type=\"radio\" name=\"answer\" value=\"a3\">Большой полосатый мух</p>\
  <p><input type=\"submit\"></p>\
 </form>\
 </body>\
</html>";

Пытаюсь через A.req.get_cgi получить значения переданных параметров:
В A.req.get_cgi(); надо передавать string id, а что это за id и как его получить? Если докопать до "корня" этой функции, то видно, что производится операция 
Код

map<string,string> cgi_lines;

 Похоже, что создается список в виде "параметр, значение".
Поясните, плз, что тут происходит и как правильно получить параметр 'answer' со значением 'a1', 'a2' или 'a3', в зависимости от того, что выбрал пользователь на странице. Или для получения параметров, переданных через GET запрос в адресе после знака "?" (handler.php?param1=123&param2=321). Также если параметров несколько , то хотелось бы получить их все в переменные (как в php). Похоже, что надо узнать сколько их через A.req.cgi_lines.size и в цикле for присвоить соответствующим переменным их значения? 
Получается все переданные параметры со своими значениями будут храниться в A.req.cgi_lines независимо от того, как они были приняты через POST или GET? (возможно передавть POST и GET одновременно некорректно...)



Это сообщение отредактировал(а) TheDestroyer - 24.5.2009, 19:39
PM MAIL   Вверх
xvr
Дата 24.5.2009, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(TheDestroyer @ 24.5.2009,  19:35)
В A.req.get_cgi(); надо передавать string id, а что это за id и как его получить? 

Их надо знать. Предполагается, что вы сами формировали формы, которые клиент отправил вам, так что параметры вам должны быть известны
Цитата

Поясните, плз, что тут происходит и как правильно получить параметр 'answer' со значением 'a1', 'a2' или 'a3', в зависимости от того, что выбрал пользователь на странице. 
Собственно вызвать A.ret.get_cgi("answer"), оно вернет "a1", "a2" или "a3"
Цитата

Или для получения параметров, переданных через GET запрос в адресе после знака "?" (handler.php?param1=123&param2=321). 
И для них тоже
Цитата

Также если параметров несколько , то хотелось бы получить их все в переменные (как в php).
Такого интерфейса не предусмотрено, но его можно легко реализовать через обход A.req.cgi_lines (с помощью итератора)
Цитата

Получается все переданные параметры со своими значениями будут храниться в A.req.cgi_lines независимо от того, как они были приняты через POST или GET?
Да
Цитата

 (возможно передавть POST и GET одновременно некорректно...)
Одновременно и не получится - это типы одного и того же запроса. Но параметры после URL (через знак '?') вполне возможны и в POST запросе (хотя лучше этого не делать)

PM MAIL   Вверх
TheDestroyer
Дата 25.5.2009, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Спасибо, с GET и POST ясно.
Разбираюсь с Cookies. Следуя 
Цитата(xvr @  21.5.2009,  12:24 Найти цитируемый пост)
Cookie (RFC2965) и Set-Cookie (RFC2109)

Делаю так:
для записи cookies пока для тестов в функции  string HTTP_SendAns::send_file1(string fname) ставлю:
Код

 // тест отправки cookies
 print_time(NULL,NULL,0,true);
 //add_hdr_line("Set-Cookie2: Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\"; expires= %s",sout_lbuf.c_str());
 add_hdr_line("Set-Cookie: Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\";");

в функции void WEB_Server::process_file(HTTP_SendAns &A, string fname)
Пишу:
Код

 string str2 = A.req.get_hdr("Cookie");

Хочу прочитать записанное, на форме из предыдущего примера жму Submit или просто обновляю страницу.
К сожалению, возвращается пустое значение. Смотрю в папке Cookies браузера (IE), созданных мной cookies там нет :(. Если заходить на данный веб сервер через FireFox, то в его cookies запись появляется. Но несмотря на это, считывание cookies при повторном заходе на страницу не происходит. Что тут может быть не так?
Возможно, в IE проблема с синтаксисом самой записи, может необходимо указывать  expires=...
Как правильно получить cookies?
Хорошо бы устанавливать время жизни cookies. Как получить текущее время + 30мин или +1 день с помощью функции  print_time() ?
Для записи cookies планирую сделать функцию в классе HTTP_SendAns: HTTP_SendAns::SetCookie(string item, string value).

Также, получать параметры переданные через GET и POST, записывать и читать cookies надо в функции динамического формирования странички. Сейчас это функция string find_resource(string name) в файле StdAfx.cpp. Как лучше сделать доступными A.req.get_cgi("..."), A.req.get_hdr("Cookies") и SetCookie(...) в find_resource()?

PM MAIL   Вверх
xvr
Дата 25.5.2009, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(TheDestroyer @ 25.5.2009,  13:11)
для записи cookies пока для тестов в функции  string HTTP_SendAns::send_file1(string fname) ставлю:
Код

 // тест отправки cookies
 print_time(NULL,NULL,0,true);
 add_hdr_line("Set-Cookie: Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\";");

Хочу прочитать записанное, на форме из предыдущего примера жму Submit или просто обновляю страницу.
К сожалению, возвращается пустое значение. Смотрю в папке Cookies браузера (IE), созданных мной cookies там нет :(. 

Cookie привязываются к URL (точнее имени сервера), откуда была полученна страница. Возможно IE хочет увидеть этот URL где то явно (в записях заголовка или атрибуте Path), точно не знаю
Цитата

Возможно, в IE проблема с синтаксисом самой записи, может необходимо указывать  expires=...
Желательно
Цитата

Хорошо бы устанавливать время жизни cookies. Как получить текущее время + 30мин или +1 день с помощью функции  print_time() ?

Код

time_t tm=time(NULL)+30*60; // or 24*60*60
print_time("expires=","\r\n",tm);

Цитата

Также, получать параметры переданные через GET и POST, записывать и читать cookies надо в функции динамического формирования странички. 

Цитата

Сейчас это функция string find_resource(string name) в файле StdAfx.cpp. 
Нет, это функция получения содержимого. Все динамическое формирование должно происходить вне нее, базируясь на содержимом, которое она вернула.
А функция для формирования ответа, это WEB_Server::process_file, туда и надо вставлять генерацию динамического контента
Кроме того, есть специальная функция для обработки управляющих запросов -  WEB_Server::process_cmd (она сейчас пустая)

PM MAIL   Вверх
TheDestroyer
Дата 26.5.2009, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Пытаюсь динамически сгенерировать страницу. Делаю это так:
Код

void WEB_Server::process_file(HTTP_SendAns &A, string fname)
{
string page= ""; // содержимое отсылаемой страницы
string str1 = A.req.get_cgi("param1");
string str2 = A.req.get_hdr("Cookie");

 // тест отправки cookies
 time_t tm=time(NULL)+30*60; // + 30 мин or 24*60*60
 A.print_time(NULL,NULL,tm,true);
 A.add_hdr_line("Set-Cookie: Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\"; expires= %s;",A.lbuf.c_str());
 // конец теста отправки cookies

page +=  
"<html>\
 <head>\
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\">\
  <title>Тег FORM</title>\
 </head>\
 <body>\
 <form action=\"/html/example/handler.php?param1=123&param2=321\" method=\"post\">\
  <p><b>Как по вашему мнению расшифровывается аббревиатура &quot;ОС&quot;?</b></p>\
  <p><input type=\"radio\" name=\"answer\" value=\"a1\">Офицерский состав<Br>\
  <input type=\"radio\" name=\"answer\" value=\"a2\">Операционная система<Br>\
  <input type=\"radio\" name=\"answer\" value=\"a3\">Большой полосатый мух</p>\
  <p><input type=\"submit\"></p>\
 </form>\
 </body>\
</html>";

// отошлем содержимое
string d = page;
if (!d.empty()) A.send_file_data(d,find_file_type(get_file_ext(fname)),true);

Для проверки того, что получается при отправке и приеме сниффером (WireShark) проверяю запросы. Выявил странность: через браузер делаю запрос на сервер, сервер отвечает не одним пакетом, а двумя
сначала
Код

HTTP/1.1 200 OK
потом
Код

Server: MAC 1.0
Public: HEAD, PUT, GET
Date: Tue, 26 May 2009 07:54:45 GMT
Connection: close
Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"; expires= Tue, 26 May 2009 08:24:44 GMT;
Last-Modified: Tue, 26 May 2009 07:54:45 GMT
Content-Length: 556
Content-Type: text/html; charset=cp1251

Проверил аналогичный запрос на сервер Apache, он отвечает одним пакетом
Код

HTTP/1.1 200 OK
Date: Tue, 26 May 2009 07:46:51 GMT
Server: Apache/2.2.8 (Win32) PHP/5.2.6
Last-Modified: Tue, 26 May 2009 07:46:27 GMT
ETag: "1e0000000641ff-24e-46acbec9ce4c5"
Accept-Ranges: bytes
Content-Length: 590
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

Возможно проблема с cookies из-за этого. 
UPDATE:
Нет, похоже это не проблема, да отсылка идет по частям, но это не влияет на процесс. 
Удалось передать cookies следующим образом:
Код

 A.add_hdr_line("Set-Cookie: Customer=test_customer; expires=%s;",A.lbuf.c_str());
 A.add_hdr_line("Set-Cookie: Test=testval; expires=%s;",A.lbuf.c_str());

А принять так:
Код

string str2 = A.req.get_hdr("Cookie");

В итоге в str2 строка со значениями через точку с запятой. Похоже остется разделить их в переменные или массив для дальнейшей работы с ними.
Для получения времени пришлось переместить функцию print_time в классе Http_SendAns из private в public

Это сообщение отредактировал(а) TheDestroyer - 26.5.2009, 13:34
PM MAIL   Вверх
xvr
Дата 26.5.2009, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата

Для получения времени пришлось переместить функцию print_time в классе Http_SendAns из private в public
Лучше добавить в Http_SendAns метод для установки Cookie

PM MAIL   Вверх
TheDestroyer
Дата 26.5.2009, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Сделал установку и получение cookies. В итоге появились функции
Код

void HTTP_SendAns::SetCookie(string Item, string value, time_t exp_time)
{
string cookie="";
print_time(NULL,NULL,exp_time,true);
cookie = "Set-Cookie: "+Item+"="+value+"; "+"expires="+lbuf.c_str();
add_hdr_line(cookie.c_str());
}
void HTTP_ReadReq::get_cookies(string line)
{
 vector<string> cookie_vect; // массив строкового типа
 split(cookie_vect,line,';');
for(int i=0;i<cookie_vect.size();++i)
  {
   vector<string> s1;
   cookie_vect[i] = trim(cookie_vect[i]);
   split(s1,cookie_vect[i],'=',1);
   if (s1.empty()) continue;
   string key=transform(unescape_url(s1[0],true),tolower);
   if (key.empty()) continue;
   switch(s1.size())
   {
     case 1: cookie_lines[key]=""; break;
     case 2: cookie_lines[key]=unescape_url(s1[1],true); break;
    }
  } // for(int i=0;i<cookie_vect.size();++i)
}

class HTTP_ReadReq {
...
map<string,string> cookie_lines;
...
}; 

может пригодятся. Получать cookies точно также как и get_cgi или get_hdr.
В процессе добавления поддержки cookies выявил некорректную работу функции trim в StdAfx.cpp,  пришлось заменить
Код

if (p) s.erase(0,p-1);
на
if (p) s.erase(0,p);

Вроде теперь есть все инструменты для создания сайта. Но теперь встал вопрос о том, как добавить большие фрагменты JavaScript кода в фаил веб сервера. Просто вбивать их строковыми переменными явно неправильно. Хотелось бы просто загружать в строковую переменную содержимое .js файла и использовать ее. Как сделать так, чтобы JavaScript код был в отдельном .js файле для его удобного редактирования до комптляции и чтобы после компиляции все упаковывалось в один фаил? Такойже вопрос и с картинками для сайта.
PM MAIL   Вверх
xvr
Дата 26.5.2009, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(TheDestroyer @ 26.5.2009,  21:37)
Сделал установку и получение cookies. В итоге появились функции

Спасибо, пригодится
Цитата

Но теперь встал вопрос о том, как добавить большие фрагменты JavaScript кода в фаил веб сервера. Такойже вопрос и с картинками для сайта.
Для этого была предназначенна функция find_resource. Она искала заданный файл по набору путей:
  •  Файл по пути из registry HKLM\Software\XVR\MACServer\1.0\Res (XVR\MACServer\1.0 надо заменить на что-нибудь свое)
  •  Во всех zip файлах по пути из registry HKLM\Software\XVR\MACServer\1.0\Res
  •  В папке data рядом с exe'ником
  •  Во всех zip файлах в этой папке
  •  В zip файле res-pack.zip рядом с exe'ником
  •  В zip файле, помещенном в ресурс RESPACK (типа RC_DATA) самого exe'ника
Файлы с реализацией в атаче

Чуть не забыл - для работы этой функции нужно прилинковать zlib


Это сообщение отредактировал(а) xvr - 26.5.2009, 22:54

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  zipfile.zip 3,78 Kb
PM MAIL   Вверх
Страницы: (4) Все 1 [2] 3 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0689 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.