My fork of the HTTPServer (working)
Embed:
(wiki syntax)
Show/hide line numbers
HTTPServer.cpp
00001 #include "HTTPServer.h" 00002 #include "NetServer.h" 00003 00004 using namespace std; 00005 using namespace mbed; 00006 00007 //unsigned int gconnections = 0; 00008 00009 unsigned int mbed::hash(unsigned char *str) { 00010 unsigned int hash = 5381; 00011 int c; 00012 while((c = *(str++))!=(unsigned char)'\0') { 00013 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ 00014 } 00015 return hash; 00016 } 00017 00018 HTTPConnection::HTTPConnection(HTTPServer *pparent, struct tcp_pcb *pcb) 00019 : TCPConnection(pparent, pcb), request_incomplete(true), data(NULL), 00020 request_handler(NULL), request_status(HTTP_NotFound), parent(pparent), 00021 _request_url(NULL), _request_type(0), _request_headerfields(NULL), 00022 _request_length(0), _request_arg_key(NULL), _request_arg_value(NULL), 00023 _request_arg_state(0), emptypolls(0) { 00024 } 00025 00026 HTTPConnection::~HTTPConnection() { 00027 deleteRequest(); 00028 emptypolls = 0; 00029 } 00030 00031 const char *HTTPConnection::getField(char *key) const { 00032 unsigned int h = hash((unsigned char *)key); 00033 return _request_fields.find(h)->second; 00034 } 00035 00036 void HTTPConnection::addField(char *key, char *value) { 00037 unsigned int h = hash((unsigned char *)key); 00038 if(parent->isField(h)) { 00039 _request_fields.insert( make_pair(h, value)); 00040 } 00041 } 00042 00043 void HTTPConnection::send() { 00044 int i = sndbuf(); 00045 if(!request_incomplete&&i) { 00046 switch(request_handler->send(this, i)) { 00047 case HTTP_SuccessEnded: 00048 case HTTP_Failed: { 00049 deleteRequest(); 00050 release_callbacks(); 00051 NetServer::get()->free(this); 00052 close(); 00053 } break; 00054 default: 00055 break; 00056 } 00057 } else { 00058 if(emptypolls>10) { 00059 release_callbacks(); 00060 NetServer::get()->free(this); 00061 close(); 00062 } 00063 } 00064 } 00065 00066 void HTTPConnection::store(void *d, struct pbuf *p) { 00067 int len = p->len-(((int)d)-((int)p->payload)); 00068 do { 00069 switch(request_handler->data(this, d, len)) { 00070 case HTTP_SuccessEnded: 00071 case HTTP_Failed: { 00072 deleteRequest(); 00073 release_callbacks(); 00074 NetServer::get()->free(this); 00075 close(); 00076 } break; 00077 default: 00078 break; 00079 } 00080 p = p->next; 00081 if(p) { 00082 len = p->len; 00083 d = static_cast<char *>(p->payload); 00084 } 00085 } while(_request_type&&p); 00086 } 00087 00088 void HTTPConnection::err(err_t err) { 00089 printf("Error\n"); 00090 release_callbacks(); 00091 NetServer::get()->free(this); 00092 } 00093 00094 err_t HTTPConnection::poll() { 00095 send(); 00096 return ERR_OK; 00097 } 00098 00099 err_t HTTPConnection::sent(u16_t len) { 00100 return poll(); 00101 } 00102 00103 err_t HTTPConnection::recv(struct pbuf *q, err_t err) { 00104 struct pbuf *p = q; 00105 int i; 00106 char *data; 00107 if(err == ERR_OK && p != NULL) { 00108 /* Inform TCP that we have taken the data. */ 00109 recved(p->tot_len); 00110 data = static_cast<char *>(p->payload); 00111 00112 // :1 00113 // Looking if it's GET, POST, 00114 // Followup from an incomplete request Header, 00115 // POST data or just crap (DEL, HEAD ...). 00116 if(!_request_type&&(strncmp(data, "GET ", 4) == 0)) { 00117 _request_type = GET; // Need :2 00118 } else if(!_request_type&&(strncmp(data, "POST ", 5) == 0)) { 00119 _request_type = POST; // Need :2 00120 } else if(_request_type&&request_incomplete) { 00121 getFields(&p, &data); // Need :3 00122 } else if(_request_type == POST) { 00123 // Followup (Data) // Exits 00124 data = static_cast<char *>(p->payload); 00125 store(data, p); 00126 emptypolls = 0; 00127 pbuf_free(q); 00128 data = NULL; 00129 return ERR_OK; 00130 } else { 00131 pbuf_free(q); // Exits 00132 data = NULL; 00133 return ERR_OK; 00134 } 00135 00136 // :2 00137 // Processing first POST or GET Packet 00138 // need :3 v--- If its 0 we have followup header data. 00139 if(_request_type&&!_request_url) { 00140 char *pagename = (char *)(data + _request_type); 00141 for(i = _request_type; i < p->len; i++) { 00142 if((data[i] == ' ') || (data[i] == '\r') || (data[i] == '\n')) { 00143 data[i] = 0; 00144 data = &data[i+1]; 00145 break; 00146 } 00147 } 00148 00149 if((pagename[0] == '/') && (pagename[1] == 0)) { 00150 pagename = "/index.htm"; 00151 } 00152 00153 i = strlen(pagename); 00154 _request_url = new char[i+1]; 00155 memcpy(_request_url, pagename, i); 00156 _request_url[i] = '\0'; 00157 getFields(&p, &data); 00158 } 00159 // :3 00160 // Send or store the first amoungh of data. 00161 // Only when the message is complete. 00162 if(!request_incomplete) { 00163 emptypolls = 0; 00164 // Find the right handler 00165 if(!request_handler) { 00166 request_handler = parent->handle(this); 00167 request_status = request_handler->init(this); 00168 } 00169 i = strlen(_request_headerfields) + 120; 00170 char *buf = new char[i]; 00171 sprintf(buf, "HTTP/1.1 %d OK\r\nServer:mbed embedded%s%d%s\r\nConnection: Close\r\n\r\n", request_status, 00172 (_request_length?"\r\nContent-Length: ":""),_request_length, 00173 getHeaderFields()); 00174 i = strlen(buf); 00175 if(sndbuf()>i) { 00176 if(request_status==HTTP_NotFound) { 00177 const char *msg = { 00178 "HTTP/1.1 404 Not Found\r\nServer:mbed embedded\r\n" 00179 "Content-Type: text/html\r\n" 00180 "Content-Length: 163\r\n" 00181 "\r\n" 00182 "<html>\r\n" 00183 "<header>\r\n" 00184 "<title>File not found<title>\r\n" 00185 "</header>\r\n" 00186 "<body>\r\n" 00187 "<h1>HTTP 404</h1>\r\n" 00188 "<p>The file you requested was not found on this mbed. </p>\r\n" 00189 "</body>\r\n" 00190 "</html>\r\n" 00191 }; 00192 00193 write((void *)msg, strlen(msg), 0); 00194 deleteRequest(); 00195 } else { 00196 write(buf, i, (TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE)); 00197 if(_request_type == POST) { 00198 store(data, p); 00199 } else { 00200 send(); 00201 } 00202 } 00203 } 00204 delete buf; 00205 } 00206 00207 // Exits 00208 pbuf_free(q); 00209 data = NULL; 00210 } else { 00211 release_callbacks(); 00212 NetServer::get()->free(this); 00213 close(); 00214 } 00215 return ERR_OK; 00216 } 00217 00218 void HTTPConnection::getFields(struct pbuf **q, char **d) { 00219 if(parent->fields.empty()) { 00220 while((*q)&&request_incomplete) { 00221 unsigned int end = ((unsigned int)((*q)->payload)+(unsigned int)((*q)->len)); 00222 for(; request_incomplete && ((unsigned int)(*d) < end); (*d)++) { 00223 if((*((char *)((*d)-0))=='\n')&&(*((char *)((*d)-1))=='\r')&& 00224 (*((char *)((*d)-2))=='\n')&&(*((char *)((*d)-3))=='\r')) { 00225 request_incomplete = false; 00226 (*d) += 1; 00227 break; 00228 } 00229 } 00230 if(request_incomplete) { 00231 (*q) = (*q)->next; 00232 if((*q)) { 00233 (*d) = static_cast<char *>((*q)->payload); 00234 } 00235 } 00236 } 00237 } else { 00238 char *kb = *d, *ke = NULL, *vb = *d, *ve = NULL; 00239 while((*q)&&request_incomplete) { 00240 unsigned int end = ((unsigned int)((*q)->payload)+(unsigned int)((*q)->len)); 00241 for(; request_incomplete && ((unsigned int)(*d) < end); (*d)++) { 00242 switch(**d) { 00243 case ' ': switch(_request_arg_state) { 00244 case 1: case 2: _request_arg_state = 2; break; 00245 case 3: _request_arg_state = 3; break; 00246 default: _request_arg_state = 0; break; 00247 } break; 00248 case ':': switch(_request_arg_state) { 00249 default: _request_arg_state = 2; break; 00250 case 3: _request_arg_state = 3; break; 00251 } break; 00252 case '\r': switch(_request_arg_state) { 00253 default: _request_arg_state = 4; break; 00254 case 5: case 6: _request_arg_state = 6; break; 00255 } break; 00256 case '\n': switch(_request_arg_state) { 00257 default: _request_arg_state = 4; break; 00258 case 4: case 5: _request_arg_state = 5; break; 00259 case 6: _request_arg_state = 7; break; 00260 } break; 00261 default: switch(_request_arg_state) { 00262 default: _request_arg_state = 1; break; 00263 case 2: case 3: _request_arg_state = 3; break; 00264 } break; 00265 } 00266 switch(_request_arg_state) { 00267 case 0: kb = (*d)+1; break; //PreKey 00268 case 1: ke = (*d); break; //Key 00269 case 2: vb = (*d)+1; break; //PreValue 00270 case 3: ve = (*d); break; //Value 00271 default: break; 00272 case 7: request_incomplete = false; break; 00273 case 5: { 00274 int oldkey = (_request_arg_key)?strlen(_request_arg_key):0; 00275 int oldval = (_request_arg_value)?strlen(_request_arg_value):0; 00276 int keylen =(ke&&kb)?ke-kb+1:0; 00277 int vallen = (ve&&vb)?ve-vb+1:0; 00278 char *key = new char[oldkey+keylen]; 00279 char *val = new char[oldval+vallen]; 00280 if(_request_arg_key&&oldkey) { 00281 strncpy(key, _request_arg_key, oldkey); 00282 } 00283 if(_request_arg_value&&oldval) { 00284 strncpy(val, _request_arg_value, oldval); 00285 } 00286 if(kb&&keylen) { 00287 strncpy(&key[oldkey], kb, keylen); 00288 } 00289 if(vb&&vallen) { 00290 strncpy(&val[oldval], vb, vallen); 00291 } 00292 key[oldkey+keylen] = 0; 00293 val[oldval+vallen] = 0; 00294 // printf("'%s':='%s'\n", key, val); 00295 addField(key, val); 00296 kb = vb = (*d)+1; 00297 ke = ve = NULL; 00298 if(_request_arg_key) { 00299 delete _request_arg_key; 00300 _request_arg_key = NULL; 00301 } 00302 if(_request_arg_value) { 00303 delete _request_arg_value; 00304 _request_arg_value = NULL; 00305 } 00306 delete key; 00307 } break; 00308 } 00309 } 00310 } 00311 switch(_request_arg_state) { 00312 case 0: break; // PreKey 00313 case 5: break; // n-rec 00314 case 6: break; // 2r-rec 00315 default: break; 00316 case 1: case 2: { // Key // PreValue 00317 int keylen =(kb)?(*d)-kb+1:0; 00318 _request_arg_key = new char[keylen]; 00319 strncpy(_request_arg_key, kb, keylen+1); 00320 _request_arg_key[keylen] = 0; 00321 } break; 00322 case 3: case 4: { // Value // r-rec 00323 int keylen =(ke&&kb)?ke-kb+1:0; 00324 int vallen = (vb)?(*d)-vb+1:0; 00325 _request_arg_key = new char[keylen]; 00326 _request_arg_value = new char[vallen]; 00327 strncpy(_request_arg_key, kb, keylen+1); 00328 strncpy(_request_arg_value, vb, vallen+1); 00329 _request_arg_key[keylen] = 0; 00330 _request_arg_value[vallen] = 0; 00331 } break; 00332 } 00333 if(request_incomplete) { 00334 (*q) = (*q)->next; 00335 if((*q)) { 00336 (*d) = static_cast<char *>((*q)->payload); 00337 } 00338 } 00339 } 00340 } 00341 00342 HTTPServer::HTTPServer(u16_t port) : TCPListener(port) { 00343 } 00344 00345 void HTTPConnection::deleteRequest() { 00346 for(map<unsigned int, char *>::iterator iter = _request_fields.begin(); 00347 iter!=_request_fields.end();iter++) { 00348 delete iter->second; 00349 } 00350 _request_fields.clear(); 00351 if(data) {delete data; data = NULL; }; 00352 00353 if(_request_type) { 00354 delete _request_headerfields; 00355 delete _request_arg_key; 00356 delete _request_arg_value; 00357 if(_request_url) { 00358 delete _request_url; 00359 _request_url = NULL; 00360 } 00361 } 00362 _request_type = 0; 00363 request_incomplete = true; 00364 } 00365
Generated on Tue Jul 12 2022 19:24:05 by 1.7.2