ソースの整理中ですが、利用はできます。 大きなファイルはできないかもしれません。
Dependencies: EthernetInterface HttpServer TextLCD expatlib mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip
Fork of giken9_HTMLServer_Sample by
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
Generated on Tue Jul 12 2022 23:04:32 by 1.7.2