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.
Fork of HTTPServer by
Diff: HTTPServer.cpp
- 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