Advertisement
captmicro

test_webserver - webserver with lua scripting!

Oct 28th, 2012
370
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.58 KB | None | 0 0
  1. #include "main.h"
  2.  
  3. WSADATA wsaData;
  4. SOCKET listenSocket;
  5.  
  6. char configFile[MAX_PATH] = {0};
  7. lua_State *luastate = NULL;
  8. char *lua_print_buffer = NULL;
  9.  
  10. int main(int argc, char *argv[])
  11. {
  12.     GetCurrentDirectoryA(MAX_PATH, configFile);
  13.     lstrcatA(configFile, "\\webcfg.ini");
  14.  
  15.     char port[16];
  16.     GetPrivateProfileStringA("MAIN", "port", "8080", port, 16, configFile);
  17.  
  18.     printf("Starting winsock...\n");
  19.     //Startup winsock
  20.     int startupResult = 0;
  21.     startupResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  22.     if (startupResult != 0) {
  23.         printf("WSAStartup failed: %d\n", startupResult);
  24.         return 1;
  25.     }
  26.  
  27.     //Create server socket
  28.     struct addrinfo *result = NULL;
  29.     struct addrinfo *ptr = NULL;
  30.     struct addrinfo hints;
  31.  
  32.     ZeroMemory(&hints, sizeof(hints));
  33.     hints.ai_family = AF_INET;
  34.     hints.ai_socktype = SOCK_STREAM;
  35.     hints.ai_protocol = IPPROTO_TCP;
  36.     hints.ai_flags = AI_PASSIVE;
  37.  
  38.     //--Resolve address & port
  39.     int gaiResult = 0;
  40.     gaiResult = getaddrinfo(NULL, port, &hints, &result);
  41.     if (gaiResult != 0) {
  42.         printf("getaddrinfo failed: %d\n", gaiResult);
  43.         WSACleanup();
  44.         return 1;
  45.     }
  46.        
  47.     //--Create socket
  48.     listenSocket = INVALID_SOCKET;
  49.  
  50.     for (int i = 0; i < 5; i++)
  51.     {
  52.         listenSocket = socket(result->ai_family,
  53.             result->ai_socktype, result->ai_protocol);
  54.         if (listenSocket != INVALID_SOCKET) break;
  55.         printf("Failed to create socket [Attempt %d]\n", i);
  56.         Sleep(1000);
  57.     }
  58.  
  59.     if (listenSocket == INVALID_SOCKET) {
  60.         printf("Failed to create socket: %d\n", WSAGetLastError());
  61.         freeaddrinfo(result);
  62.         WSACleanup();
  63.         return 1;
  64.     }
  65.  
  66.     //--Bind socket
  67.     int bindResult = 0;
  68.     bindResult = bind(listenSocket, result->ai_addr,
  69.         (int)result->ai_addrlen); //bind to localhost:port
  70.     if (bindResult == SOCKET_ERROR) {
  71.         printf("Fail to bind socket: %d\n", WSAGetLastError());
  72.         freeaddrinfo(result);
  73.         WSACleanup();
  74.         return 1;
  75.     }
  76.    
  77.     freeaddrinfo(result);
  78.  
  79.     //Start listening
  80.     if (listen(listenSocket, MAX_CONNECTIONS) == SOCKET_ERROR) {
  81.         printf("Failed to listen: %d\n", WSAGetLastError());
  82.         closesocket(listenSocket);
  83.         WSACleanup();
  84.         return 1;
  85.     }
  86.  
  87.     /*Non-blocking
  88.     unsigned long nonblocking = 1;
  89.     ioctlsocket(listenSocket, FIONBIO, &nonblocking);*/
  90.  
  91.     //Startup lua
  92.     printf("Creating lua state...\n");
  93.     luastate = lua_open();
  94.     luaL_openlibs(luastate);
  95.     lua_register(luastate, "print", l_print);
  96.  
  97.     //Server loop
  98.     printf("Entering server loop...\n");
  99.     char buffer[BUFFER_SIZE] = {0};
  100.  
  101.     while (!GetAsyncKeyState(VK_END))
  102.     {
  103.         memset(buffer, 0, BUFFER_SIZE);
  104.         SOCKET cs = INVALID_SOCKET;
  105.  
  106.         cs = accept(listenSocket, NULL, NULL);
  107.         if (cs == INVALID_SOCKET) continue;
  108.  
  109.         int sz = recv(cs, buffer, BUFFER_SIZE, 0);
  110.         if (sz > 0)
  111.         {
  112.             if (lstrcmpn(buffer, "GET", 3) == 0)
  113.             {
  114.                 parsesendGET(&cs, buffer);
  115.             }
  116.         }
  117.  
  118.         closesocket(cs);
  119.     }
  120.  
  121.     lua_close(luastate);
  122.     closesocket(listenSocket);
  123.     WSACleanup();
  124.  
  125.     return 0;
  126. }
  127.  
  128. void parsesendGET(SOCKET *cs, char *request)
  129. {
  130.     char *newreq = (char*)halloc(lstrlenA(request));
  131.     char lastReqChar = *request; int nridx = 0;
  132.     while (*request != NULL)
  133.     {
  134.         if (*request != '\r' && !(*request == '\n' && lastReqChar == '\n'))
  135.         {
  136.             newreq[nridx++] = *request;
  137.             lastReqChar = *request;
  138.         }
  139.         *request++;
  140.     }
  141.     newreq[lstrlenA(newreq)-1] = '\0';
  142.    
  143.     char *pnewreq = newreq;
  144.     while (*pnewreq != NULL)
  145.     {
  146.         if (*pnewreq == '\n') *pnewreq = '\0';
  147.         pnewreq++;
  148.     }
  149.  
  150.     char *GETline = newreq;
  151.     char *GETfile = GETline+4;
  152.     while (*GETline != NULL)
  153.     {
  154.         if (*GETline == ' ') *GETline = '\0';
  155.         *GETline++;
  156.     }
  157.    
  158.     char returnFile[MAX_PATH] = {0};
  159.     if (lstrcmpA(GETfile, "/") == 0)
  160.         lstrcpyA(returnFile, HTTP_DEFAULT_FILE);
  161.     else
  162.         lstrcpyA(returnFile, GETfile);
  163.     GETfile = &returnFile[0];
  164.  
  165.     char *GEText = NULL;
  166.     while (*GETfile != NULL)
  167.     {
  168.         if (*GETfile == '.') GEText = GETfile+1;
  169.         *GETfile++;
  170.     }
  171.  
  172.     char returnExt[16] = {0};
  173.     lstrcpyA(returnExt, "ext_");
  174.     lstrcatA(returnExt, GEText);
  175.     hfree(newreq);
  176.  
  177.     char mimeType[MAX_PATH] = {0};
  178.     if (GEText == NULL) lstrcpyA(mimeType, "text/plain");
  179.     else GetPrivateProfileStringA("TRANSLATIONS", returnExt, "text/plain",
  180.         mimeType, MAX_PATH, configFile);
  181.  
  182.     char filePath[MAX_PATH] = {0};
  183.     GetCurrentDirectoryA(MAX_PATH, filePath);
  184.     int currdirsize = lstrlenA(filePath);
  185.     lstrcatA(filePath, returnFile);
  186.    
  187.     //Read file
  188.     printf("File requested: %s\n", &filePath[0]+currdirsize);
  189.     char *fc = NULL; DWORD fsize = 0;
  190.  
  191.     HANDLE file = INVALID_HANDLE_VALUE;
  192.     file = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ,
  193.         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  194.     if (file == INVALID_HANDLE_VALUE)
  195.     {
  196.         printf("Error opening file! %d\n", GetLastError());
  197.         fc = (char*)halloc(KB * 5);
  198.         GetPrivateProfileSectionA("ERROR_404", fc, KB * 5, configFile);
  199.         if (lstrlenA(fc) > 0) ProfileSection2str(fc);
  200.         else lstrcpyA(fc, HTTP_404_CONTENT);
  201.         lstrcpyA(mimeType, "text/html");
  202.     }
  203.     else
  204.     {
  205.         fsize = GetFileSize(file, NULL);
  206.         printf("File size: %d\n", fsize);
  207.         fc = (char*)halloc(fsize+8);
  208.         DWORD bytesRead = 0;
  209.         if (ReadFile(file, fc, fsize, &bytesRead, NULL) == FALSE)
  210.         {
  211.             printf("Error reading file! %d\n", GetLastError());
  212.             CloseHandle(file);
  213.         }
  214.         CloseHandle(file);
  215.     }
  216.  
  217.     //Build HTTP response
  218.     lua_print_buffer = (char*)halloc(LUA_PRINTBUFFER_SIZE);
  219.     *lua_print_buffer = '\n';
  220.     char *data = (char*)halloc(512+fsize+LUA_PRINTBUFFER_SIZE);
  221.  
  222.     char httpVer[64] = {0};
  223.     wsprintfA(httpVer, HTTP_VER, (fsize==0)?"404 Not Found":"200 OK");
  224.     lstrcatA(data, HTTP_VER);
  225.     lstrcatA(data, HTTP_SERVER);
  226.     lstrcatA(data, HTTP_CACHECONTROL);
  227.     lstrcatA(data, HTTP_KEEPALIVE);
  228.     lstrcatA(data, HTTP_CONNECTION);
  229.     char httpContenttype[64] = {0};
  230.     wsprintfA(httpContenttype, HTTP_CONTENTTYPE, mimeType);
  231.     lstrcatA(data, httpContenttype);
  232.  
  233.     if (fc != NULL)
  234.     {
  235.         char *lend = ParseLuaTags(fc);
  236.         lstrcatA(data, fc);
  237.         if (lend != NULL)
  238.         {
  239.             lstrcatA(data, lend);
  240.             if (lstrlenA(lua_print_buffer) > 0)
  241.                 lstrcatA(data, lua_print_buffer);
  242.             hfree(lua_print_buffer);
  243.         }
  244.         hfree(fc);
  245.     }
  246.  
  247.     send(*cs, data, lstrlenA(data), 0);
  248.  
  249.     hfree(data);
  250. }
  251.  
  252. char *ParseLuaTags(char *html)
  253. {
  254.     char *ptr = html;
  255.     char *luastart = NULL;
  256.     char *luaend = NULL;
  257.     int lualen = -1;
  258.  
  259.     while (*ptr != NULL)
  260.     {
  261.         if (luastart == NULL)
  262.         {
  263.             if (*ptr == '<' && *++ptr == 'l' && *++ptr == 'u' &&
  264.                 *++ptr == 'a' && *++ptr == '>')
  265.             {
  266.                 *(ptr - 4) = '\0';
  267.                 luastart = ++ptr;
  268.                 if (*luastart == '\r') *luastart++;
  269.                 if (*luastart == '\n') *luastart++;
  270.             }
  271.         } else {
  272.             if (*ptr == '<' && *++ptr == '/' && *++ptr == 'l' &&
  273.                 *++ptr == 'u' && *++ptr == 'a' && *++ptr == '>')
  274.             {
  275.                 luaend = ptr - 7;
  276.             }
  277.         }
  278.         *ptr++;
  279.     }
  280.  
  281.     if (luastart != NULL && luaend != NULL)
  282.     {
  283.         lualen = luaend - luastart;
  284.         char *luastr = (char*)halloc(lualen + 1);
  285.         lstrcpynA(luastr, luastart, lualen);
  286.         //printf("Lua: %X %X %d\n", luastart, luaend, lualen);
  287.         luaL_dostring(luastate, luastr);
  288.         hfree(luastr);
  289.     }
  290.     return luaend+8;
  291. }
  292.  
  293. LUA_FUNCTION(l_print)
  294. {
  295.     if (!lua_isstring(L, 1)) return 0;
  296.     const char *str = lua_tostring(L, 1);
  297.     if (lstrlenA(lua_print_buffer) + lstrlenA(str) < LUA_PRINTBUFFER_SIZE)
  298.         lstrcatA(lua_print_buffer, str);
  299.     return 0;
  300. }
  301.  
  302. void ProfileSection2str(char *sec)
  303. {
  304.     char *ptr = sec;
  305.     while (true)
  306.     {
  307.         if (*ptr == NULL)
  308.         {
  309.             if (*(ptr+1) == NULL) break;
  310.             *ptr = '\n';
  311.         }
  312.         *ptr++;
  313.     }
  314. }
  315.  
  316. int lstrcmpn(char *str1, char *str2, int size)
  317. {
  318.     for (int i = 0; i < size; i++)
  319.     {
  320.         if (str1[i] != str2[i]) return 1;
  321.     }
  322.     return 0;
  323. }
  324.  
  325. int lstrcnt(char *str1, char chr)
  326. {
  327.     char *ptr = str1;
  328.     int charCount = 0;
  329.     while (*ptr != NULL)
  330.     {
  331.         if (chr == *ptr) charCount++;
  332.         *ptr++;
  333.     }
  334.     return charCount;
  335. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement