ソースの整理中ですが、利用はできます。
Dependencies: EthernetInterface HttpServer TextLCD mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip
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
Generated on Tue Jul 12 2022 13:42:53 by 1.7.2