|
Server 0.0.1
HTTP/REST server implementation
|
00001 00023 #include <stdlib.h> 00024 00025 #include "class.h" 00026 #include "cbuf.h" 00027 #include "stream.h" 00028 00029 #include "http/parser.h" 00030 #include "http/header.h" 00031 #include "http/interface/http_intro.h" 00032 00033 #include "utils/memory.h" 00034 #include "commons.h" 00035 00036 #define MIN(a,b) ((a)<(b)? (a) : (b)) 00037 00038 00039 ssize_t 00040 httpParserParse(void * _this, Stream st) 00041 { 00042 HttpParser this = _this; 00043 int cont = 1; 00044 ssize_t read; 00045 char * line; 00046 char * line_end; 00047 00048 if (cbufIsLocked(this->buffer)) { 00049 if (FALSE == this->ourLock) 00050 return 0; 00051 } 00052 else { 00053 cbufLock(this->buffer); 00054 this->ourLock = TRUE; 00055 } 00056 00057 if (NULL != this->incomplete) { 00058 cbufSetData(this->buffer, this->incomplete, this->isize); 00059 free(this->incomplete); 00060 this->incomplete = NULL; 00061 } 00062 00063 if (0 > (read = cbufRead(this->buffer, st))) { 00064 return read; 00065 } 00066 00067 while (cont) { 00068 switch(this->state) { 00069 case HTTP_MESSAGE_GARBAGE: 00070 cbufSkipNonAlpha(this->buffer); 00071 if (! cbufIsEmpty(this->buffer)) { 00072 this->state = HTTP_MESSAGE_START; 00073 } 00074 else { 00075 cbufRelease(this->buffer); 00076 this->ourLock = FALSE; 00077 cont = 0; 00078 } 00079 00080 break; 00081 00082 case HTTP_MESSAGE_START: 00083 if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { 00084 if (! cbufIsEmpty(this->buffer)) { 00085 this->isize = this->buffer->bused; 00086 this->incomplete = malloc(this->isize); 00087 memcpy(this->incomplete, 00088 cbufGetData(this->buffer, this->isize), 00089 this->isize); 00090 } 00091 cbufRelease(this->buffer); 00092 this->ourLock = FALSE; 00093 cont = 0; 00094 break; 00095 } 00096 00097 httpParserNewMessage(this, line, line_end); 00098 if (NULL == this->current) { 00099 cbufRelease(this->buffer); 00100 this->ourLock = FALSE; 00101 return -1; 00102 } 00103 httpParserRequestVars(this); 00104 00105 this->state = HTTP_MESSAGE_INTRO_DONE; 00106 break; 00107 00108 case HTTP_MESSAGE_INTRO_DONE: 00109 if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { 00110 if (! cbufIsEmpty(this->buffer)) { 00111 this->isize = this->buffer->bused; 00112 this->incomplete = malloc(this->isize); 00113 memcpy(this->incomplete, 00114 cbufGetData(this->buffer, this->isize), 00115 this->isize); 00116 } 00117 cbufRelease(this->buffer); 00118 this->ourLock = FALSE; 00119 cont = 0; 00120 break; 00121 } 00122 00123 if (0 == strlen(line)) { 00124 this->state = HTTP_MESSAGE_HEADERS_DONE; 00125 break; 00126 } 00127 00128 httpParserHeader(this, line, line_end); 00129 break; 00130 00131 case HTTP_MESSAGE_HEADERS_DONE: 00132 if (this->current->dbody == this->current->nbody) { 00133 this->state = HTTP_MESSAGE_DONE; 00134 break; 00135 } 00136 00137 if (cbufIsEmpty(this->buffer)) { 00138 cbufRelease(this->buffer); 00139 this->ourLock = FALSE; 00140 cont = 0; 00141 break; 00142 } 00143 00144 cbufIncRead( 00145 this->buffer, 00146 httpParserBody( 00147 this, 00148 cbufGetRead(this->buffer), 00149 this->buffer->bused)); 00150 break; 00151 00152 case HTTP_MESSAGE_DONE: 00153 { 00154 HttpHeader enc = hashGet( 00155 this->current->header, 00156 CSTRA("content-type")); 00157 00161 if (NULL != enc && 0 == strncasecmp( 00162 "application/x-www-form-urlencoded", 00163 enc->value[0], 00164 MIN(sizeof("application/x-www-form-urlencoded")-1, 00165 enc->nvalue[0]))) { 00167 httpParserPostVars(this); 00168 } 00169 00173 this->queue->msgs[(this->queue->nmsgs)++] = this->current; 00174 this->current = NULL; 00175 00179 this->state = HTTP_MESSAGE_GARBAGE; 00180 } 00181 break; 00182 00183 default: 00184 break; 00185 } 00186 } 00187 00188 return this->queue->nmsgs; 00189 } 00190 00191 // vim: set ts=4 sw=4: