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

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPServer.h Source File

HTTPServer.h

00001 //#define _DEBUG_HTTP_SERVER_H
00002 
00003 #ifndef HTTP_SERVER_H
00004 #define HTTP_SERVER_H
00005 
00006 #define HELLO_PAGE "/hello"
00007 #define RPC_PAGE "/rpc"
00008 //#define IEEE1888WSDL_PAGE "/IEEE1888?wsdl"
00009 //#define IEEE1888_PAGE "/IEEE1888"
00010 #define FS_PAGE "/"
00011 
00012 #include <string>
00013 using std::string;
00014 
00015 #include <map>
00016 using std::map;
00017 
00018 #include "HTTPRequestHandler.h"
00019 #include "rtos.h"
00020 #include "mbed.h"
00021 #include "EthernetInterface.h"
00022 
00023 #include "Handler/RPCHandler.h"
00024 #include "Handler/FSHandler.h"
00025 #include "Handler/SimpleHandler.h"
00026 
00027 #define THREAD_MAX 3
00028 Thread *threads[THREAD_MAX];
00029 Thread *xthread;
00030 
00031 /*
00032 struct handlersComp { //Used to order handlers in the right way
00033     bool operator() (const string& handler1, const string& handler2) const {
00034         //The first handler is longer than the second one
00035         if (handler1.length() > handler2.length())
00036             return true; //Returns true if handler1 is to appear before handler2
00037         else if (handler1.length() < handler2.length())
00038             return false;
00039         else //To avoid the == case, sort now by address
00040             return ((&handler1)>(&handler2));
00041     }
00042 };
00043 
00044 map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocketConnection* ), handlersComp > m_lpHandlers;
00045 template<typename T>
00046 void HTTPServerAddHandler(const char* path)  //Template decl in header
00047 {
00048     m_lpHandlers[path] = &T::inst;
00049 }
00050 */
00051 
00052 void ListenThread(void const *args);
00053 enum HTTP_METH {
00054     HTTP_GET,
00055     HTTP_POST,
00056     HTTP_HEAD
00057 };
00058 
00059 bool getRequest(TCPSocketConnection* client,string* path, string* meth)
00060 {
00061     char req[128];
00062     char c_path[128];
00063     char c_meth[128];
00064     const int maxLen = 128;
00065     char* p = req;
00066     //Read Line
00067     int ret;
00068     int len = 0;
00069     for(int i = 0; i < maxLen - 1; i++) {
00070         ret = client->receive(p, 1);
00071         if(!ret) {
00072             break;
00073         }
00074         if( (len > 1) && *(p-1)=='\r' && *p=='\n' ) {
00075             p--;
00076             len-=2;
00077             break;
00078         } else if( *p=='\n' ) {
00079             len--;
00080             break;
00081         }
00082         p++;
00083         len++;
00084     }
00085     *p = 0;
00086 #ifdef _DEBUG_HTTP_SERVER_H
00087     printf("Parsing request : %s\r\n", req);
00088 #endif
00089     ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path);
00090     if(ret !=2)        return false;
00091     *meth = string(c_meth);
00092     *path = string(c_path);
00093     return true;
00094 }
00095 
00096 void dispatchRequest(TCPSocketConnection* client)
00097 {
00098     string path;
00099     string meth;
00100     HTTP_METH methCode;
00101 #ifdef _DEBUG_HTTP_SERVER_H
00102     printf("Dispatching req\r\n");
00103 #endif
00104     if( !getRequest(client,&path, &meth ) ) {
00105 #ifdef _DEBUG_HTTP_SERVER_H
00106         printf("dispatchRequest Invalid request\r\n");
00107 #endif
00108         //close();
00109         return; //Invalid request
00110     }
00111     if( !meth.compare("GET") ) {
00112 #ifdef _DEBUG_HTTP_SERVER_H
00113         printf("dispatchRequest HTTP_GET\r\n");
00114 #endif
00115         methCode = HTTP_GET;
00116     } else if( !meth.compare("POST") ) {
00117 #ifdef _DEBUG_HTTP_SERVER_H
00118         printf("dispatchRequest HTTP_POST\r\n");
00119 #endif
00120         methCode = HTTP_POST;
00121     } else if( !meth.compare("HEAD") ) {
00122 #ifdef _DEBUG_HTTP_SERVER_H
00123         printf("dispatchRequest HTTP_HEAD\r\n");
00124 #endif
00125         methCode = HTTP_HEAD;
00126     } else {
00127 #ifdef _DEBUG_HTTP_SERVER_H
00128         printf("dispatchRequest() Parse error\r\n");
00129 #endif
00130         //close(); //Parse error
00131         return;
00132     }
00133 #ifdef _DEBUG_HTTP_SERVER_H
00134     printf("Looking for a handler\r\n");
00135 #endif
00136     /*
00137         map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocketConnection*) >::iterator it;
00138         int root_len = 0;
00139         for (it = m_lpHandlers.begin(); it != m_lpHandlers.end(); it++) {
00140     #ifdef _DEBUG_HTTP_SERVER_H
00141             printf("Checking %s...\r\n", (*it).first.c_str());
00142     #endif
00143             root_len = (*it).first.length();
00144             if ( root_len &&
00145                     !path.compare( 0, root_len, (*it).first ) &&
00146                     (path[root_len] == '/' || path[root_len] == '\0')) {
00147     #ifdef _DEBUG_HTTP_SERVER_H
00148                 printf("Found (%s)\r\n", (*it).first.c_str());
00149     #endif
00150                 // Found!
00151                 break;  // for
00152             }
00153         }
00154         if((it == m_lpHandlers.end()) && !(m_lpHandlers.empty())) {
00155     #ifdef _DEBUG_HTTP_SERVER_H
00156             printf("Using default handler\r\n");
00157     #endif
00158             it = m_lpHandlers.end();
00159             it--; //Get the last element
00160             if( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler
00161                 it = m_lpHandlers.end();
00162             root_len = 0;
00163         }
00164         if(it == m_lpHandlers.end()) {
00165     #ifdef _DEBUG_HTTP_SERVER_H
00166             printf("No handler found\r\n");
00167     #endif
00168             return;
00169         }
00170     #ifdef _DEBUG_HTTP_SERVER_H
00171         printf("Handler found.\r\n");
00172     #endif
00173         HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, client);
00174     */
00175     HTTPRequestHandler* pHdlr;
00176     if (!path.compare(0,strlen(HELLO_PAGE),HELLO_PAGE)) {
00177 #ifdef _DEBUG_HTTP_SERVER_H
00178         printf("HELLO PAGE CREATE. PATH %s: %s \r\n",HELLO_PAGE, path.c_str() + strlen(HELLO_PAGE));
00179 #endif
00180         pHdlr = new SimpleHandler(HELLO_PAGE, path.c_str() + strlen(HELLO_PAGE), client);
00181     }
00182     
00183 #ifdef RPC_PAGE
00184     else if (!path.compare(0,strlen(RPC_PAGE),RPC_PAGE)) {
00185 #ifdef _DEBUG_HTTP_SERVER_H
00186         printf("RPC PAGE CREATE. PATH %s: %s \r\n",RPC_PAGE, path.c_str() + strlen(RPC_PAGE));
00187 #endif
00188         pHdlr = new RPCHandler(RPC_PAGE, path.c_str() + strlen(RPC_PAGE), client);
00189     }
00190 #endif
00191 
00192 #ifdef IEEE1888WSDL_PAGE
00193     else if (!path.compare(0,strlen(IEEE1888WSDL_PAGE),IEEE1888WSDL_PAGE)) {
00194 #ifdef _DEBUG_HTTP_SERVER_H
00195         printf("IEEE1888WSDL_PAGE CREATE. PATH %s: %s \r\n",IEEE1888WSDL_PAGE, path.c_str() + strlen(IEEE1888WSDL_PAGE));
00196 #endif
00197         pHdlr = new IEEE1888WSDLHandler(IEEE1888WSDL_PAGE, path.c_str() + strlen(IEEE1888WSDL_PAGE)-1, client);
00198     }
00199 #endif
00200 
00201 #ifdef IEEE1888_PAGE
00202     else if (!path.compare(0,strlen(IEEE1888_PAGE),IEEE1888_PAGE)) {
00203 #ifdef _DEBUG_HTTP_SERVER_H
00204         printf("IEEE1888_PAGE CREATE. PATH %s: %s \r\n",IEEE1888_PAGE, path.c_str() + strlen(IEEE1888_PAGE));
00205 #endif
00206         pHdlr = new IEEE1888Handler(IEEE1888_PAGE, path.c_str() + strlen(IEEE1888_PAGE)-1, client);
00207     }
00208 #endif
00209 
00210 #ifdef FS_PAGE
00211     else if (!path.compare(0,strlen(FS_PAGE),FS_PAGE)) {
00212 #ifdef _DEBUG_HTTP_SERVER_H
00213         printf("FS_PAGE CREATE. PATH %s: %s \r\n",FS_PAGE, path.c_str() + strlen(FS_PAGE));
00214 #endif
00215         pHdlr = new FSHandler(FS_PAGE, path.c_str() + strlen(FS_PAGE)-1, client);
00216     }
00217 #endif
00218 
00219     else {
00220 #ifdef _DEBUG_HTTP_SERVER_H
00221         printf("No handler found\r\n");
00222 #endif
00223         pHdlr = new SimpleHandler(HELLO_PAGE, path.c_str() + strlen(HELLO_PAGE), client);
00224         return;
00225     }
00226     //****  client = NULL; //We don't own it anymore
00227 #ifdef _DEBUG_HTTP_SERVER_H
00228     printf("Handler Created.\r\n");
00229 #endif
00230     switch(methCode) {
00231         case HTTP_GET:
00232             pHdlr->doGet();
00233             break;
00234         case HTTP_POST:
00235             pHdlr->doPost();
00236             break;
00237         case HTTP_HEAD:
00238             pHdlr->doHead();
00239             break;
00240     }
00241 #ifdef _DEBUG_HTTP_SERVER_H
00242     printf("Handler Delete.\r\n");
00243 #endif
00244     delete pHdlr;
00245     // delete client;
00246     //delete pTCPSocketConnection;
00247 #ifdef _DEBUG_HTTP_SERVER_H
00248     printf("(dispatcherRequest)return\r\n");
00249 #endif
00250     return ;
00251 }
00252 
00253 void HTTPServerChild (void const *arg)
00254 {
00255 #ifdef _DEBUG_HTTP_SERVER_H
00256     printf("HTTPServerChiled Start......\r\n");
00257 #endif
00258     TCPSocketConnection* client = (TCPSocketConnection*)arg;
00259 
00260     for (;;) {
00261 #ifdef _DEBUG_HTTP_SERVER_H
00262         printf("(HTTPServer.h<HTTPServerChild>)Connection from %s\r\n", client->get_address());
00263 #endif
00264         dispatchRequest(client);
00265 #ifdef _DEBUG_HTTP_SERVER_H
00266         printf("(HTTPServer.h<HTTPServerChild>)Client->Close %s\r\n", client->get_address());
00267 #endif
00268         client->close();
00269 #ifdef _DEBUG_HTTP_SERVER_H
00270  //       printf("(HTTPServer.h<HTTPServerChild>)Client->reset\r\n");
00271 #endif
00272  //       client->reset_address();
00273 #ifdef _DEBUG_HTTP_SERVER_H
00274         printf("(HTTPServer.h<HTTPServerChild>)Thread::signal_wait(1)\r\n");
00275 #endif        //delete client;
00276         Thread::signal_wait(1);
00277 #ifdef _DEBUG_HTTP_SERVER_H
00278         printf("(HTTPServer.h<HTTPServerChild>)Return \r\n");
00279 #endif
00280     }
00281 }
00282 
00283 void HTTPServerCloser (void const *arg)
00284 {
00285     TCPSocketConnection *client = (TCPSocketConnection*)arg;
00286 #ifdef _DEBUG_HTTP_SERVER_H
00287         printf("HTTPCloser start%s\r\n", client->get_address());
00288 #endif
00289 
00290     for (;;) {
00291         client->close();
00292 #ifdef _DEBUG_HTTP_SERVER_H
00293         printf("Close %s\r\n", client->get_address());
00294 #endif
00295         Thread::signal_wait(1);
00296     }
00297 }
00298 
00299 void HTTPServerStart(int port = 80)
00300 {
00301     int i, t = 0;
00302     TCPSocketConnection clients[THREAD_MAX];
00303     TCPSocketConnection xclient;
00304 
00305     for (i = 0; i < THREAD_MAX; i ++) {
00306         threads[i] = NULL;
00307     }
00308     xthread = NULL;
00309 
00310     TCPSocketServer server;
00311     server.bind(port);
00312     server.listen();
00313     // server.set_blocking(false);
00314 #ifdef _DEBUG_HTTP_SERVER_H
00315     printf("Wait for new connection...\r\n");
00316 #endif
00317     for (;;) {
00318 #ifdef _DEBUG_HTTP_SERVER_H
00319         printf("**Start Loop** \r\n");
00320 #endif
00321         if (t >= 0) {
00322             if(server.accept(clients[t])==0) {
00323                 // fork child process
00324                 if (threads[t]) {
00325                     threads[t]->signal_set(1);
00326                 } else {
00327                     threads[t] = new Thread(HTTPServerChild, (void*)&clients[t]);
00328                 }
00329 #ifdef _DEBUG_HTTP_SERVER_H
00330                 printf("Forked %d\r\n", t);
00331 #endif
00332             }
00333         } else {
00334             if(server.accept(xclient)==0) {
00335                 // closer process
00336                 if (xthread) {
00337                     xthread->signal_set(1);
00338                 } else {
00339                     xthread = new Thread(HTTPServerCloser, (void*)&xclient);
00340                 }
00341 #ifdef _DEBUG_HTTP_SERVER_H
00342                 printf("Connection full\r\n");
00343 #endif
00344             }
00345         }
00346 
00347         t = -1;
00348         for (i = 0; i < THREAD_MAX; i ++) {
00349             if (threads[i] == NULL || threads[i]->get_state() == Thread::WaitingAnd) {
00350                 if (t < 0) t = i; // next empty thread
00351             }
00352         }
00353         // Thread::wait(100);
00354     }
00355 }
00356 
00357 
00358 #endif
00359 
00360