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:
yueee_yt
Date:
Thu Feb 20 05:36:19 2014 +0000
Revision:
0:fdf9c2c5200f
Child:
4:1b6b021ee21d
Initialize version

Who changed what in which revision?

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