
An example HTTP Server using new Ethernet Interface and localfilesystem.
Dependencies: EthernetInterface HttpServer mbed-rpc mbed-rtos mbed
Fork of giken9_HTMLServer_Sample by
Diff: HttpServer/HTTPRequestHandler.cpp
- Revision:
- 4:28e8af6595f7
- Parent:
- 3:f0c16cc3a4ef
- Child:
- 5:d98cf6df5187
--- a/HttpServer/HTTPRequestHandler.cpp Tue Dec 23 18:40:55 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,386 +0,0 @@ -/* -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ -//#define _DEBUG_REQUEST_HANDLER -//#pragma O0 -#include "HTTPRequestHandler.h" - -#include <string.h> - -//#define HTTP_REQUEST_TIMEOUT 5000 -//#define HTTP_POST_REQUEST_TIMEOUT 2000 -#define READ_SIZE 128 -//HTTPRequestHandler::HTTPRequestHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : NetService(), -// m_pTCPSocketConnection(pTCPSocketConnection), m_reqHeaders(), m_respHeaders(), -// m_rootPath(rootPath), m_path(path), m_errc(200), -// m_watchdog(), m_timeout(0),**/ m_closed(false), m_headersSent(false) //OK -HTTPRequestHandler::HTTPRequestHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) : - m_pTCPSocketConnection(pTCPSocketConnection), /*m_reqHeaders(), m_respHeaders(),*/ - m_rootPath(rootPath), m_path(path), m_errc(200), m_closed(false), m_headersSent(false) -{ -#ifdef _DEBUG_REQUEST_HANDLER - printf("+++(HTTPRequestHandler) init \r\n"); -#endif - req_headers_count=0; - resp_headers_count=0; - //Read & parse headers - readHeaders(); -//* m_pTCPSocket->setOnEvent(this, &HTTPRequestHandler::onTCPSocketEvent); -//* setTimeout(HTTP_REQUEST_TIMEOUT); -#ifdef _DEBUG_REQUEST_HANDLER - printf("+++(HTTPRequestHandler) init end \r\n"); -#endif -} - -HTTPRequestHandler::~HTTPRequestHandler() -{ - close(); -#ifdef _DEBUG_REQUEST_HANDLER - printf("+++(HTTPRequestHandler) Destroy end\r\n"); -#endif -} - -void HTTPRequestHandler::onTimeout() //Connection has timed out -{ - close(); -} - -void HTTPRequestHandler::close() //Close socket and destroy data -{ - if(m_closed) - return; - m_closed = true; //Prevent recursive calling or calling on an object being destructed by someone else - /** m_watchdog.detach(); **/ -//* onClose(); -//* m_pTCPSocket->resetOnEvent(); -//*m_pTCPSocketConnection->close(); -//* delete m_pTCPSocketConnection; //Can safely destroy socket -//* NetService::close(); -} - -//map<string, string>& HTTPRequestHandler::reqHeaders() //const -//{ -// return m_reqHeaders; -//} -void HTTPRequestHandler::reqHeaders(string *key,string *value,unsigned char *count) //const -{ - for(int i=0; i<10; i++) { - key[i]=req_headers_key[i]; - value[i]=req_headers_value[i]; - } - *count=req_headers_count; -// return m_reqHeaders; -} - -string& HTTPRequestHandler::path() //const -{ - return m_path; -} - -int HTTPRequestHandler::dataLen() const -{ - int ret=0; - if (clength>0) ret=clength; - // map<string,string>::iterator it; - // it = m_reqHeaders.find("Content-Length"); - // if( it == m_reqHeaders.end() ) { - // return 0; - // } - // return atoi((*it).second.c_str()); //return 0 if parse fails, so that's fine - return ret; -} - -int HTTPRequestHandler::readData(char* buf, int len) -{ - return m_pTCPSocketConnection->receive(buf, len); -} - -string& HTTPRequestHandler::rootPath() //const -{ - return m_rootPath; -} - -void HTTPRequestHandler::setErrCode(int errc) -{ - m_errc = errc; -} - -void HTTPRequestHandler::setContentLen(int len) -{ - char len_str[7] = {0}; -//#ifdef _DEBUG_REQUEST_HANDLER - printf( "+++(HTTPRequestHandler)Content-Length %d \r\n", len); -//#endif - sprintf(len_str, "%d", len); -// respHeaders()["Content-Length"] = len_str; - addRespHeaders("Content-Length",string(len_str)); -} - -//map<string, string>& HTTPRequestHandler::respHeaders() -//{ -// return m_respHeaders; -//} - -void HTTPRequestHandler::respHeaders(string *key,string *value,unsigned char *count ) -{ - for(int i=0; i<10; i++) { - key[i]=resp_headers_key[i]; - value[i]=resp_headers_value[i]; - } - *count=resp_headers_count; -} - - -int HTTPRequestHandler::writeData(const char* buf, int len) -{ - if(!m_headersSent) { - m_headersSent = true; - writeHeaders(); - } - return m_pTCPSocketConnection->send((char *)buf, len); -} -/** -void HTTPRequestHandler::setTimeout(int ms) -{ - m_timeout = 1000*ms; - resetTimeout(); -} -**/ -/** -void HTTPRequestHandler::resetTimeout() -{ - m_watchdog.detach(); - m_watchdog.attach_us<HTTPRequestHandler>(this, &HTTPRequestHandler::onTimeout, m_timeout); -} -**/ - -void HTTPRequestHandler::readHeaders() -{ - static char line[128]; - static char key[128]; - static char value[128]; - char *p; - chunkmode=false; - req_headers_count=0; - resp_headers_count=0; - while( readLine(line, 128) > 0) { //if == 0, it is an empty line = end of headers - int n = sscanf(line, "%[^:]: %[^\n]", key, value); - if ( n == 2 ) { -#ifdef _DEBUG_REQUEST_HANDLER - printf("+++(HTTPRequestHandler)Read header : %s : %s\r\n", key, value); -#endif - // m_reqHeaders[key] = value; - if(req_headers_count<10) { - req_headers_key[req_headers_count]=string(key); - req_headers_value[req_headers_count]=string(value); - req_headers_count++; - } - //Check Content Length - for(p=&key[0]; p<(&key[0]+strlen(key)); p++) { - if((*p>0x60)&&(*p<0x7b))*p=*p-0x20; - } -#ifdef _DEBUG_REQUEST_SERVER_H - printf("+++(HTTPRequestHandler) HEADER %s\r\n",key); -#endif - if(strcmp(key,"CONTENT-LENGTH")==0) { - sscanf(value,"%d",&clength); - } else if(strcmp(key,"TRANSFER-ENCODING")==0) { - for(p=&value[0]; p<(&value[0]+strlen(value)); p++) { - if((*p>0x60)&&(*p<0x7b))*p=*p-0x20; - } - if(strcmp(value,"CHUNKED")==0)chunkmode=true; - } - } - //TODO: Impl n==1 case (part 2 of previous header) - } -} - -void HTTPRequestHandler::readReqData() -{ - int i; - //ReadHeader -#ifdef _DEBUG_REQUEST_SERVER_H - printf("+++(HTTPRequestHandler)content-length: %d \r\n",cont_length); - if(chunkmode==true)printf("+++(HTTPRequestHandler)CHUNK Transfer \r\n"); - else printf("+++(HTTPRequestHandler)NO CHUNK Transfer \r\n"); -#endif -// m_pTCPSocketConnection->set_blocking(true,HTTP_POST_REQUEST_TIMEOUT); - char buffer[READ_SIZE+1]; - if(chunkmode==false) { - //no chunked mode - for(;;) { - if(clength>READ_SIZE) { - i=m_pTCPSocketConnection->receive(buffer,READ_SIZE); - buffer[READ_SIZE]=0x0; - m_reqData.append(string(buffer)); - clength-=READ_SIZE; - } else { - i=m_pTCPSocketConnection->receive(buffer, clength); - buffer[clength]=0x0; - m_reqData.append(string(buffer)); - break; - } - } - if(i>0)printf("Success \r\n"); - } else { - //chunked mode - int chunk_size; - - for(;;) { - i=readLine(buffer,20); - printf("chunk :%s:\r\n",buffer); - sscanf(buffer,"%x",&chunk_size); - printf("chunk_size = %d \r\n",chunk_size); - if(chunk_size==0)break; - for(;;) { - if(chunk_size>READ_SIZE) { - i=m_pTCPSocketConnection->receive(buffer, READ_SIZE); - buffer[READ_SIZE]=0x0; - m_reqData.append(string(buffer)); - chunk_size-=READ_SIZE; - } else { - i=m_pTCPSocketConnection->receive(buffer, chunk_size); - buffer[chunk_size]=0x0; - m_reqData.append(string(buffer)); - break; - } - } - i=m_pTCPSocketConnection->receive(buffer,2); //\r\n ro read - } -// i=readLine(buffer,20);//dummy - } -// m_pTCPSocketConnection->set_blocking(false); -// while(m_pTCPSocketConnection->receive(buffer,1)>0){} -// m_pTCPSocketConnection->set_blocking(false); -// printf("%s \r\n",m_reqData.c_str()); -} - -void HTTPRequestHandler::writeHeaders() //Called at the first writeData call -{ - char line[128]= {0}; - int i; - //Response line - //printf("Hdebug e1\r\n"); - //m_pTCPSocketConnection->receive(line, 1); - //printf("%d \r\n",line[0]); - - sprintf(line, "HTTP/1.1 %d OK\r\n", m_errc); //Not a violation of the standard not to include the descriptive text - //printf("debug e2 %d:%s \r\n",strlen(line),line); - //if(m_pTCPSocketConnection->is_connected()==true) { - // printf("Connect \r\n"); - //} else { - // printf("disconnected \r\n"); - //} - //return; - m_pTCPSocketConnection->send(line, strlen(line)); -// map<string,string>::iterator it; - //printf("%d debug e3 \r\n",resp_headers_count); - for(i=0; i<resp_headers_count; i++) { -// while( !m_respHeaders.empty() ) { -// it = m_respHeaders.begin(); -// sprintf(line, "%s: %s\r\n", (*it).first.c_str(), (*it).second.c_str() ); -// printf("debug e\r\n"); - sprintf(line, "%s: %s\r\n", resp_headers_key[i].c_str(),resp_headers_value[i].c_str()); -// printf("debug e2 %s %d\r\n",line,strlen(line)); -#ifdef _DEBUG_REQUEST_HANDLER - printf("\r\n+++(HTTPRequestHandler)Write header %s \r\n", line); -#endif - m_pTCPSocketConnection->send(line, strlen(line)); -// m_respHeaders.erase(it); - } - m_pTCPSocketConnection->send("\r\n",2); //End of head -} - -void HTTPRequestHandler::addRespHeaders(string key,string value) -{ - if(resp_headers_count<10) { - resp_headers_key[resp_headers_count]=string(key); - resp_headers_value[resp_headers_count]=string(value); - resp_headers_count++; - } else { - printf("MAX over resp_headers_num \r\n"); - } -} - -int HTTPRequestHandler::readLine(char* str, int maxLen) -{ - int ret; - int len = 0; - for(int i = 0; i < maxLen - 1; i++) { - ret = m_pTCPSocketConnection->receive(str, 1); - if(!ret) { - break; - } - if( (len > 1) && *(str-1)=='\r' && *str=='\n' ) { - str--; - len-=2; - break; - } else if( *str=='\n' ) { - len--; - break; - } - str++; - len++; - } - *str = 0; - return len; -} -/** -void HTTPRequestHandler::onTCPSocketEvent(TCPSocketEvent e) -{ - //printf("\r\nEvent %d in HTTPRequestHandler\r\n", e); - printf("\r\n+++(HTTPRequestHandler)Event in HTTPRequestHandler\r\n"); - - if(m_closed) - { - printf("\r\n+++(HTTPRequestHandler)WARN: Discarded\r\n"); - return; - } - - switch(e) - { - case TCPSOCKET_READABLE: - resetTimeout(); - onReadable(); - break; - case TCPSOCKET_WRITEABLE: - resetTimeout(); - onWriteable(); - break; - case TCPSOCKET_CONTIMEOUT: - case TCPSOCKET_CONRST: - case TCPSOCKET_CONABRT: - case TCPSOCKET_ERROR: - case TCPSOCKET_DISCONNECTED: - DBG("\r\nConnection error in handler\r\n"); - close(); - break; - } -} -**/ -char* HTTPRequestHandler::getAddress(void) -{ - return m_pTCPSocketConnection->get_address(); -} - -string& HTTPRequestHandler::getRequestData(void) -{ - return m_reqData; -} -