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