Adaptation of the HttpServer by user yueee_yt. This version has improved handling of the HTTP headers (**NOTE**: There are limitations with this implementation and it is not fully functional. Use it only as a starting point.)
Dependents: DMSupport DMSupport DMSupport DMSupport
Fork of DM_HttpServer by
HTTPServer.h
00001 //#define _DEBUG_ALL 00002 00003 #ifndef HTTP_SERVER_H 00004 #define HTTP_SERVER_H 00005 00006 #ifdef _DEBUG_ALL 00007 #define _DEBUG_HTTP_SERVER_H 00008 #endif 00009 00010 #include <string> 00011 using std::string; 00012 00013 #include <map> 00014 using std::map; 00015 00016 #include "HTTPRequestHandler.h" 00017 #include "rtos.h" 00018 #include "mbed.h" 00019 #include "EthernetInterface.h" 00020 //#include "HTTPRequestDispatcher.h" 00021 00022 //#include "dbg/dbg.h" 00023 00024 #define THREAD_MAX 5 00025 Thread *threads[THREAD_MAX]; 00026 Thread *xthread; 00027 //#include "HTTPServer2.h" 00028 00029 struct handlersComp { //Used to order handlers in the right way 00030 bool operator() (const string& handler1, const string& handler2) const { 00031 //The first handler is longer than the second one 00032 if (handler1.length() > handler2.length()) 00033 return true; //Returns true if handler1 is to appear before handler2 00034 else if (handler1.length() < handler2.length()) 00035 return false; 00036 else //To avoid the == case, sort now by address 00037 return ((&handler1)>(&handler2)); 00038 } 00039 }; 00040 00041 map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocket* ), handlersComp > m_lpHandlers; 00042 template<typename T> 00043 void HTTPServerAddHandler(const char* path) //Template decl in header 00044 { 00045 m_lpHandlers[path] = &T::inst; 00046 } 00047 00048 void ListenThread(void const *args); 00049 enum HTTP_METH { 00050 HTTP_GET, 00051 HTTP_POST, 00052 HTTP_HEAD 00053 }; 00054 00055 bool getRequest(TCPSocket* client,string* path, string* meth) 00056 { 00057 char req[128]; 00058 char c_path[128]; 00059 char c_meth[128]; 00060 const int maxLen = 128; 00061 char* p = req; 00062 //Read Line 00063 int ret; 00064 int len = 0; 00065 for(int i = 0; i < maxLen - 1; i++) { 00066 ret = client->recv(p, 1); 00067 if(!ret) { 00068 break; 00069 } 00070 if( (len > 1) && *(p-1)=='\r' && *p=='\n' ) { 00071 p--; 00072 len-=2; 00073 break; 00074 } else if( *p=='\n' ) { 00075 len--; 00076 break; 00077 } 00078 p++; 00079 len++; 00080 } 00081 *p = 0; 00082 #ifdef _DEBUG_HTTP_SERVER_H 00083 printf("Parsing request : %s\r\n", req); 00084 #endif 00085 ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path); 00086 if(ret !=2) return false; 00087 *meth = string(c_meth); 00088 *path = string(c_path); 00089 return true; 00090 } 00091 00092 void dispatchRequest(TCPSocket* client) 00093 { 00094 string path; 00095 string meth; 00096 HTTP_METH methCode; 00097 #ifdef _DEBUG_HTTP_SERVER_H 00098 printf("Dispatching req\r\n"); 00099 #endif 00100 if( !getRequest(client,&path, &meth ) ) { 00101 #ifdef _DEBUG_HTTP_SERVER_H 00102 printf("dispatchRequest Invalid request\r\n"); 00103 #endif 00104 //close(); 00105 return; //Invalid request 00106 } 00107 if( !meth.compare("GET") ) { 00108 #ifdef _DEBUG_HTTP_SERVER_H 00109 printf("dispatchRequest HTTP_GET\r\n"); 00110 #endif 00111 methCode = HTTP_GET; 00112 } else if( !meth.compare("POST") ) { 00113 #ifdef _DEBUG_HTTP_SERVER_H 00114 printf("dispatchRequest HTTP_POST\r\n"); 00115 #endif 00116 methCode = HTTP_POST; 00117 } else if( !meth.compare("HEAD") ) { 00118 #ifdef _DEBUG_HTTP_SERVER_H 00119 printf("dispatchRequest HTTP_HEAD\r\n"); 00120 #endif 00121 methCode = HTTP_HEAD; 00122 } else { 00123 #ifdef _DEBUG_HTTP_SERVER_H 00124 printf("dispatchRequest() Parse error\r\n"); 00125 #endif 00126 //close(); //Parse error 00127 return; 00128 } 00129 #ifdef _DEBUG_HTTP_SERVER_H 00130 printf("Looking for a handler\r\n"); 00131 #endif 00132 map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocket*) >::iterator it; 00133 int root_len = 0; 00134 for (it = m_lpHandlers.begin(); it != m_lpHandlers.end(); it++) { 00135 #ifdef _DEBUG_HTTP_SERVER_H 00136 printf("Checking %s...\r\n", (*it).first.c_str()); 00137 #endif 00138 root_len = (*it).first.length(); 00139 if ( root_len && 00140 !path.compare( 0, root_len, (*it).first ) && 00141 (path[root_len] == '/' || path[root_len] == '\0')) { 00142 #ifdef _DEBUG_HTTP_SERVER_H 00143 printf("Found (%s)\r\n", (*it).first.c_str()); 00144 #endif 00145 // Found! 00146 break; // for 00147 } 00148 } 00149 if((it == m_lpHandlers.end()) && !(m_lpHandlers.empty())) { 00150 #ifdef _DEBUG_HTTP_SERVER_H 00151 printf("Using default handler\r\n"); 00152 #endif 00153 it = m_lpHandlers.end(); 00154 it--; //Get the last element 00155 if( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler 00156 it = m_lpHandlers.end(); 00157 root_len = 0; 00158 } 00159 if(it == m_lpHandlers.end()) { 00160 #ifdef _DEBUG_HTTP_SERVER_H 00161 printf("No handler found\r\n"); 00162 #endif 00163 return; 00164 } 00165 #ifdef _DEBUG_HTTP_SERVER_H 00166 printf("Handler found.\r\n"); 00167 #endif 00168 HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, client); 00169 //**** client = NULL; //We don't own it anymore 00170 switch(methCode) { 00171 case HTTP_GET: 00172 pHdlr->doGet(); 00173 break; 00174 case HTTP_POST: 00175 pHdlr->doPost(); 00176 break; 00177 case HTTP_HEAD: 00178 pHdlr->doHead(); 00179 break; 00180 } 00181 delete pHdlr; 00182 // delete client; 00183 // delete m_pTCPSocketConnection; 00184 #ifdef _DEBUG_HTTP_SERVER_H 00185 printf("(dispatcherRequest)return\r\n"); 00186 #endif 00187 return ; 00188 } 00189 00190 void HTTPServerChild (void const *arg) 00191 { 00192 #ifdef _DEBUG_HTTP_SERVER_H 00193 SocketAddress remoteAddress; 00194 printf("HTTPServerChiled Start......\r\n"); 00195 #endif 00196 TCPSocket* client = (TCPSocket*)arg; 00197 00198 for (;;) { 00199 #ifdef _DEBUG_HTTP_SERVER_H 00200 client->getpeername(&remoteAddress); 00201 printf("(HTTPServer.h<HTTPServerChild>)Connection from %s\r\n", remoteAddress.get_ip_address()); 00202 #endif 00203 dispatchRequest(client); 00204 #ifdef _DEBUG_HTTP_SERVER_H 00205 client->getpeername(&remoteAddress); 00206 printf("(HTTPServer.h<HTTPServerChild>)Close %s\r\n", remoteAddress.get_ip_address()); 00207 #endif 00208 client->close(); 00209 // client->reset_address(); 00210 //delete client; 00211 ThisThread::flags_wait_any(1); 00212 } 00213 } 00214 00215 void HTTPServerCloser (void const *arg) 00216 { 00217 #ifdef _DEBUG_HTTP_SERVER_H 00218 SocketAddress remoteAddress; 00219 #endif 00220 TCPSocket *client = (TCPSocket*)arg; 00221 00222 for (;;) { 00223 #ifdef _DEBUG_HTTP_SERVER_H 00224 client->getpeername(&remoteAddress); 00225 printf("Close %s, %x\r\n", remoteAddress.get_ip_address(), client); 00226 #endif 00227 client->close(); 00228 ThisThread::flags_wait_any(1); 00229 } 00230 } 00231 00232 void HTTPServerStart(int port = 80) 00233 { 00234 int i, t = 0; 00235 nsapi_error_t ret; 00236 TCPSocket* clients[THREAD_MAX]; 00237 TCPSocket* xclient; 00238 00239 for (i = 0; i < THREAD_MAX; i ++) { 00240 threads[i] = NULL; 00241 } 00242 xthread = NULL; 00243 00244 TCPSocket server; 00245 00246 00247 ret = server.open(NetworkInterface::get_default_instance()); 00248 if (ret != NSAPI_ERROR_OK) { 00249 printf("HTTPServer: open failed %d\n", ret); 00250 return; 00251 } 00252 00253 ret = server.bind(port); 00254 if (ret != NSAPI_ERROR_OK) { 00255 printf("HTTPServer: bind failed %d\n", ret); 00256 return; 00257 } 00258 server.listen(); 00259 // server.set_blocking(false); 00260 #ifdef _DEBUG_HTTP_SERVER_H 00261 printf("Wait for new connection...\r\n"); 00262 #endif 00263 for (;;) { 00264 #ifdef _DEBUG_HTTP_SERVER_H 00265 printf("**Start Loop** \r\n"); 00266 #endif 00267 if (t >= 0) { 00268 00269 clients[t] = server.accept(); 00270 //if(server.accept(clients[t])==0) { 00271 if (clients[t] != NULL) { 00272 // fork child process 00273 if (threads[t]) { 00274 threads[t]->flags_set(1); 00275 } else { 00276 00277 threads[t] = new Thread(osPriorityNormal, OS_STACK_SIZE*2); 00278 if (threads[t] != NULL) { 00279 00280 threads[t]->start(callback(HTTPServerChild, (void*)clients[t])); 00281 } 00282 } 00283 #ifdef _DEBUG_HTTP_SERVER_H 00284 printf("Forked %d\r\n", t); 00285 #endif 00286 } 00287 } else { 00288 xclient = server.accept(); 00289 //if(server.accept(xclient)==0) { 00290 if (xclient != NULL) { 00291 // closer process 00292 if (xthread) { 00293 xthread->flags_set(1); 00294 } else { 00295 xthread = new Thread(osPriorityNormal, OS_STACK_SIZE*2); 00296 if (xthread != NULL) { 00297 xthread->start(callback(HTTPServerChild, (void*)xclient)); 00298 } 00299 } 00300 #ifdef _DEBUG_HTTP_SERVER_H 00301 printf("Connection full\r\n"); 00302 #endif 00303 } 00304 } 00305 00306 t = -1; 00307 for (i = 0; i < THREAD_MAX; i ++) { 00308 if (threads[i] == NULL || threads[i]->get_state() == Thread::WaitingThreadFlag) { 00309 if (t < 0) t = i; // next empty thread 00310 } 00311 } 00312 // Thread::wait(100); 00313 } 00314 } 00315 //#include "Handler/RPCHandler.h" 00316 #include "Handler/FSHandler.h" 00317 #include "Handler/SimpleHandler.h" 00318 00319 #endif
Generated on Sat Jul 16 2022 20:32:10 by 1.7.2