An example HTTP Server library using new Ethernet Interface
Revision 0:8e1971a883be, committed 2014-12-23
- Comitter:
- mkilivan
- Date:
- Tue Dec 23 18:49:25 2014 +0000
- Commit message:
- forked from http://developer.mbed.org/users/yueee_yt/code/giken9_HTMLServer_Sample/
Changed in this revision
diff -r 000000000000 -r 8e1971a883be HTTPRequestHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPRequestHandler.cpp Tue Dec 23 18:49:25 2014 +0000 @@ -0,0 +1,386 @@ +/* +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; +} +
diff -r 000000000000 -r 8e1971a883be HTTPRequestHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPRequestHandler.h Tue Dec 23 18:49:25 2014 +0000 @@ -0,0 +1,119 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +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. +*/ + +/** +HTTP Request Handler header file. +*/ + +#ifndef HTTP_REQUEST_HANDLER_H +#define HTTP_REQUEST_HANDLER_H + +//#include "HTTPServer.h" + +#include "mbed.h" +#include "EthernetInterface.h" + +#include <string> +using std::string; + +#include <map> +using std::map; + +///HTTP Server's generic request handler +class HTTPRequestHandler +{ +public: + ///Instantiated by the HTTP Server + HTTPRequestHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection); + virtual ~HTTPRequestHandler(); + +//protected: + virtual void doGet() = 0; + virtual void doPost() = 0; + virtual void doHead() = 0; + + virtual void onReadable() = 0; //Data has been read + virtual void onWriteable() = 0; //Data has been written & buf is free + virtual void onTimeout(); //Connection has timed out + virtual void onClose() = 0; //Connection is closing + + virtual void close(); //Close socket and destroy data + +protected: + // map<string, string>& reqHeaders() /*const*/; + void reqHeaders(string *key,string *value,unsigned char *count); + string& path() /*const*/; + int dataLen() const; + int readData(char* buf, int len); + string& rootPath() /*const*/; + + void setErrCode(int errc); + void setContentLen(int len); + + // map<string, string>& respHeaders(); + void respHeaders(string *key,string *value,unsigned char *count ); + + int writeData(const char* buf, int len); + char* getAddress(void); + string& getRequestData(void); + void addRespHeaders(string key,string value); + + void readReqData(); + +//* void setTimeout(int ms); +//* void resetTimeout(); + +private: + void readHeaders(); //Called at instanciation + void writeHeaders(); //Called at the first writeData call + //**void onTCPSocketEvent(/**TCPSocketEvent e**/); + + TCPSocketConnection* m_pTCPSocketConnection; + //map<string, string> m_reqHeaders; + //map<string, string> m_respHeaders; + string req_headers_key[10]; + string req_headers_value[10]; + unsigned char req_headers_count; + string resp_headers_key[10]; + string resp_headers_value[10]; + unsigned char resp_headers_count; + string m_rootPath; + string m_path; + string m_reqData; + + int m_errc; //Response code + +//* Timeout m_watchdog; +//* int m_timeout; + + bool m_closed; + bool m_headersSent; + + int readLine(char* str, int maxLen); +int clength; +bool chunkmode; +}; + +#endif + +
diff -r 000000000000 -r 8e1971a883be HTTPServer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPServer.h Tue Dec 23 18:49:25 2014 +0000 @@ -0,0 +1,360 @@ +//#define _DEBUG_HTTP_SERVER_H + +#ifndef HTTP_SERVER_H +#define HTTP_SERVER_H + +#define HELLO_PAGE "/hello" +#define RPC_PAGE "/rpc" +//#define IEEE1888WSDL_PAGE "/IEEE1888?wsdl" +//#define IEEE1888_PAGE "/IEEE1888" +#define FS_PAGE "/" + +#include <string> +using std::string; + +#include <map> +using std::map; + +#include "HTTPRequestHandler.h" +#include "rtos.h" +#include "mbed.h" +#include "EthernetInterface.h" + +#include "Handler/RPCHandler.h" +#include "Handler/FSHandler.h" +#include "Handler/SimpleHandler.h" + +#define THREAD_MAX 3 +Thread *threads[THREAD_MAX]; +Thread *xthread; + +/* +struct handlersComp { //Used to order handlers in the right way + bool operator() (const string& handler1, const string& handler2) const { + //The first handler is longer than the second one + if (handler1.length() > handler2.length()) + return true; //Returns true if handler1 is to appear before handler2 + else if (handler1.length() < handler2.length()) + return false; + else //To avoid the == case, sort now by address + return ((&handler1)>(&handler2)); + } +}; + +map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocketConnection* ), handlersComp > m_lpHandlers; +template<typename T> +void HTTPServerAddHandler(const char* path) //Template decl in header +{ + m_lpHandlers[path] = &T::inst; +} +*/ + +void ListenThread(void const *args); +enum HTTP_METH { + HTTP_GET, + HTTP_POST, + HTTP_HEAD +}; + +bool getRequest(TCPSocketConnection* client,string* path, string* meth) +{ + char req[128]; + char c_path[128]; + char c_meth[128]; + const int maxLen = 128; + char* p = req; + //Read Line + int ret; + int len = 0; + for(int i = 0; i < maxLen - 1; i++) { + ret = client->receive(p, 1); + if(!ret) { + break; + } + if( (len > 1) && *(p-1)=='\r' && *p=='\n' ) { + p--; + len-=2; + break; + } else if( *p=='\n' ) { + len--; + break; + } + p++; + len++; + } + *p = 0; +#ifdef _DEBUG_HTTP_SERVER_H + printf("Parsing request : %s\r\n", req); +#endif + ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path); + if(ret !=2) return false; + *meth = string(c_meth); + *path = string(c_path); + return true; +} + +void dispatchRequest(TCPSocketConnection* client) +{ + string path; + string meth; + HTTP_METH methCode; +#ifdef _DEBUG_HTTP_SERVER_H + printf("Dispatching req\r\n"); +#endif + if( !getRequest(client,&path, &meth ) ) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("dispatchRequest Invalid request\r\n"); +#endif + //close(); + return; //Invalid request + } + if( !meth.compare("GET") ) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("dispatchRequest HTTP_GET\r\n"); +#endif + methCode = HTTP_GET; + } else if( !meth.compare("POST") ) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("dispatchRequest HTTP_POST\r\n"); +#endif + methCode = HTTP_POST; + } else if( !meth.compare("HEAD") ) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("dispatchRequest HTTP_HEAD\r\n"); +#endif + methCode = HTTP_HEAD; + } else { +#ifdef _DEBUG_HTTP_SERVER_H + printf("dispatchRequest() Parse error\r\n"); +#endif + //close(); //Parse error + return; + } +#ifdef _DEBUG_HTTP_SERVER_H + printf("Looking for a handler\r\n"); +#endif + /* + map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocketConnection*) >::iterator it; + int root_len = 0; + for (it = m_lpHandlers.begin(); it != m_lpHandlers.end(); it++) { + #ifdef _DEBUG_HTTP_SERVER_H + printf("Checking %s...\r\n", (*it).first.c_str()); + #endif + root_len = (*it).first.length(); + if ( root_len && + !path.compare( 0, root_len, (*it).first ) && + (path[root_len] == '/' || path[root_len] == '\0')) { + #ifdef _DEBUG_HTTP_SERVER_H + printf("Found (%s)\r\n", (*it).first.c_str()); + #endif + // Found! + break; // for + } + } + if((it == m_lpHandlers.end()) && !(m_lpHandlers.empty())) { + #ifdef _DEBUG_HTTP_SERVER_H + printf("Using default handler\r\n"); + #endif + it = m_lpHandlers.end(); + it--; //Get the last element + if( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler + it = m_lpHandlers.end(); + root_len = 0; + } + if(it == m_lpHandlers.end()) { + #ifdef _DEBUG_HTTP_SERVER_H + printf("No handler found\r\n"); + #endif + return; + } + #ifdef _DEBUG_HTTP_SERVER_H + printf("Handler found.\r\n"); + #endif + HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, client); + */ + HTTPRequestHandler* pHdlr; + if (!path.compare(0,strlen(HELLO_PAGE),HELLO_PAGE)) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("HELLO PAGE CREATE. PATH %s: %s \r\n",HELLO_PAGE, path.c_str() + strlen(HELLO_PAGE)); +#endif + pHdlr = new SimpleHandler(HELLO_PAGE, path.c_str() + strlen(HELLO_PAGE), client); + } + +#ifdef RPC_PAGE + else if (!path.compare(0,strlen(RPC_PAGE),RPC_PAGE)) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("RPC PAGE CREATE. PATH %s: %s \r\n",RPC_PAGE, path.c_str() + strlen(RPC_PAGE)); +#endif + pHdlr = new RPCHandler(RPC_PAGE, path.c_str() + strlen(RPC_PAGE), client); + } +#endif + +#ifdef IEEE1888WSDL_PAGE + else if (!path.compare(0,strlen(IEEE1888WSDL_PAGE),IEEE1888WSDL_PAGE)) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("IEEE1888WSDL_PAGE CREATE. PATH %s: %s \r\n",IEEE1888WSDL_PAGE, path.c_str() + strlen(IEEE1888WSDL_PAGE)); +#endif + pHdlr = new IEEE1888WSDLHandler(IEEE1888WSDL_PAGE, path.c_str() + strlen(IEEE1888WSDL_PAGE)-1, client); + } +#endif + +#ifdef IEEE1888_PAGE + else if (!path.compare(0,strlen(IEEE1888_PAGE),IEEE1888_PAGE)) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("IEEE1888_PAGE CREATE. PATH %s: %s \r\n",IEEE1888_PAGE, path.c_str() + strlen(IEEE1888_PAGE)); +#endif + pHdlr = new IEEE1888Handler(IEEE1888_PAGE, path.c_str() + strlen(IEEE1888_PAGE)-1, client); + } +#endif + +#ifdef FS_PAGE + else if (!path.compare(0,strlen(FS_PAGE),FS_PAGE)) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("FS_PAGE CREATE. PATH %s: %s \r\n",FS_PAGE, path.c_str() + strlen(FS_PAGE)); +#endif + pHdlr = new FSHandler(FS_PAGE, path.c_str() + strlen(FS_PAGE)-1, client); + } +#endif + + else { +#ifdef _DEBUG_HTTP_SERVER_H + printf("No handler found\r\n"); +#endif + pHdlr = new SimpleHandler(HELLO_PAGE, path.c_str() + strlen(HELLO_PAGE), client); + return; + } + //**** client = NULL; //We don't own it anymore +#ifdef _DEBUG_HTTP_SERVER_H + printf("Handler Created.\r\n"); +#endif + switch(methCode) { + case HTTP_GET: + pHdlr->doGet(); + break; + case HTTP_POST: + pHdlr->doPost(); + break; + case HTTP_HEAD: + pHdlr->doHead(); + break; + } +#ifdef _DEBUG_HTTP_SERVER_H + printf("Handler Delete.\r\n"); +#endif + delete pHdlr; + // delete client; + //delete pTCPSocketConnection; +#ifdef _DEBUG_HTTP_SERVER_H + printf("(dispatcherRequest)return\r\n"); +#endif + return ; +} + +void HTTPServerChild (void const *arg) +{ +#ifdef _DEBUG_HTTP_SERVER_H + printf("HTTPServerChiled Start......\r\n"); +#endif + TCPSocketConnection* client = (TCPSocketConnection*)arg; + + for (;;) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("(HTTPServer.h<HTTPServerChild>)Connection from %s\r\n", client->get_address()); +#endif + dispatchRequest(client); +#ifdef _DEBUG_HTTP_SERVER_H + printf("(HTTPServer.h<HTTPServerChild>)Client->Close %s\r\n", client->get_address()); +#endif + client->close(); +#ifdef _DEBUG_HTTP_SERVER_H + // printf("(HTTPServer.h<HTTPServerChild>)Client->reset\r\n"); +#endif + // client->reset_address(); +#ifdef _DEBUG_HTTP_SERVER_H + printf("(HTTPServer.h<HTTPServerChild>)Thread::signal_wait(1)\r\n"); +#endif //delete client; + Thread::signal_wait(1); +#ifdef _DEBUG_HTTP_SERVER_H + printf("(HTTPServer.h<HTTPServerChild>)Return \r\n"); +#endif + } +} + +void HTTPServerCloser (void const *arg) +{ + TCPSocketConnection *client = (TCPSocketConnection*)arg; +#ifdef _DEBUG_HTTP_SERVER_H + printf("HTTPCloser start%s\r\n", client->get_address()); +#endif + + for (;;) { + client->close(); +#ifdef _DEBUG_HTTP_SERVER_H + printf("Close %s\r\n", client->get_address()); +#endif + Thread::signal_wait(1); + } +} + +void HTTPServerStart(int port = 80) +{ + int i, t = 0; + TCPSocketConnection clients[THREAD_MAX]; + TCPSocketConnection xclient; + + for (i = 0; i < THREAD_MAX; i ++) { + threads[i] = NULL; + } + xthread = NULL; + + TCPSocketServer server; + server.bind(port); + server.listen(); + // server.set_blocking(false); +#ifdef _DEBUG_HTTP_SERVER_H + printf("Wait for new connection...\r\n"); +#endif + for (;;) { +#ifdef _DEBUG_HTTP_SERVER_H + printf("**Start Loop** \r\n"); +#endif + if (t >= 0) { + if(server.accept(clients[t])==0) { + // fork child process + if (threads[t]) { + threads[t]->signal_set(1); + } else { + threads[t] = new Thread(HTTPServerChild, (void*)&clients[t]); + } +#ifdef _DEBUG_HTTP_SERVER_H + printf("Forked %d\r\n", t); +#endif + } + } else { + if(server.accept(xclient)==0) { + // closer process + if (xthread) { + xthread->signal_set(1); + } else { + xthread = new Thread(HTTPServerCloser, (void*)&xclient); + } +#ifdef _DEBUG_HTTP_SERVER_H + printf("Connection full\r\n"); +#endif + } + } + + t = -1; + for (i = 0; i < THREAD_MAX; i ++) { + if (threads[i] == NULL || threads[i]->get_state() == Thread::WaitingAnd) { + if (t < 0) t = i; // next empty thread + } + } + // Thread::wait(100); + } +} + + +#endif + +
diff -r 000000000000 -r 8e1971a883be Handler/FSHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/FSHandler.cpp Tue Dec 23 18:49:25 2014 +0000 @@ -0,0 +1,210 @@ +/* +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_FS_HANDLER + +#include "FSHandler.h" + +#define CHUNK_SIZE 128 + +#define DEFAULT_PAGE "/index.htm" + +//*FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : HTTPRequestHandler(rootPath, path, pTCPSocket), m_err404(false) +FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) : HTTPRequestHandler(rootPath, path, pTCPSocketConnection), m_err404(false) +{} + +FSHandler::~FSHandler() +{ +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler) destroy\r\n"); +#endif + if(m_fp) { +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler) fclose start\r\n"); +#endif + fclose(m_fp); +#ifdef _DEBUG_FS_HANDLER + printf("+++(FSHandler) fclose end\r\n"); +#endif + + } +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)Handler destroyed\r\n"); +#endif +} + +//static init +map<string,string> FSHandler::m_lFsPath = map<string,string>(); + +void FSHandler::mount(const string& fsPath, const string& rootPath) +{ + m_lFsPath[rootPath]=fsPath; +} + + +void FSHandler::doGet() +{ +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)doGet() - rootPath=%s, path=%s\r\n", rootPath().c_str(), path().c_str()); +#endif + //FIXME: Translate path to local/path + string checkedRootPath = rootPath(); + if(checkedRootPath.empty()) + checkedRootPath="/"; + string filePath = m_lFsPath[checkedRootPath]; + if (path().size() > 1) { + filePath += path(); + } else { + filePath += DEFAULT_PAGE; + } +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)Trying to open %s\r\n", filePath.c_str()); +#endif + m_fp = fopen(filePath.c_str(), "r"); //FIXME: if null, error 404 +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler) opened %s\r\n", filePath.c_str()); +#endif + + if(!m_fp) { +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)404Error\r\n"); +#endif + + m_err404 = true; + setErrCode(404); + const char* msg = "File not found."; + setContentLen(strlen(msg)); +// respHeaders()["Content-Type"] = "text/html"; +// respHeaders()["Connection"] = "close"; + addRespHeaders("Content-Type", "text/html"); + addRespHeaders("Connection", "close"); + writeData(msg,strlen(msg)); //Only send header + printf("++++(FSHandler)\r\nExit FSHandler::doGet() w Error 404\r\n"); + return; + } + // printf("++++(FSHandler) Seek start\r\n"); + //Seek EOF to get length + fseek(m_fp, 0, SEEK_END); + setContentLen( ftell(m_fp) ); + fseek(m_fp, 0, SEEK_SET); //Goto SOF + +// respHeaders()["Connection"] = "close"; + addRespHeaders("Connection", "close"); + // printf("++++(FSHandler)Write start\r\n"); + onWriteable(); +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)Exit doGet()\r\n"); +#endif +} + +void FSHandler::doPost() +{ + +} + +void FSHandler::doHead() +{ + +} + +void FSHandler::onReadable() //Data has been read +{ + +} + +void FSHandler::onWriteable() //Data has been written & buf is free +{ +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)onWriteable() event\r\n"); +#endif + if(m_err404) { +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)m_err404\r\n"); +#endif + //Error has been served, now exit + close(); + return; + } +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)not m_err404\r\n"); +#endif + + static char rBuf[CHUNK_SIZE]; + while(true) { + int len = fread(rBuf, 1, CHUNK_SIZE, m_fp); + if(len>0) { + int writtenLen = writeData(rBuf, len); + if(writtenLen < 0) { //Socket error +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler) Socket error %d\r\n", writtenLen); +#endif + /** Not Work + if(writtenLen == TCPSOCKET_MEM) { + #ifdef _DEBUG_FS_HANDLER + printf("FSHandler: Socket error %d\n", writtenLen); + #endif + fseek(m_fp, -len, SEEK_CUR); + return; //Wait for the queued TCP segments to be transmitted + } else { + //This is a critical error + **/ +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)critical error\r\n"); +#endif + close(); + return; + /** + } + **/ + } else if(writtenLen < len) { //Short write, socket's buffer is full +#ifdef _DEBUG_FS_HANDLER + printf("++++(FSHandler)Short write, socket's buffer is full\r\n"); +#endif + fseek(m_fp, writtenLen - len, SEEK_CUR); + return; + } + } else { + close(); //Data written, we can close the connection + return; + } + } +} + +void FSHandler::onClose() //Connection is closing +{ + /** + #ifdef _DEBUG_FS_HANDLER + printf("FSHandler: onClose start \r\n"); + #endif + if(m_fp){ + #ifdef _DEBUG_FS_HANDLER + printf("FSHandler: fclose start \r\n"); + #endif + fclose(m_fp); + #ifdef _DEBUG_FS_HANDLER + printf("FSHandler: fclose end \r\n"); + #endif + } + #ifdef _DEBUG_FS_HANDLER + printf("FSHandler: onClose end \r\n"); + #endif + **/ +} + +
diff -r 000000000000 -r 8e1971a883be Handler/FSHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/FSHandler.h Tue Dec 23 18:49:25 2014 +0000 @@ -0,0 +1,58 @@ +/* +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. +*/ + +#ifndef FS_HANDLER_H +#define FS_HANDLER_H + +#include "../HTTPRequestHandler.h" +#include "mbed.h" +#include "EthernetInterface.h" +#include <map> +using std::map; + +#include <string> +using std::string; + +class FSHandler : public HTTPRequestHandler +{ +public: + FSHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection); + virtual ~FSHandler(); + + static void mount(const string& fsPath, const string& rootPath); + +//protected: + static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) { return new FSHandler(rootPath, path, pTCPSocketConnection); } //if we ever could do static virtual functions, this would be one + + virtual void doGet(); + virtual void doPost(); + virtual void doHead(); + + virtual void onReadable(); //Data has been read + virtual void onWriteable(); //Data has been written & buf is free + virtual void onClose(); //Connection is closing + +private: + FILE* m_fp; + bool m_err404; + static map<string,string> m_lFsPath; +}; + +#endif
diff -r 000000000000 -r 8e1971a883be Handler/RPCHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/RPCHandler.cpp Tue Dec 23 18:49:25 2014 +0000 @@ -0,0 +1,140 @@ +/* +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_RPC_HANDLER + +#include "RPCHandler.h" +#include "mbed_rpc.h" + +#define RPC_DATA_LEN 64 + +RPCHandler::RPCHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) : HTTPRequestHandler(rootPath, path, pTCPSocketConnection) +{} + +RPCHandler::~RPCHandler() +{ +#ifdef _DEBUG_RPC_HANDLER + printf("++++(RPC Handler)Handler destroyed\r\n"); +#endif +} + +void RPCHandler::doGet() +{ +#ifdef _DEBUG_RPC_HANDLER + printf("++++(RPC Handler)doGet\r\n"); +#endif + char resp[RPC_DATA_LEN] = {0}; + char req[RPC_DATA_LEN] = {0}; + +#ifdef _DEBUG_RPC_HANDLER + printf("++++(RPC Handler)Path : %s\r\n", path().c_str()); + printf("++++(RPC Handler)Root Path : %s\r\n", rootPath().c_str()); +#endif + //Remove path + strncpy(req, path().c_str(), RPC_DATA_LEN-1); +#ifdef _DEBUG_RPC_HANDLER + printf("++++(RPC Handler)RPC req(before) : %s\r\n", req); +#endif + //Remove "%20", "+", "," from req + cleanReq(req); +#ifdef _DEBUG_RPC_HANDLER + printf("++++(RPC Handler)RPC req(after) : %s\r\n", req); +#endif + //Do RPC Call + RPC::call(req, resp); //FIXME: Use bool result +#ifdef _DEBUG_RPC_HANDLER + printf("++++(RPC Handler)Response %s \r\n",resp); +#endif + //Response + setContentLen( strlen(resp) ); + + //Make sure that the browser won't cache this request +// respHeaders()["Cache-control"]="no-cache;no-store"; +// respHeaders()["Pragma"]="no-cache"; +// respHeaders()["Expires"]="0"; + addRespHeaders("Cache-control","no-cache;no-store"); + addRespHeaders("Pragma","no-cache"); + addRespHeaders("Expires","0"); + + //Write data +// respHeaders()["Connection"] = "close"; + addRespHeaders("Connection", "close"); + writeData(resp, strlen(resp)); +#ifdef _DEBUG_RPC_HANDLER + printf("++++(RPC Handler)Exit RPCHandler::doGet()\r\n"); +#endif +} + +void RPCHandler::doPost() +{ + +} + +void RPCHandler::doHead() +{ + +} + + +void RPCHandler::onReadable() //Data has been read +{ + +} + +void RPCHandler::onWriteable() //Data has been written & buf is free +{ +#ifdef _DEBUG_RPC_HANDLER + printf("++++(RPC Handler)onWriteable event\r\n"); +#endif + // close(); //Data written, we can close the connection +} + +void RPCHandler::onClose() //Connection is closing +{ + //Nothing to do +} + +void RPCHandler::cleanReq(char* data) +{ + char* p; + if((p = strstr(data, "+"))!=NULL)memset((void*) p, ' ', 1); + else if((p = strstr(data, ","))!=NULL)memset((void*) p, ' ', 1); + else if((p = strstr(data, "%20"))!=NULL) { + memset((void*) p, ' ', 1); + while(*(p+2)!=NULL) { + p++; + memset((void*) p,*(p+2),1); + } + } + + if((p = strstr(data, "+"))!=NULL)memset((void*) p, ' ', 1); + else if((p = strstr(data, ","))!=NULL)memset((void*) p, ' ', 1); + else if((p = strstr(data, "%20"))!=NULL) { + memset((void*) p, ' ', 1); + while(*(p+2)!=NULL) { + p++; + memset((void*) p,*(p+2),1); + } + } +} + + + +
diff -r 000000000000 -r 8e1971a883be Handler/RPCHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/RPCHandler.h Tue Dec 23 18:49:25 2014 +0000 @@ -0,0 +1,51 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +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. +*/ + +#ifndef RPC_HANDLER_H +#define RPC_HANDLER_H + +#include "../HTTPRequestHandler.h" + +class RPCHandler : public HTTPRequestHandler +{ +public: + RPCHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection); + virtual ~RPCHandler(); + +//protected: + static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) { return new RPCHandler(rootPath, path, pTCPSocketConnection); } //if we ever could do static virtual functions, this would be one + + virtual void doGet(); + virtual void doPost(); + virtual void doHead(); + + virtual void onReadable(); //Data has been read + virtual void onWriteable(); //Data has been written & buf is free + virtual void onClose(); //Connection is closing + +protected: + void cleanReq(char* data); +}; + +#endif +
diff -r 000000000000 -r 8e1971a883be Handler/SimpleHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/SimpleHandler.cpp Tue Dec 23 18:49:25 2014 +0000 @@ -0,0 +1,83 @@ +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +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_SIMPLE_HANDLER + +#include "SimpleHandler.h" + +SimpleHandler::SimpleHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) : HTTPRequestHandler(rootPath, path, pTCPSocketConnection) +{ +#ifdef _DEBUG_SIMPLE_HANDLER + printf("++++(SimpleHeandler)Initialize\r\n"); +#endif +} + +SimpleHandler::~SimpleHandler() +{ +#ifdef _DEBUG_SIMPLE_HANDLER + printf("++++(SimpleHeandler)Handler destroyed\r\n"); +#endif +} + +void SimpleHandler::doGet() +{ +#ifdef _DEBUG_SIMPLE_HANDLER + printf("++++(SimpleHeandler) doGet()\r\n"); +#endif + const char* resp = "Hello world !"; + setContentLen( strlen(resp) ); + //respHeaders()["Connection"] = "close"; + addRespHeaders("Connection", "close"); + writeData(resp, strlen(resp)); +#ifdef _DEBUG_SIMPLE_HANDLER + printf("++++(SimpleHeandler) doGet Exit\r\n"); +#endif +} + +void SimpleHandler::doPost() +{ + +} + +void SimpleHandler::doHead() +{ + +} + + +void SimpleHandler::onReadable() //Data has been read +{ + +} + +void SimpleHandler::onWriteable() //Data has been written & buf is free +{ +#ifdef _DEBUG_SIMPLE_HANDLER + printf("++++(SimpleHeandler)onWriteable() event\r\n"); +#endif +// close(); //Data written, we can close the connection +} + +void SimpleHandler::onClose() //Connection is closing +{ + //Nothing to do +} +
diff -r 000000000000 -r 8e1971a883be Handler/SimpleHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/SimpleHandler.h Tue Dec 23 18:49:25 2014 +0000 @@ -0,0 +1,47 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +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. +*/ + +#ifndef SIMPLE_HANDLER_H +#define SIMPLE_HANDLER_H + +#include "../HTTPRequestHandler.h" + +class SimpleHandler : public HTTPRequestHandler +{ +public: + SimpleHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection); + virtual ~SimpleHandler(); + +//protected: + static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) { return new SimpleHandler(rootPath, path, pTCPSocketConnection); } //if we ever could do static virtual functions, this would be one + + virtual void doGet(); + virtual void doPost(); + virtual void doHead(); + + virtual void onReadable(); //Data has been read + virtual void onWriteable(); //Data has been written & buf is free + virtual void onClose(); //Connection is closing +}; + +#endif