Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   [c++] Класс Веб-сервер (https://forum.antichat.xyz/showthread.php?t=43297)

ZaCo 28.06.2007 15:36

[c++] Класс Веб-сервер
 
Вчера возникла задача обслуживания своего приложения через веб, но чтобы не возиться с локализацией я решил написать более-менее универсальный класс на си++ для решения этой задачи. Класс представляет собой набор методов для воссоздания модели настоящего веб-сервера, тут конечно ни о каком соответствии с rfc и речи быть не может, однако для получения и соответствующей обработки переменных передаваемых в get\post\cookie его в общем-то хватает.
Пример программы, которая складывает два числа и выводит ip-адрес пользователя на странице:
Код:

#include <winsock2.h>
#include <string>

#include "swebs.hpp"
namespace std
{

typedef map <string, string> var_map;
void func(int,var_map *,p_selfOut);

void func(int id,var_map * vars,p_selfOut outF)
 {
  string out_s;

  out_s="HTTP/1.1 200 OK\n";
  out_s+="Connection: close\n";
  out_s+="Content-Type: text/html\n\n";
  outF(id, out_s.c_str(), out_s.length());


  var_map & Vars=*vars;

  string data1=Vars["a"],data2=Vars["b"];
 
  if(data1.empty()||data2.empty())//form
  {
    out_s="Welcome: "+Vars["REMOTE_ADDR"]+"<br>\n";
    outF(id, out_s.c_str(), out_s.length());
   
    out_s="<html> <head>  <title>WebS test</title> </head> <form method=post>  <input type=text name=a>  <input type=text name=b>  <input type=submit> </form></html>";
    outF(id, out_s.c_str(), out_s.length());
  }
  else
  {
    char out_s[256];
    strcpy(out_s,"<b>sum is: </b>");
    sprintf(&out_s[strlen(out_s)],"%d",atoi(data1.c_str())+atoi(data2.c_str()));
    outF(id, out_s, strlen(out_s));
  }

  delete vars;
 }

int main(int argc, char * argv[])
 {
  WSADATA WSA;
  if(WSAStartup(MAKEWORD(2,2), &WSA) != 0) return 0;
  //
  cWebs server(func, 6669);
  bool ok=server.Bind();
  if(ok) server.Listen();
  else puts("binding error");
  return 0;
 }
}

Сначала идет описание прототипа пользовательской функции:
Код:

void func(int id,var_map * vars,p_selfOut outF)
Ее задача состоит как раз-таки в обработке переданных переменных и выводе соответствующей странички в качестве ответа. Передав конструктору адрес функции, при каждом новом запросе к веб-серверу, объект класса cWebs сам вызовет функцию и указатель на обьект типа карта (map), (предоставляя тем самым удобный пхп-подобный доступ к переменным), адрес-функцию Out и некоторое int значение id, которое функция сама должна передать в Out для вывода данных в ответ на исходный хттп-запрос. Прототип функции Out:

Код:

void Out(int ,const char *, int);
Второй аргумент представляет собой строку-указатель, третий длину строки.

Несмотря на то, что класс обеспечивает лишь элементарные возможности http-запроса, он в то же время предоставляет и простую их обработку пользовательской функцией. Все переданные переменные сохраняются в карте *vars при этом метод которым они передавались не учитывается. Одновременно через *vars имеется доступ к переменным окружения: REMOTE_ADDR (ИП пользователя) и GET_FILE (запрашиваемый файл в запросе).

ps иерархия переменных: get, cookie, post. то есть, значение get-переменной 'a', перепишется значением post-переменной 'a', если таковая имеется.



Исходники: http://zaco.itdefence.ru/webs/

Pochka 28.06.2007 17:29

Цитата:

WSAStartup(MAKEWORD(2,2), &WSA)
:D откуда скопипастил?

ZaCo 28.06.2007 18:36

не помню,

зы вообще говоря, в пользовательской функции отправлять ответ можно напрямую - писать по дексриптору id :)


Время: 18:56