LRSD stephane / Mbed 2 deprecated WEBserverv4

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPServer.cpp Source File

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&#65533;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