Single instance HTTP Server using new Ethernet Interface. Blocking mode only; this improved stability, but the HTTP server must be started from a separate thread.

Dependents:   SmartLight

Fork of HTTPServer by Henry Leinen

Revision:
4:d065642c32cc
Parent:
3:d6224049b3bf
Child:
5:dc88012caef1
--- a/HTTPServer.cpp	Tue May 28 01:56:14 2013 +0000
+++ b/HTTPServer.cpp	Tue May 28 21:20:58 2013 +0000
@@ -1,12 +1,16 @@
 #include "mbed.h"
 #include "HTTPServer.h"
 
+#define _DEBUG      1
+
+#ifdef _DEBUG
 DigitalOut led1(LED1);
 DigitalOut led2(LED2);
 DigitalOut led3(LED3);
 DigitalOut led4(LED4);
+#endif
 
-#if (1 && !defined(TARGET_LPC11U24))
+#if (_DEBUG && !defined(TARGET_LPC11U24))
 #define INFO(x, ...) if (m_pDbg) m_pDbg->printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__); else printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__);
 #define WARN(x, ...) if (m_pDbg) m_pDbg->printf("[HttpServer : WARN]"x"\r\n", ##__VA_ARGS__); else printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__);
 #define ERR(x, ...) if (m_pDbg) m_pDbg->printf("[HttpServer : ERR]"x"\r\n", ##__VA_ARGS__); else printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__);
@@ -16,11 +20,13 @@
 #define ERR(x, ...)
 #endif
 
+
+/* Constructor */
+/* initialize all members and set the standard error handler. */
 HTTPServer::HTTPServer(Serial *dbg)
 {
     m_pDbg = dbg;
     m_pSvr = NULL;
-    m_bServerListening = false;
     m_pErrorHandler = StdErrorHandler;
 }
 
@@ -29,17 +35,15 @@
     if (m_pSvr) {
         delete m_pSvr;
         m_pSvr = NULL;
-        m_bServerListening = false;
     }
 }
 
 
-const char* szStdErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error 404</h1><P>This resource is not available<P></BODY></HTML>\r\n\r\n";
+static const char* szStdErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error 404</h1><P>This resource is not available<P></BODY></HTML>\r\n\r\n";
 
 void HTTPServer::StdErrorHandler(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp)
 {
-    char echoHeader[512];
-    
+    char echoHeader[256];
     tcp.set_blocking(true, 1500);
     sprintf(echoHeader,"HTTP/1.1 404 Fail\r\nContent-Length: %d\r\nContent-Type: text/html\r\nServer: mbed embedded\r\n\n\r",strlen(szStdErrorPage));
     tcp.send(echoHeader, strlen(echoHeader));
@@ -54,8 +58,6 @@
         ERR("start function was already called, server is already in listening state.");
         return -1;
     }
-
-    m_bServerListening = false;
     
     //  Create a new server object
     m_pSvr = new TCPSocketServer();
@@ -78,7 +80,6 @@
     }
     else {
         INFO("Listening\n");
-        m_bServerListening = true;
     }
 
     //  set into non blocking operation
@@ -96,36 +97,47 @@
     //  If so , a new HTTPConnection is created and the connection thread is started.
     TCPSocketConnection Clnt;
 
+#ifdef _DEBUG
     led4 = 1;   //  Indicate we are waiting for a new connection 
+#endif 
     if (m_pSvr->accept(Clnt) < 0) {
         //  an error occured 
         ERR("There was an error, Accept returned with an error. Probably the connection to the router was lost. Shutting down server");
+#ifdef _DEBUG
         led2 = 0;
-        m_bServerListening = false;
+#endif 
         m_pSvr->close();
         delete m_pSvr;
         m_pSvr = NULL;
+#ifdef _DEBUG
         led4 = 0;
         led3 = 1;   //  ERROR
         led2 = 0;
         led1 = 0;
+#endif
         return -1;
     }
     else {
+#ifdef _DEBUG
         led4 = 0;
+#endif 
         //   a new connection was received
         INFO("Client (IP=%s) is connected !\n", Clnt.get_address());
         //  Start the main connection thread
+#ifdef _DEBUG
         led3 = 1;
         led2 = 1;
+#endif
         HTTPConnection con;
         int c = con.poll();
         if (c == 0) {
             //  Handle the request
             HandleRequest(con.m_Msg, Clnt);
         }
+#ifdef _DEBUG
         led2 = 0;
         led3 = 0;
+#endif
     }
     
     INFO("Leaving polling thread");
@@ -137,12 +149,13 @@
     std::string localPath;
     std::map<std::string, HTTPRequestHandler*(*)(const char*, const char*, HTTPConnection::HTTPMessage&, TCPSocketConnection&), handlersComp>::const_iterator it;
 
+    //  Iterate through registered handlers and check if the handler's path is a subset of the requested uri.
     for (it = m_lpHandlers.begin() ; it != m_lpHandlers.end() ; it++) {
         //  check if this entries' path is fully contained at the beginning of the requested path
         std::string curpth = it->first;
 
         if (msg.uri.find(curpth) == 0) {
-            // handler found
+            // firts matching handler found, we just take it and we'll be happy
             localPath = msg.uri.substr(curpth.length());
             break;
         }
@@ -155,31 +168,12 @@
         INFO("Webrequest left unhandled.");
     }
     else {
+        //  Valid handler was found
         INFO("Routing webrequest !");
-
+        //  Instantiate the handler object (handling will be done from withing the object's constructor
         HTTPRequestHandler *phdl = (*it->second)(it->first.c_str(), localPath.c_str(), msg, tcp);
+        //  now we can delete the object, because handling is completed.
         if (phdl != NULL)
             delete phdl;
     }
-    
 }
-/*
-void HTTPServer::HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp)
-{
-    map<string, HTTPRequestHandlerFunction>::iterator it;
-    
-    it = m_pHandlers.find(msg.uri);
-    
-    if (it == m_pHandlers.end()) {
-        //  There is no such handler, so return invalid
-
-        m_pErrorHandler(msg, tcp);        
-        INFO("Webrequest left unhandled.");
-    }
-    else {
-        //  Handler was found so pass action to handler
-        INFO("Routing webrequest !");
-        (it->second)(msg, tcp);
-    }
-}
-*/
\ No newline at end of file