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