HttpServer Library for "mbed classic" which added a snapshot handler.
Dependents: GR-PEACH_WebCamera_OV5642_fixedIP GR-PEACH_WebCamera_AP
Fork of 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* , TCPSocketConnection* ), 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(TCPSocketConnection* 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->receive(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(TCPSocketConnection* 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*, TCPSocketConnection*), handlersComp >::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 printf("HTTPServerChiled Start......\r\n"); 00194 #endif 00195 TCPSocketConnection* client = (TCPSocketConnection*)arg; 00196 00197 for (;;) { 00198 #ifdef _DEBUG_HTTP_SERVER_H 00199 printf("(HTTPServer.h<HTTPServerChild>)Connection from %s\r\n", client->get_address()); 00200 #endif 00201 dispatchRequest(client); 00202 #ifdef _DEBUG_HTTP_SERVER_H 00203 printf("(HTTPServer.h<HTTPServerChild>)Close %s\r\n", client->get_address()); 00204 #endif 00205 client->close(); 00206 client->reset_address(); 00207 //delete client; 00208 Thread::signal_wait(1); 00209 } 00210 } 00211 00212 void HTTPServerCloser (void const *arg) 00213 { 00214 TCPSocketConnection *client = (TCPSocketConnection*)arg; 00215 00216 for (;;) { 00217 client->close(); 00218 #ifdef _DEBUG_HTTP_SERVER_H 00219 printf("Close %s\r\n", client->get_address()); 00220 #endif 00221 Thread::signal_wait(1); 00222 } 00223 } 00224 00225 void HTTPServerStart(int port = 80) 00226 { 00227 int i, t = 0; 00228 TCPSocketConnection clients[THREAD_MAX]; 00229 TCPSocketConnection xclient; 00230 00231 for (i = 0; i < THREAD_MAX; i ++) { 00232 threads[i] = NULL; 00233 } 00234 xthread = NULL; 00235 00236 TCPSocketServer server; 00237 server.bind(port); 00238 server.listen(); 00239 // server.set_blocking(false); 00240 #ifdef _DEBUG_HTTP_SERVER_H 00241 printf("Wait for new connection...\r\n"); 00242 #endif 00243 for (;;) { 00244 #ifdef _DEBUG_HTTP_SERVER_H 00245 printf("**Start Loop** \r\n"); 00246 #endif 00247 if (t >= 0) { 00248 if(server.accept(clients[t])==0) { 00249 // fork child process 00250 if (threads[t]) { 00251 threads[t]->signal_set(1); 00252 } else { 00253 threads[t] = new Thread(HTTPServerChild, (void*)&clients[t], osPriorityNormal, 1024 * 3, NULL); 00254 } 00255 #ifdef _DEBUG_HTTP_SERVER_H 00256 printf("Forked %d\r\n", t); 00257 #endif 00258 } 00259 } else { 00260 if(server.accept(xclient)==0) { 00261 // closer process 00262 if (xthread) { 00263 xthread->signal_set(1); 00264 } else { 00265 xthread = new Thread(HTTPServerCloser, (void*)&xclient); 00266 } 00267 #ifdef _DEBUG_HTTP_SERVER_H 00268 printf("Connection full\r\n"); 00269 #endif 00270 } 00271 } 00272 00273 t = -1; 00274 for (i = 0; i < THREAD_MAX; i ++) { 00275 if ((threads[i] == NULL) 00276 || ((threads[i]->get_state() == Thread::WaitingAnd) && (*clients[i].get_address() == 0))) { 00277 if (t < 0) t = i; // next empty thread 00278 } 00279 } 00280 // Thread::wait(100); 00281 } 00282 } 00283 #include "Handler/RPCHandler.h" 00284 #include "Handler/FSHandler.h" 00285 #include "Handler/SimpleHandler.h" 00286 #include "SnapshotHandler.h" 00287 00288 #endif
Generated on Sat Jul 16 2022 00:30:13 by 1.7.2