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 Renesas

Committer:
dkato
Date:
Fri Oct 28 06:15:29 2016 +0000
Revision:
11:0700755d64ae
Parent:
10:4ab2f287d06d
Child:
13:d3571c244759
Change for the mbed-os.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yueee_yt 4:1b6b021ee21d 1 //#define _DEBUG_ALL
yueee_yt 4:1b6b021ee21d 2
yueee_yt 0:fdf9c2c5200f 3 #ifndef HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 4 #define HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 5
yueee_yt 4:1b6b021ee21d 6 #ifdef _DEBUG_ALL
yueee_yt 4:1b6b021ee21d 7 #define _DEBUG_HTTP_SERVER_H
yueee_yt 4:1b6b021ee21d 8 #endif
yueee_yt 4:1b6b021ee21d 9
yueee_yt 0:fdf9c2c5200f 10 #include <string>
yueee_yt 0:fdf9c2c5200f 11 using std::string;
yueee_yt 0:fdf9c2c5200f 12
yueee_yt 0:fdf9c2c5200f 13 #include <map>
yueee_yt 0:fdf9c2c5200f 14 using std::map;
yueee_yt 0:fdf9c2c5200f 15
yueee_yt 0:fdf9c2c5200f 16 #include "HTTPRequestHandler.h"
yueee_yt 0:fdf9c2c5200f 17 #include "rtos.h"
yueee_yt 0:fdf9c2c5200f 18 #include "mbed.h"
yueee_yt 0:fdf9c2c5200f 19
yueee_yt 0:fdf9c2c5200f 20 #define THREAD_MAX 5
yueee_yt 0:fdf9c2c5200f 21 Thread *threads[THREAD_MAX];
yueee_yt 0:fdf9c2c5200f 22 Thread *xthread;
yueee_yt 0:fdf9c2c5200f 23
yueee_yt 0:fdf9c2c5200f 24 struct handlersComp { //Used to order handlers in the right way
yueee_yt 0:fdf9c2c5200f 25 bool operator() (const string& handler1, const string& handler2) const {
yueee_yt 0:fdf9c2c5200f 26 //The first handler is longer than the second one
yueee_yt 0:fdf9c2c5200f 27 if (handler1.length() > handler2.length())
yueee_yt 0:fdf9c2c5200f 28 return true; //Returns true if handler1 is to appear before handler2
yueee_yt 0:fdf9c2c5200f 29 else if (handler1.length() < handler2.length())
yueee_yt 0:fdf9c2c5200f 30 return false;
yueee_yt 0:fdf9c2c5200f 31 else //To avoid the == case, sort now by address
yueee_yt 0:fdf9c2c5200f 32 return ((&handler1)>(&handler2));
yueee_yt 0:fdf9c2c5200f 33 }
yueee_yt 0:fdf9c2c5200f 34 };
yueee_yt 0:fdf9c2c5200f 35
dkato 11:0700755d64ae 36 map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocket* ), handlersComp > m_lpHandlers;
yueee_yt 0:fdf9c2c5200f 37 template<typename T>
yueee_yt 0:fdf9c2c5200f 38 void HTTPServerAddHandler(const char* path) //Template decl in header
yueee_yt 0:fdf9c2c5200f 39 {
yueee_yt 0:fdf9c2c5200f 40 m_lpHandlers[path] = &T::inst;
yueee_yt 0:fdf9c2c5200f 41 }
yueee_yt 0:fdf9c2c5200f 42
yueee_yt 0:fdf9c2c5200f 43 void ListenThread(void const *args);
yueee_yt 0:fdf9c2c5200f 44 enum HTTP_METH {
yueee_yt 0:fdf9c2c5200f 45 HTTP_GET,
yueee_yt 0:fdf9c2c5200f 46 HTTP_POST,
yueee_yt 0:fdf9c2c5200f 47 HTTP_HEAD
yueee_yt 0:fdf9c2c5200f 48 };
yueee_yt 0:fdf9c2c5200f 49
dkato 11:0700755d64ae 50 bool getRequest(TCPSocket* client, string* path, string* meth)
yueee_yt 0:fdf9c2c5200f 51 {
yueee_yt 0:fdf9c2c5200f 52 char req[128];
yueee_yt 0:fdf9c2c5200f 53 char c_path[128];
yueee_yt 0:fdf9c2c5200f 54 char c_meth[128];
yueee_yt 0:fdf9c2c5200f 55 const int maxLen = 128;
yueee_yt 0:fdf9c2c5200f 56 char* p = req;
yueee_yt 0:fdf9c2c5200f 57 //Read Line
yueee_yt 0:fdf9c2c5200f 58 int ret;
yueee_yt 0:fdf9c2c5200f 59 int len = 0;
yueee_yt 0:fdf9c2c5200f 60 for(int i = 0; i < maxLen - 1; i++) {
dkato 11:0700755d64ae 61 ret = client->recv(p, 1);
yueee_yt 0:fdf9c2c5200f 62 if(!ret) {
yueee_yt 0:fdf9c2c5200f 63 break;
yueee_yt 0:fdf9c2c5200f 64 }
yueee_yt 0:fdf9c2c5200f 65 if( (len > 1) && *(p-1)=='\r' && *p=='\n' ) {
yueee_yt 0:fdf9c2c5200f 66 p--;
yueee_yt 0:fdf9c2c5200f 67 len-=2;
yueee_yt 0:fdf9c2c5200f 68 break;
yueee_yt 0:fdf9c2c5200f 69 } else if( *p=='\n' ) {
yueee_yt 0:fdf9c2c5200f 70 len--;
yueee_yt 0:fdf9c2c5200f 71 break;
yueee_yt 0:fdf9c2c5200f 72 }
yueee_yt 0:fdf9c2c5200f 73 p++;
yueee_yt 0:fdf9c2c5200f 74 len++;
yueee_yt 0:fdf9c2c5200f 75 }
yueee_yt 0:fdf9c2c5200f 76 *p = 0;
yueee_yt 4:1b6b021ee21d 77 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 78 printf("Parsing request : %s\r\n", req);
yueee_yt 4:1b6b021ee21d 79 #endif
yueee_yt 0:fdf9c2c5200f 80 ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path);
yueee_yt 0:fdf9c2c5200f 81 if(ret !=2) return false;
yueee_yt 0:fdf9c2c5200f 82 *meth = string(c_meth);
yueee_yt 0:fdf9c2c5200f 83 *path = string(c_path);
yueee_yt 0:fdf9c2c5200f 84 return true;
yueee_yt 0:fdf9c2c5200f 85 }
yueee_yt 0:fdf9c2c5200f 86
dkato 11:0700755d64ae 87 void dispatchRequest(TCPSocket* client)
yueee_yt 0:fdf9c2c5200f 88 {
yueee_yt 0:fdf9c2c5200f 89 string path;
yueee_yt 0:fdf9c2c5200f 90 string meth;
yueee_yt 0:fdf9c2c5200f 91 HTTP_METH methCode;
yueee_yt 4:1b6b021ee21d 92 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 93 printf("Dispatching req\r\n");
yueee_yt 4:1b6b021ee21d 94 #endif
yueee_yt 0:fdf9c2c5200f 95 if( !getRequest(client,&path, &meth ) ) {
yueee_yt 4:1b6b021ee21d 96 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 97 printf("dispatchRequest Invalid request\r\n");
yueee_yt 4:1b6b021ee21d 98 #endif
yueee_yt 0:fdf9c2c5200f 99 //close();
yueee_yt 0:fdf9c2c5200f 100 return; //Invalid request
yueee_yt 0:fdf9c2c5200f 101 }
yueee_yt 0:fdf9c2c5200f 102 if( !meth.compare("GET") ) {
yueee_yt 4:1b6b021ee21d 103 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 104 printf("dispatchRequest HTTP_GET\r\n");
yueee_yt 4:1b6b021ee21d 105 #endif
yueee_yt 0:fdf9c2c5200f 106 methCode = HTTP_GET;
yueee_yt 0:fdf9c2c5200f 107 } else if( !meth.compare("POST") ) {
yueee_yt 4:1b6b021ee21d 108 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 109 printf("dispatchRequest HTTP_POST\r\n");
yueee_yt 4:1b6b021ee21d 110 #endif
yueee_yt 0:fdf9c2c5200f 111 methCode = HTTP_POST;
yueee_yt 0:fdf9c2c5200f 112 } else if( !meth.compare("HEAD") ) {
yueee_yt 4:1b6b021ee21d 113 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 114 printf("dispatchRequest HTTP_HEAD\r\n");
yueee_yt 4:1b6b021ee21d 115 #endif
yueee_yt 0:fdf9c2c5200f 116 methCode = HTTP_HEAD;
yueee_yt 0:fdf9c2c5200f 117 } else {
yueee_yt 4:1b6b021ee21d 118 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 119 printf("dispatchRequest() Parse error\r\n");
yueee_yt 4:1b6b021ee21d 120 #endif
yueee_yt 0:fdf9c2c5200f 121 //close(); //Parse error
yueee_yt 0:fdf9c2c5200f 122 return;
yueee_yt 0:fdf9c2c5200f 123 }
yueee_yt 4:1b6b021ee21d 124 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 125 printf("Looking for a handler\r\n");
yueee_yt 4:1b6b021ee21d 126 #endif
dkato 11:0700755d64ae 127 map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocket*), handlersComp >::iterator it;
yueee_yt 0:fdf9c2c5200f 128 int root_len = 0;
yueee_yt 0:fdf9c2c5200f 129 for (it = m_lpHandlers.begin(); it != m_lpHandlers.end(); it++) {
yueee_yt 4:1b6b021ee21d 130 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 131 printf("Checking %s...\r\n", (*it).first.c_str());
yueee_yt 4:1b6b021ee21d 132 #endif
yueee_yt 0:fdf9c2c5200f 133 root_len = (*it).first.length();
yueee_yt 0:fdf9c2c5200f 134 if ( root_len &&
yueee_yt 0:fdf9c2c5200f 135 !path.compare( 0, root_len, (*it).first ) &&
yueee_yt 0:fdf9c2c5200f 136 (path[root_len] == '/' || path[root_len] == '\0')) {
yueee_yt 4:1b6b021ee21d 137 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 138 printf("Found (%s)\r\n", (*it).first.c_str());
yueee_yt 4:1b6b021ee21d 139 #endif
yueee_yt 0:fdf9c2c5200f 140 // Found!
yueee_yt 0:fdf9c2c5200f 141 break; // for
yueee_yt 0:fdf9c2c5200f 142 }
yueee_yt 0:fdf9c2c5200f 143 }
yueee_yt 0:fdf9c2c5200f 144 if((it == m_lpHandlers.end()) && !(m_lpHandlers.empty())) {
yueee_yt 4:1b6b021ee21d 145 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 146 printf("Using default handler\r\n");
yueee_yt 4:1b6b021ee21d 147 #endif
yueee_yt 0:fdf9c2c5200f 148 it = m_lpHandlers.end();
yueee_yt 0:fdf9c2c5200f 149 it--; //Get the last element
yueee_yt 0:fdf9c2c5200f 150 if( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler
yueee_yt 0:fdf9c2c5200f 151 it = m_lpHandlers.end();
yueee_yt 0:fdf9c2c5200f 152 root_len = 0;
yueee_yt 0:fdf9c2c5200f 153 }
yueee_yt 0:fdf9c2c5200f 154 if(it == m_lpHandlers.end()) {
yueee_yt 4:1b6b021ee21d 155 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 156 printf("No handler found\r\n");
yueee_yt 4:1b6b021ee21d 157 #endif
yueee_yt 0:fdf9c2c5200f 158 return;
yueee_yt 0:fdf9c2c5200f 159 }
yueee_yt 4:1b6b021ee21d 160 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 161 printf("Handler found.\r\n");
yueee_yt 4:1b6b021ee21d 162 #endif
yueee_yt 0:fdf9c2c5200f 163 HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, client);
yueee_yt 0:fdf9c2c5200f 164 //**** client = NULL; //We don't own it anymore
yueee_yt 0:fdf9c2c5200f 165 switch(methCode) {
yueee_yt 0:fdf9c2c5200f 166 case HTTP_GET:
yueee_yt 0:fdf9c2c5200f 167 pHdlr->doGet();
yueee_yt 0:fdf9c2c5200f 168 break;
yueee_yt 0:fdf9c2c5200f 169 case HTTP_POST:
yueee_yt 0:fdf9c2c5200f 170 pHdlr->doPost();
yueee_yt 0:fdf9c2c5200f 171 break;
yueee_yt 0:fdf9c2c5200f 172 case HTTP_HEAD:
yueee_yt 0:fdf9c2c5200f 173 pHdlr->doHead();
yueee_yt 0:fdf9c2c5200f 174 break;
yueee_yt 0:fdf9c2c5200f 175 }
yueee_yt 0:fdf9c2c5200f 176 delete pHdlr;
yueee_yt 4:1b6b021ee21d 177 // delete client;
dkato 11:0700755d64ae 178 // delete m_pTCPSocket;
yueee_yt 4:1b6b021ee21d 179 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 4:1b6b021ee21d 180 printf("(dispatcherRequest)return\r\n");
yueee_yt 4:1b6b021ee21d 181 #endif
yueee_yt 4:1b6b021ee21d 182 return ;
yueee_yt 0:fdf9c2c5200f 183 }
yueee_yt 0:fdf9c2c5200f 184
yueee_yt 0:fdf9c2c5200f 185 void HTTPServerChild (void const *arg)
yueee_yt 0:fdf9c2c5200f 186 {
yueee_yt 4:1b6b021ee21d 187 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 188 printf("HTTPServerChiled Start......\r\n");
yueee_yt 4:1b6b021ee21d 189 #endif
dkato 11:0700755d64ae 190 TCPSocket* client = (TCPSocket*)arg;
yueee_yt 0:fdf9c2c5200f 191
yueee_yt 0:fdf9c2c5200f 192 for (;;) {
yueee_yt 4:1b6b021ee21d 193 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 194 printf("(HTTPServer.h<HTTPServerChild>)Connection from %s\r\n", client->get_address());
yueee_yt 4:1b6b021ee21d 195 #endif
yueee_yt 0:fdf9c2c5200f 196 dispatchRequest(client);
yueee_yt 4:1b6b021ee21d 197 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 198 printf("(HTTPServer.h<HTTPServerChild>)Close %s\r\n", client->get_address());
yueee_yt 4:1b6b021ee21d 199 #endif
yueee_yt 0:fdf9c2c5200f 200 client->close();
yueee_yt 0:fdf9c2c5200f 201 //delete client;
yueee_yt 0:fdf9c2c5200f 202 Thread::signal_wait(1);
yueee_yt 0:fdf9c2c5200f 203 }
yueee_yt 0:fdf9c2c5200f 204 }
yueee_yt 0:fdf9c2c5200f 205
yueee_yt 0:fdf9c2c5200f 206 void HTTPServerCloser (void const *arg)
yueee_yt 0:fdf9c2c5200f 207 {
dkato 11:0700755d64ae 208 TCPSocket *client = (TCPSocket*)arg;
yueee_yt 0:fdf9c2c5200f 209
yueee_yt 0:fdf9c2c5200f 210 for (;;) {
yueee_yt 0:fdf9c2c5200f 211 client->close();
yueee_yt 4:1b6b021ee21d 212 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 213 printf("Close %s\r\n", client->get_address());
yueee_yt 4:1b6b021ee21d 214 #endif
yueee_yt 0:fdf9c2c5200f 215 Thread::signal_wait(1);
yueee_yt 0:fdf9c2c5200f 216 }
yueee_yt 0:fdf9c2c5200f 217 }
yueee_yt 0:fdf9c2c5200f 218
dkato 11:0700755d64ae 219 void HTTPServerStart(NetworkInterface *net, int port = 80)
yueee_yt 0:fdf9c2c5200f 220 {
yueee_yt 0:fdf9c2c5200f 221 int i, t = 0;
dkato 11:0700755d64ae 222 TCPSocket clients[THREAD_MAX];
dkato 11:0700755d64ae 223 TCPSocket xclient;
yueee_yt 0:fdf9c2c5200f 224
yueee_yt 0:fdf9c2c5200f 225 for (i = 0; i < THREAD_MAX; i ++) {
yueee_yt 0:fdf9c2c5200f 226 threads[i] = NULL;
yueee_yt 0:fdf9c2c5200f 227 }
yueee_yt 0:fdf9c2c5200f 228 xthread = NULL;
yueee_yt 0:fdf9c2c5200f 229
dkato 11:0700755d64ae 230 TCPServer server(net);
yueee_yt 0:fdf9c2c5200f 231 server.bind(port);
yueee_yt 0:fdf9c2c5200f 232 server.listen();
yueee_yt 4:1b6b021ee21d 233 // server.set_blocking(false);
yueee_yt 4:1b6b021ee21d 234 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 235 printf("Wait for new connection...\r\n");
yueee_yt 4:1b6b021ee21d 236 #endif
yueee_yt 0:fdf9c2c5200f 237 for (;;) {
yueee_yt 4:1b6b021ee21d 238 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 239 printf("**Start Loop** \r\n");
yueee_yt 4:1b6b021ee21d 240 #endif
yueee_yt 0:fdf9c2c5200f 241 if (t >= 0) {
dkato 11:0700755d64ae 242 if(server.accept(&clients[t])==0) {
yueee_yt 0:fdf9c2c5200f 243 // fork child process
yueee_yt 0:fdf9c2c5200f 244 if (threads[t]) {
yueee_yt 0:fdf9c2c5200f 245 threads[t]->signal_set(1);
yueee_yt 0:fdf9c2c5200f 246 } else {
dkato 9:d117d5f84994 247 threads[t] = new Thread(HTTPServerChild, (void*)&clients[t], osPriorityNormal, 1024 * 3, NULL);
yueee_yt 0:fdf9c2c5200f 248 }
yueee_yt 4:1b6b021ee21d 249 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 250 printf("Forked %d\r\n", t);
yueee_yt 4:1b6b021ee21d 251 #endif
yueee_yt 0:fdf9c2c5200f 252 }
yueee_yt 0:fdf9c2c5200f 253 } else {
dkato 11:0700755d64ae 254 if(server.accept(&xclient)==0) {
yueee_yt 0:fdf9c2c5200f 255 // closer process
yueee_yt 0:fdf9c2c5200f 256 if (xthread) {
yueee_yt 0:fdf9c2c5200f 257 xthread->signal_set(1);
yueee_yt 0:fdf9c2c5200f 258 } else {
yueee_yt 0:fdf9c2c5200f 259 xthread = new Thread(HTTPServerCloser, (void*)&xclient);
yueee_yt 0:fdf9c2c5200f 260 }
yueee_yt 4:1b6b021ee21d 261 #ifdef _DEBUG_HTTP_SERVER_H
yueee_yt 0:fdf9c2c5200f 262 printf("Connection full\r\n");
yueee_yt 4:1b6b021ee21d 263 #endif
yueee_yt 0:fdf9c2c5200f 264 }
yueee_yt 0:fdf9c2c5200f 265 }
yueee_yt 0:fdf9c2c5200f 266
yueee_yt 0:fdf9c2c5200f 267 t = -1;
yueee_yt 0:fdf9c2c5200f 268 for (i = 0; i < THREAD_MAX; i ++) {
dkato 6:d9e6379eefac 269 if ((threads[i] == NULL)
dkato 11:0700755d64ae 270 || ((threads[i]->get_state() == Thread::WaitingAnd))) {
yueee_yt 0:fdf9c2c5200f 271 if (t < 0) t = i; // next empty thread
yueee_yt 0:fdf9c2c5200f 272 }
yueee_yt 0:fdf9c2c5200f 273 }
yueee_yt 4:1b6b021ee21d 274 // Thread::wait(100);
yueee_yt 0:fdf9c2c5200f 275 }
yueee_yt 0:fdf9c2c5200f 276 }
yueee_yt 0:fdf9c2c5200f 277 #include "Handler/RPCHandler.h"
yueee_yt 0:fdf9c2c5200f 278 #include "Handler/FSHandler.h"
yueee_yt 0:fdf9c2c5200f 279 #include "Handler/SimpleHandler.h"
dkato 6:d9e6379eefac 280 #include "SnapshotHandler.h"
yueee_yt 0:fdf9c2c5200f 281
yueee_yt 0:fdf9c2c5200f 282 #endif