ソースの整理中ですが、利用はできます。 大きなファイルはできないかもしれません。

Dependencies:   EthernetInterface HttpServer TextLCD expatlib mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Fork of giken9_HTMLServer_Sample by Yasushi TAUCHI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPRequestHandler.cpp Source File

HTTPRequestHandler.cpp

00001 /*
00002 Permission is hereby granted, free of charge, to any person obtaining a copy
00003 of this software and associated documentation files (the "Software"), to deal
00004 in the Software without restriction, including without limitation the rights
00005 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00006 copies of the Software, and to permit persons to whom the Software is
00007 furnished to do so, subject to the following conditions:
00008 
00009 The above copyright notice and this permission notice shall be included in
00010 all copies or substantial portions of the Software.
00011 
00012 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00013 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00014 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00015 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00016 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00017 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00018 THE SOFTWARE.
00019 */
00020 //#define _DEBUG_REQUEST_HANDLER
00021 //#pragma O0
00022 #include "HTTPRequestHandler.h"
00023 
00024 #include <string.h>
00025 
00026 //#define HTTP_REQUEST_TIMEOUT 5000
00027 //#define HTTP_POST_REQUEST_TIMEOUT 2000
00028 #define READ_SIZE 128
00029 //HTTPRequestHandler::HTTPRequestHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : NetService(),
00030 //   m_pTCPSocketConnection(pTCPSocketConnection), m_reqHeaders(), m_respHeaders(),
00031 //   m_rootPath(rootPath), m_path(path), m_errc(200),
00032 //   m_watchdog(), m_timeout(0),**/ m_closed(false), m_headersSent(false) //OK
00033 HTTPRequestHandler::HTTPRequestHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) :
00034     m_pTCPSocketConnection(pTCPSocketConnection), /*m_reqHeaders(), m_respHeaders(),*/
00035     m_rootPath(rootPath), m_path(path), m_errc(200), m_closed(false), m_headersSent(false)
00036 {
00037 #ifdef _DEBUG_REQUEST_HANDLER
00038     printf("+++(HTTPRequestHandler) init \r\n");
00039 #endif
00040     req_headers_count=0;
00041     resp_headers_count=0;
00042     //Read & parse headers
00043     readHeaders();
00044 //*  m_pTCPSocket->setOnEvent(this, &HTTPRequestHandler::onTCPSocketEvent);
00045 //*  setTimeout(HTTP_REQUEST_TIMEOUT);
00046 #ifdef _DEBUG_REQUEST_HANDLER
00047     printf("+++(HTTPRequestHandler) init end \r\n");
00048 #endif
00049 }
00050 
00051 HTTPRequestHandler::~HTTPRequestHandler()
00052 {
00053     close ();
00054 #ifdef _DEBUG_REQUEST_HANDLER
00055     printf("+++(HTTPRequestHandler) Destroy end\r\n");
00056 #endif
00057 }
00058 
00059 void HTTPRequestHandler::onTimeout() //Connection has timed out
00060 {
00061     close ();
00062 }
00063 
00064 void HTTPRequestHandler::close () //Close socket and destroy data
00065 {
00066     if(m_closed)
00067         return;
00068     m_closed = true; //Prevent recursive calling or calling on an object being destructed by someone else
00069     /**  m_watchdog.detach(); **/
00070 //*  onClose();
00071 //*  m_pTCPSocket->resetOnEvent();
00072 //*m_pTCPSocketConnection->close();
00073 //* delete m_pTCPSocketConnection; //Can safely destroy socket
00074 //*  NetService::close();
00075 }
00076 
00077 //map<string, string>& HTTPRequestHandler::reqHeaders() //const
00078 //{
00079 //    return m_reqHeaders;
00080 //}
00081 void HTTPRequestHandler::reqHeaders(string *key,string *value,unsigned char *count) //const
00082 {
00083     for(int i=0; i<10; i++) {
00084         key[i]=req_headers_key[i];
00085         value[i]=req_headers_value[i];
00086     }
00087     *count=req_headers_count;
00088 //    return m_reqHeaders;
00089 }
00090 
00091 string& HTTPRequestHandler::path() //const
00092 {
00093     return m_path;
00094 }
00095 
00096 int HTTPRequestHandler::dataLen() const
00097 {
00098     int ret=0;
00099     if (clength>0) ret=clength;
00100     //   map<string,string>::iterator it;
00101     // it = m_reqHeaders.find("Content-Length");
00102     //  if( it == m_reqHeaders.end() ) {
00103     //      return 0;
00104     //  }
00105     //  return atoi((*it).second.c_str()); //return 0 if parse fails, so that's fine
00106     return ret;
00107 }
00108 
00109 int HTTPRequestHandler::readData(char* buf, int len)
00110 {
00111     return m_pTCPSocketConnection->receive(buf, len);
00112 }
00113 
00114 string& HTTPRequestHandler::rootPath() //const
00115 {
00116     return m_rootPath;
00117 }
00118 
00119 void HTTPRequestHandler::setErrCode(int errc)
00120 {
00121     m_errc = errc;
00122 }
00123 
00124 void HTTPRequestHandler::setContentLen(int len)
00125 {
00126     char len_str[7] = {0};
00127 //#ifdef _DEBUG_REQUEST_HANDLER
00128     printf( "+++(HTTPRequestHandler)Content-Length %d \r\n", len);
00129 //#endif
00130     sprintf(len_str, "%d", len);
00131 //    respHeaders()["Content-Length"] = len_str;
00132     addRespHeaders("Content-Length",string(len_str));
00133 }
00134 
00135 //map<string, string>& HTTPRequestHandler::respHeaders()
00136 //{
00137 //    return m_respHeaders;
00138 //}
00139 
00140 void HTTPRequestHandler::respHeaders(string *key,string *value,unsigned char *count )
00141 {
00142     for(int i=0; i<10; i++) {
00143         key[i]=resp_headers_key[i];
00144         value[i]=resp_headers_value[i];
00145     }
00146     *count=resp_headers_count;
00147 }
00148 
00149 
00150 int HTTPRequestHandler::writeData(const char* buf, int len)
00151 {
00152     if(!m_headersSent) {
00153         m_headersSent = true;
00154         writeHeaders();
00155     }
00156     return  m_pTCPSocketConnection->send((char *)buf, len);
00157 }
00158 /**
00159 void HTTPRequestHandler::setTimeout(int ms)
00160 {
00161   m_timeout = 1000*ms;
00162   resetTimeout();
00163 }
00164 **/
00165 /**
00166 void HTTPRequestHandler::resetTimeout()
00167 {
00168   m_watchdog.detach();
00169   m_watchdog.attach_us<HTTPRequestHandler>(this, &HTTPRequestHandler::onTimeout, m_timeout);
00170 }
00171 **/
00172 
00173 void HTTPRequestHandler::readHeaders()
00174 {
00175     static char line[128];
00176     static char key[128];
00177     static char value[128];
00178     int i;
00179     char *p;
00180     req_headers_count=0;
00181     resp_headers_count=0;
00182     while( readLine(line, 128) > 0) { //if == 0, it is an empty line = end of headers
00183         int n = sscanf(line, "%[^:]: %[^\n]", key, value);
00184         if ( n == 2 ) {
00185 #ifdef _DEBUG_REQUEST_HANDLER
00186             printf("+++(HTTPRequestHandler)Read header : %s : %s\r\n", key, value);
00187 #endif
00188             //    m_reqHeaders[key] = value;
00189             if(req_headers_count<10) {
00190                 req_headers_key[req_headers_count]=string(key);
00191                 req_headers_value[req_headers_count]=string(value);
00192                 req_headers_count++;
00193             }
00194             //Check Content Length
00195             for(p=&key[0]; p<(&key[0]+strlen(key)); p++) {
00196                 if((*p>0x60)&&(*p<0x7b))*p=*p-0x20;
00197             }
00198 #ifdef _DEBUG_REQUEST_SERVER_H
00199             printf("+++(HTTPRequestHandler) HEADER %s\r\n",key);
00200 #endif
00201             if(strcmp(key,"CONTENT-LENGTH")==0) {
00202                 sscanf(value,"%d",&clength);
00203             }
00204         }
00205         //TODO: Impl n==1 case (part 2 of previous header)
00206     }
00207 }
00208 
00209 void HTTPRequestHandler::readReqData()
00210 {
00211     static char key[128];
00212     static char value[128];
00213     int cont_length=0;
00214     bool chunk=false;
00215     char *p;
00216     int i;
00217     //ReadHeader
00218 //    map< string, string >::iterator it;
00219 //    for (it = m_reqHeaders.begin(); it != m_reqHeaders.end(); it++) {
00220     for (i=0; i<req_headers_count; i++) {
00221 //        sprintf(key,"%s",(*it).first.c_str());
00222 //        sprintf(value,"%s",(*it).second.c_str());
00223         sprintf(key,"%s",req_headers_key[i].c_str());
00224         sprintf(value,"%s",req_headers_value[i].c_str());
00225         for(p=&key[0]; p<(&key[0]+strlen(key)); p++) {
00226             if((*p>0x60)&&(*p<0x7b))*p=*p-0x20;
00227         }
00228 #ifdef _DEBUG_REQUEST_SERVER_H
00229         printf("+++(HTTPRequestHandler) HEADER %s\r\n",key);
00230 #endif
00231         if(strcmp(key,"CONTENT-LENGTH")==0) {
00232             sscanf(value,"%d",&cont_length);
00233         } else if(strcmp(key,"TRANSFER-ENCODING")==0) {
00234             for(p=&value[0]; p<(&value[0]+strlen(value)); p++) {
00235                 if((*p>0x60)&&(*p<0x7b))*p=*p-0x20;
00236             }
00237             if(strcmp(value,"CHUNKED")==0)chunk=true;
00238         }
00239     }
00240 #ifdef _DEBUG_REQUEST_SERVER_H
00241     printf("+++(HTTPRequestHandler)content-length: %d \r\n",cont_length);
00242     if(chunk==true)printf("+++(HTTPRequestHandler)CHUNK Transfer \r\n");
00243     else printf("+++(HTTPRequestHandler)NO CHUNK Transfer \r\n");
00244 #endif
00245 //   m_pTCPSocketConnection->set_blocking(true,HTTP_POST_REQUEST_TIMEOUT);
00246     char buffer[READ_SIZE+1];
00247     if(chunk==false) {
00248         //no chunked mode
00249         for(;;) {
00250             if(cont_length>READ_SIZE) {
00251                 i=m_pTCPSocketConnection->receive(buffer,READ_SIZE);
00252                 buffer[READ_SIZE]=0x0;
00253                 m_reqData.append(string(buffer));
00254                 cont_length-=READ_SIZE;
00255             } else {
00256                 i=m_pTCPSocketConnection->receive(buffer, cont_length);
00257                 buffer[cont_length]=0x0;
00258                 m_reqData.append(string(buffer));
00259                 break;
00260             }
00261         }
00262         if(i>0)printf("Success \r\n");
00263     } else {
00264         //chunked mode
00265         int chunk_size;
00266 
00267         for(;;) {
00268             i=readLine(buffer,20);
00269             printf("chunk :%s:\r\n",buffer);
00270             sscanf(buffer,"%x",&chunk_size);
00271             printf("chunk_size = %d \r\n",chunk_size);
00272             if(chunk_size==0)break;
00273             for(;;) {
00274                 if(chunk_size>READ_SIZE) {
00275                     i=m_pTCPSocketConnection->receive(buffer, READ_SIZE);
00276                     buffer[READ_SIZE]=0x0;
00277                     m_reqData.append(string(buffer));
00278                     chunk_size-=READ_SIZE;
00279                 } else {
00280                     i=m_pTCPSocketConnection->receive(buffer, chunk_size);
00281                     buffer[chunk_size]=0x0;
00282                     m_reqData.append(string(buffer));
00283                     break;
00284                 }
00285             }
00286             i=m_pTCPSocketConnection->receive(buffer,2); //\r\n ro read
00287         }
00288 //   i=readLine(buffer,20);//dummy
00289     }
00290 //        m_pTCPSocketConnection->set_blocking(false);
00291 //        while(m_pTCPSocketConnection->receive(buffer,1)>0){}
00292 //     m_pTCPSocketConnection->set_blocking(false);
00293 //    printf("%s \r\n",m_reqData.c_str());
00294 }
00295 
00296 void HTTPRequestHandler::writeHeaders() //Called at the first writeData call
00297 {
00298     char line[128]= {0};
00299     int i;
00300     //Response line
00301     //printf("Hdebug e1\r\n");
00302     //m_pTCPSocketConnection->receive(line, 1);
00303     //printf("%d \r\n",line[0]);
00304 
00305     sprintf(line, "HTTP/1.1 %d OK\r\n", m_errc); //Not a violation of the standard not to include the descriptive text
00306     //printf("debug e2 %d:%s \r\n",strlen(line),line);
00307     //if(m_pTCPSocketConnection->is_connected()==true) {
00308     //    printf("Connect \r\n");
00309     //} else {
00310     //    printf("disconnected \r\n");
00311     //}
00312     //return;
00313     m_pTCPSocketConnection->send(line, strlen(line));
00314 //    map<string,string>::iterator it;
00315     //printf("%d debug e3 \r\n",resp_headers_count);
00316     for(i=0; i<resp_headers_count; i++) {
00317 //    while( !m_respHeaders.empty() ) {
00318 //        it = m_respHeaders.begin();
00319 //        sprintf(line, "%s: %s\r\n", (*it).first.c_str(), (*it).second.c_str() );
00320 //        printf("debug e\r\n");
00321         sprintf(line, "%s: %s\r\n", resp_headers_key[i].c_str(),resp_headers_value[i].c_str());
00322 //        printf("debug e2 %s %d\r\n",line,strlen(line));
00323 #ifdef _DEBUG_REQUEST_HANDLER
00324         printf("\r\n+++(HTTPRequestHandler)Write header %s \r\n", line);
00325 #endif
00326         m_pTCPSocketConnection->send(line, strlen(line));
00327 //        m_respHeaders.erase(it);
00328     }
00329     m_pTCPSocketConnection->send("\r\n",2); //End of head
00330 }
00331 
00332 void HTTPRequestHandler::addRespHeaders(string key,string value)
00333 {
00334     if(resp_headers_count<10) {
00335         resp_headers_key[resp_headers_count]=string(key);
00336         resp_headers_value[resp_headers_count]=string(value);
00337         resp_headers_count++;
00338     } else {
00339         printf("MAX over resp_headers_num \r\n");
00340     }
00341 }
00342 
00343 int HTTPRequestHandler::readLine(char* str, int maxLen)
00344 {
00345     int ret;
00346     int len = 0;
00347     for(int i = 0; i < maxLen - 1; i++) {
00348         ret = m_pTCPSocketConnection->receive(str, 1);
00349         if(!ret) {
00350             break;
00351         }
00352         if( (len > 1) && *(str-1)=='\r' && *str=='\n' ) {
00353             str--;
00354             len-=2;
00355             break;
00356         } else if( *str=='\n' ) {
00357             len--;
00358             break;
00359         }
00360         str++;
00361         len++;
00362     }
00363     *str = 0;
00364     return len;
00365 }
00366 /**
00367 void HTTPRequestHandler::onTCPSocketEvent(TCPSocketEvent e)
00368 {
00369   //printf("\r\nEvent %d in HTTPRequestHandler\r\n", e);
00370   printf("\r\n+++(HTTPRequestHandler)Event in HTTPRequestHandler\r\n");
00371 
00372   if(m_closed)
00373   {
00374     printf("\r\n+++(HTTPRequestHandler)WARN: Discarded\r\n");
00375     return;
00376   }
00377 
00378   switch(e)
00379   {
00380         case TCPSOCKET_READABLE:
00381     resetTimeout();
00382    onReadable();
00383     break;
00384   case TCPSOCKET_WRITEABLE:
00385     resetTimeout();
00386     onWriteable();
00387     break;
00388   case TCPSOCKET_CONTIMEOUT:
00389   case TCPSOCKET_CONRST:
00390   case TCPSOCKET_CONABRT:
00391   case TCPSOCKET_ERROR:
00392   case TCPSOCKET_DISCONNECTED:
00393     DBG("\r\nConnection error in handler\r\n");
00394     close();
00395     break;
00396   }
00397 }
00398 **/
00399 char* HTTPRequestHandler::getAddress(void)
00400 {
00401     return   m_pTCPSocketConnection->get_address();
00402 }
00403 
00404 string& HTTPRequestHandler::getRequestData(void)
00405 {
00406     return  m_reqData;
00407 }
00408