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