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