ソースの整理中ですが、利用はできます。

Dependencies:   EthernetInterface HttpServer TextLCD mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Revision:
0:7766f6712673
--- /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
+
+