ソースの整理中ですが、利用はできます。
Dependencies: EthernetInterface HttpServer TextLCD mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip
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 char *p; 00179 chunkmode=false; 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 } else if(strcmp(key,"TRANSFER-ENCODING")==0) { 00204 for(p=&value[0]; p<(&value[0]+strlen(value)); p++) { 00205 if((*p>0x60)&&(*p<0x7b))*p=*p-0x20; 00206 } 00207 if(strcmp(value,"CHUNKED")==0)chunkmode=true; 00208 } 00209 } 00210 //TODO: Impl n==1 case (part 2 of previous header) 00211 } 00212 } 00213 00214 void HTTPRequestHandler::readReqData() 00215 { 00216 int i; 00217 //ReadHeader 00218 #ifdef _DEBUG_REQUEST_SERVER_H 00219 printf("+++(HTTPRequestHandler)content-length: %d \r\n",cont_length); 00220 if(chunkmode==true)printf("+++(HTTPRequestHandler)CHUNK Transfer \r\n"); 00221 else printf("+++(HTTPRequestHandler)NO CHUNK Transfer \r\n"); 00222 #endif 00223 // m_pTCPSocketConnection->set_blocking(true,HTTP_POST_REQUEST_TIMEOUT); 00224 char buffer[READ_SIZE+1]; 00225 if(chunkmode==false) { 00226 //no chunked mode 00227 for(;;) { 00228 if(clength>READ_SIZE) { 00229 i=m_pTCPSocketConnection->receive(buffer,READ_SIZE); 00230 buffer[READ_SIZE]=0x0; 00231 m_reqData.append(string(buffer)); 00232 clength-=READ_SIZE; 00233 } else { 00234 i=m_pTCPSocketConnection->receive(buffer, clength); 00235 buffer[clength]=0x0; 00236 m_reqData.append(string(buffer)); 00237 break; 00238 } 00239 } 00240 if(i>0)printf("Success \r\n"); 00241 } else { 00242 //chunked mode 00243 int chunk_size; 00244 00245 for(;;) { 00246 i=readLine(buffer,20); 00247 printf("chunk :%s:\r\n",buffer); 00248 sscanf(buffer,"%x",&chunk_size); 00249 printf("chunk_size = %d \r\n",chunk_size); 00250 if(chunk_size==0)break; 00251 for(;;) { 00252 if(chunk_size>READ_SIZE) { 00253 i=m_pTCPSocketConnection->receive(buffer, READ_SIZE); 00254 buffer[READ_SIZE]=0x0; 00255 m_reqData.append(string(buffer)); 00256 chunk_size-=READ_SIZE; 00257 } else { 00258 i=m_pTCPSocketConnection->receive(buffer, chunk_size); 00259 buffer[chunk_size]=0x0; 00260 m_reqData.append(string(buffer)); 00261 break; 00262 } 00263 } 00264 i=m_pTCPSocketConnection->receive(buffer,2); //\r\n ro read 00265 } 00266 // i=readLine(buffer,20);//dummy 00267 } 00268 // m_pTCPSocketConnection->set_blocking(false); 00269 // while(m_pTCPSocketConnection->receive(buffer,1)>0){} 00270 // m_pTCPSocketConnection->set_blocking(false); 00271 // printf("%s \r\n",m_reqData.c_str()); 00272 } 00273 00274 void HTTPRequestHandler::writeHeaders() //Called at the first writeData call 00275 { 00276 char line[128]= {0}; 00277 int i; 00278 //Response line 00279 //printf("Hdebug e1\r\n"); 00280 //m_pTCPSocketConnection->receive(line, 1); 00281 //printf("%d \r\n",line[0]); 00282 00283 sprintf(line, "HTTP/1.1 %d OK\r\n", m_errc); //Not a violation of the standard not to include the descriptive text 00284 //printf("debug e2 %d:%s \r\n",strlen(line),line); 00285 //if(m_pTCPSocketConnection->is_connected()==true) { 00286 // printf("Connect \r\n"); 00287 //} else { 00288 // printf("disconnected \r\n"); 00289 //} 00290 //return; 00291 m_pTCPSocketConnection->send(line, strlen(line)); 00292 // map<string,string>::iterator it; 00293 //printf("%d debug e3 \r\n",resp_headers_count); 00294 for(i=0; i<resp_headers_count; i++) { 00295 // while( !m_respHeaders.empty() ) { 00296 // it = m_respHeaders.begin(); 00297 // sprintf(line, "%s: %s\r\n", (*it).first.c_str(), (*it).second.c_str() ); 00298 // printf("debug e\r\n"); 00299 sprintf(line, "%s: %s\r\n", resp_headers_key[i].c_str(),resp_headers_value[i].c_str()); 00300 // printf("debug e2 %s %d\r\n",line,strlen(line)); 00301 #ifdef _DEBUG_REQUEST_HANDLER 00302 printf("\r\n+++(HTTPRequestHandler)Write header %s \r\n", line); 00303 #endif 00304 m_pTCPSocketConnection->send(line, strlen(line)); 00305 // m_respHeaders.erase(it); 00306 } 00307 m_pTCPSocketConnection->send("\r\n",2); //End of head 00308 } 00309 00310 void HTTPRequestHandler::addRespHeaders(string key,string value) 00311 { 00312 if(resp_headers_count<10) { 00313 resp_headers_key[resp_headers_count]=string(key); 00314 resp_headers_value[resp_headers_count]=string(value); 00315 resp_headers_count++; 00316 } else { 00317 printf("MAX over resp_headers_num \r\n"); 00318 } 00319 } 00320 00321 int HTTPRequestHandler::readLine(char* str, int maxLen) 00322 { 00323 int ret; 00324 int len = 0; 00325 for(int i = 0; i < maxLen - 1; i++) { 00326 ret = m_pTCPSocketConnection->receive(str, 1); 00327 if(!ret) { 00328 break; 00329 } 00330 if( (len > 1) && *(str-1)=='\r' && *str=='\n' ) { 00331 str--; 00332 len-=2; 00333 break; 00334 } else if( *str=='\n' ) { 00335 len--; 00336 break; 00337 } 00338 str++; 00339 len++; 00340 } 00341 *str = 0; 00342 return len; 00343 } 00344 /** 00345 void HTTPRequestHandler::onTCPSocketEvent(TCPSocketEvent e) 00346 { 00347 //printf("\r\nEvent %d in HTTPRequestHandler\r\n", e); 00348 printf("\r\n+++(HTTPRequestHandler)Event in HTTPRequestHandler\r\n"); 00349 00350 if(m_closed) 00351 { 00352 printf("\r\n+++(HTTPRequestHandler)WARN: Discarded\r\n"); 00353 return; 00354 } 00355 00356 switch(e) 00357 { 00358 case TCPSOCKET_READABLE: 00359 resetTimeout(); 00360 onReadable(); 00361 break; 00362 case TCPSOCKET_WRITEABLE: 00363 resetTimeout(); 00364 onWriteable(); 00365 break; 00366 case TCPSOCKET_CONTIMEOUT: 00367 case TCPSOCKET_CONRST: 00368 case TCPSOCKET_CONABRT: 00369 case TCPSOCKET_ERROR: 00370 case TCPSOCKET_DISCONNECTED: 00371 DBG("\r\nConnection error in handler\r\n"); 00372 close(); 00373 break; 00374 } 00375 } 00376 **/ 00377 char* HTTPRequestHandler::getAddress(void) 00378 { 00379 return m_pTCPSocketConnection->get_address(); 00380 } 00381 00382 string& HTTPRequestHandler::getRequestData(void) 00383 { 00384 return m_reqData; 00385 } 00386
Generated on Tue Jul 12 2022 13:42:53 by 1.7.2