ソースの整理中ですが、利用はできます。 大きなファイルはできないかもしれません。
Dependencies: EthernetInterface HttpServer TextLCD expatlib mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip
Fork of giken9_HTMLServer_Sample by
Diff: HttpServer/HTTPServer.h
- Revision:
- 0:7766f6712673
- Child:
- 1:bd7da995f192
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HttpServer/HTTPServer.h Wed Mar 12 04:19:54 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 + +