HttpServer Library for "mbed-os" which added a snapshot handler.
Dependents: GR-PEACH-webcam GR-Boards_WebCamera GR-Boards_WebCamera GR-Boards_WebCamera
Fork of HttpServer_snapshot by
HTTPServer.h
00001 //#define _DEBUG_ALL 00002 00003 #ifndef HTTP_SERVER_H 00004 #define HTTP_SERVER_H 00005 00006 #ifdef _DEBUG_ALL 00007 #include <stdio.h> 00008 #include <stdarg.h> 00009 static inline void http_server_debug_print(const char *format, ...) { 00010 va_list args; 00011 va_start(args, format); 00012 vfprintf(stderr, format, args); 00013 va_end(args); 00014 } 00015 #else 00016 static inline void http_server_debug_print(const char *format, ...) {} 00017 #endif 00018 00019 #include <string> 00020 using std::string; 00021 00022 #include <map> 00023 using std::map; 00024 00025 #include "HTTPRequestHandler.h" 00026 #include "rtos.h" 00027 #include "mbed.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 <= 0) { 00068 return false; 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 http_server_debug_print("Parsing request : %s\r\n", req); 00083 ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path); 00084 if(ret !=2) return false; 00085 *meth = string(c_meth); 00086 *path = string(c_path); 00087 return true; 00088 } 00089 00090 void dispatchRequest(TCPSocket* client) 00091 { 00092 string path; 00093 string meth; 00094 HTTP_METH methCode; 00095 http_server_debug_print("Dispatching req\r\n"); 00096 if( !getRequest(client,&path, &meth ) ) { 00097 http_server_debug_print("dispatchRequest Invalid request\r\n"); 00098 return; //Invalid request 00099 } 00100 if( !meth.compare("GET") ) { 00101 http_server_debug_print("dispatchRequest HTTP_GET\r\n"); 00102 methCode = HTTP_GET; 00103 } else if( !meth.compare("POST") ) { 00104 http_server_debug_print("dispatchRequest HTTP_POST\r\n"); 00105 methCode = HTTP_POST; 00106 } else if( !meth.compare("HEAD") ) { 00107 http_server_debug_print("dispatchRequest HTTP_HEAD\r\n"); 00108 methCode = HTTP_HEAD; 00109 } else { 00110 http_server_debug_print("dispatchRequest() Parse error\r\n"); 00111 return; 00112 } 00113 http_server_debug_print("Looking for a handler\r\n"); 00114 map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocket*), handlersComp >::iterator it; 00115 int root_len = 0; 00116 for (it = m_lpHandlers.begin(); it != m_lpHandlers.end(); it++) { 00117 http_server_debug_print("Checking %s...\r\n", (*it).first.c_str()); 00118 root_len = (*it).first.length(); 00119 if ( root_len && 00120 !path.compare( 0, root_len, (*it).first ) && 00121 (path[root_len] == '/' || path[root_len] == '\0')) { 00122 http_server_debug_print("Found (%s)\r\n", (*it).first.c_str()); 00123 // Found! 00124 break; // for 00125 } 00126 } 00127 if((it == m_lpHandlers.end()) && !(m_lpHandlers.empty())) { 00128 http_server_debug_print("Using default handler\r\n"); 00129 it = m_lpHandlers.end(); 00130 it--; //Get the last element 00131 if( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler 00132 it = m_lpHandlers.end(); 00133 root_len = 0; 00134 } 00135 if(it == m_lpHandlers.end()) { 00136 http_server_debug_print("No handler found\r\n"); 00137 return; 00138 } 00139 http_server_debug_print("Handler found.\r\n"); 00140 HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, client); 00141 //**** client = NULL; //We don't own it anymore 00142 switch(methCode) { 00143 case HTTP_GET: 00144 pHdlr->doGet(); 00145 break; 00146 case HTTP_POST: 00147 pHdlr->doPost(); 00148 break; 00149 case HTTP_HEAD: 00150 pHdlr->doHead(); 00151 break; 00152 } 00153 delete pHdlr; 00154 http_server_debug_print("(dispatcherRequest)return\r\n"); 00155 return ; 00156 } 00157 00158 #ifndef HTTP_SERVER_THREAD_MAX 00159 #define HTTP_SERVER_THREAD_MAX 1 00160 #endif 00161 00162 #if (HTTP_SERVER_THREAD_MAX > 1) 00163 static Thread *threads[HTTP_SERVER_THREAD_MAX]; 00164 static bool soket_rady[HTTP_SERVER_THREAD_MAX]; 00165 static TCPSocket * clients[HTTP_SERVER_THREAD_MAX]; 00166 00167 static void HTTPServerChild (void* param) 00168 { 00169 bool* p_rady = &soket_rady[(int)param]; 00170 00171 while (1) { 00172 ThisThread::flags_wait_all(1); 00173 TCPSocket* client = clients[(int)param]; 00174 dispatchRequest(client); 00175 client->close(); 00176 *p_rady = true; 00177 } 00178 } 00179 00180 void HTTPServerStart(NetworkInterface *net, int port = 80, osPriority priority = osPriorityNormal) 00181 { 00182 int i; 00183 TCPSocket server; 00184 00185 for (i = 0; i < HTTP_SERVER_THREAD_MAX; i++) { 00186 soket_rady[i] = true; 00187 threads[i] = new Thread(priority, 1024 * 3); 00188 threads[i]->start(callback(HTTPServerChild, (void *)i)); 00189 } 00190 00191 server.open(net); 00192 server.bind(port); 00193 server.listen(); 00194 http_server_debug_print("Wait for new connection...\r\n"); 00195 00196 while (1) { 00197 while (1) { 00198 for (i = 0; i < HTTP_SERVER_THREAD_MAX; i++) { 00199 if (soket_rady[i] != false) { 00200 break; 00201 } 00202 } 00203 if (i < HTTP_SERVER_THREAD_MAX) { 00204 break; 00205 } 00206 ThisThread::sleep_for(5); 00207 } 00208 00209 clients[i] = server.accept(); 00210 if (clients[i] != NULL) { 00211 // fork child process 00212 soket_rady[i] = false; 00213 threads[i]->flags_set(1); 00214 } 00215 } 00216 } 00217 00218 #else // HTTP_SERVER_THREAD_MAX == 1 00219 00220 void HTTPServerStart(NetworkInterface *net, int port = 80, osPriority priority = osPriorityNormal) 00221 { 00222 TCPSocket server; 00223 TCPSocket * p_client; 00224 00225 (void)priority; 00226 00227 server.open(net); 00228 server.bind(port); 00229 server.listen(); 00230 http_server_debug_print("Wait for new connection...\r\n"); 00231 00232 while (1) { 00233 p_client = server.accept(); 00234 if (p_client != NULL) { 00235 dispatchRequest(p_client); 00236 p_client->close(); 00237 } 00238 } 00239 } 00240 00241 #endif 00242 00243 #include "Handler/RPCHandler.h" 00244 #include "Handler/FSHandler.h" 00245 #include "Handler/SimpleHandler.h" 00246 #include "SnapshotHandler.h" 00247 00248 #endif
Generated on Tue Jul 12 2022 21:18:29 by 1.7.2