|
server 0.0.1
basicserverinfrastructure
|
00001 #include <stdlib.h> 00002 #include <string.h> 00003 #include <unistd.h> 00004 #include <ctype.h> 00005 00006 #include "http/request_parser.h" 00007 #include "interface/class.h" 00008 00009 00010 #define REMAINS(pars,done) \ 00011 ((pars)->buffer_used - ((done) - (pars)->buffer)) 00012 00013 00014 static 00015 inline 00016 char * 00017 httpRequestParserGetLine(char ** data) 00018 { 00019 char * line_end = strstr(*data, "\r\n"); 00020 char * ret = *data; 00021 00022 if (NULL == line_end) { 00023 return NULL; 00024 } 00025 00026 *line_end = 0; 00027 *data = line_end + 2; 00028 00029 return ret; 00030 } 00031 00032 static 00033 inline 00034 void 00035 httpRequestSkip(char ** data) 00036 { 00037 for (; 0 != **data && ! isalpha(**data); (*data)++); 00038 } 00039 00040 void httpRequestParserGetRequestLine(HttpRequest, char *); 00041 00042 void 00043 httpRequestParserParse(HttpRequestParser this) 00044 { 00045 static HttpRequest request = NULL; 00046 static char * data; // static pointer to unprocessed data 00047 char * line; 00048 int cont = 1; 00049 00050 while(cont) { 00051 switch(this->state) { 00052 case HTTP_REQUEST_GARBAGE: 00053 data = this->buffer; // initialize static pointer 00054 httpRequestSkip(&data); 00055 request = new(HttpRequest); 00056 00057 this->state = HTTP_REQUEST_START; 00058 break; 00059 00060 case HTTP_REQUEST_START: 00061 if (NULL == (line = httpRequestParserGetLine(&data))) { 00062 cont = 0; 00063 break; 00064 } 00065 00066 httpRequestParserGetRequestLine(request, line); 00067 00068 this->state = HTTP_REQUEST_REQUEST_LINE_DONE; 00069 break; 00070 00071 case HTTP_REQUEST_REQUEST_LINE_DONE: 00072 if (NULL == (line = httpRequestParserGetLine(&data))) { 00073 cont = 0; 00074 break; 00075 } 00076 00077 if (0 == strlen(line)) { 00078 this->state = HTTP_REQUEST_HEADERS_DONE; 00079 break; 00080 } 00081 00082 httpRequestParserGetHeader(request, line); 00083 break; 00084 00085 case HTTP_REQUEST_HEADERS_DONE: 00086 httpHeaderSort(request->header, request->nheader); 00087 00088 { 00089 char * nbody; 00090 00091 if (0 == request->nbody) { 00092 nbody = httpHeaderGet( 00093 request->header, 00094 request->nheader, 00095 "Content-Length"); 00096 00097 if (NULL == nbody) { 00098 this->state = HTTP_REQUEST_DONE; 00099 break; 00100 } 00101 else { 00102 request->nbody = atoi(nbody); 00103 } 00104 } 00105 00106 if (REMAINS(this, data) >= request->nbody) { 00107 request->body = calloc(1, request->nbody + 1); 00108 memcpy(request->body, data, request->nbody); 00109 data += request->nbody; 00110 this->state = HTTP_REQUEST_DONE; 00111 } 00112 } 00113 00114 break; 00115 00116 case HTTP_REQUEST_DONE: 00120 this->request_queue->requests[(this->request_queue->nrequests)++] = 00121 request; 00122 00126 memmove(this->buffer, data, REMAINS(this, data)); 00127 00128 this->buffer_used -= data - this->buffer; 00129 00133 if (0 == this->buffer_used) { 00134 cont = 0; 00135 } 00136 00140 this->state = HTTP_REQUEST_GARBAGE; 00141 00142 break; 00143 00144 default: 00145 break; 00146 } 00147 } 00148 } 00149 00150 // vim: set ts=4 sw=4: