
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/HTTPServer.h
- Revision:
- 4:28e8af6595f7
- Parent:
- 3:f0c16cc3a4ef
- Child:
- 5:d98cf6df5187
--- a/HttpServer/HTTPServer.h Tue Dec 23 18:40:55 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,360 +0,0 @@ -//#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 - -