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
HTTPServer.cpp
- Committer:
- leihen
- Date:
- 2013-05-26
- Revision:
- 1:6b7472d5e9ee
- Parent:
- 0:7a2421e63e74
- Child:
- 2:8653bbcf7e58
File content as of revision 1:6b7472d5e9ee:
#include "mbed.h" #include "HTTPServer.h" DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); #if (0 && !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__); #else #define INFO(x, ...) #define WARN(x, ...) #define ERR(x, ...) #endif static const char* szMsgs = "No such file or folder."; HTTPServer::HTTPServer(Serial* pDbg) { m_pDbg = pDbg; m_pSvr = NULL; m_bServerListening = false; } HTTPServer::~HTTPServer() { if (m_pSvr) { delete m_pSvr; m_pSvr = NULL; m_bServerListening = false; } } int HTTPServer::start(int port) { // check if the start member was called already once if (m_pSvr != NULL) { 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(); // Bind the local server to the given port if (m_pSvr->bind(port) < 0) { ERR("Failed to bind to port %d\n", port); return -1; } else { INFO("Binding succeeded !\n"); } // Listen to a maximum of 10 concurrent connections if (m_pSvr->listen(1) < 0) { ERR("Faild to listen !\n"); delete m_pSvr; m_pSvr = NULL; return -1; } else { INFO("Listening\n"); m_bServerListening = true; } // set into non blocking operation m_pSvr->set_blocking(false, 100); return 0; } int HTTPServer::poll() { INFO("Listening for new connection requests."); // This thread basically checks if there is a new incoming connection. // If so , a new HTTPConnection is created and the connection thread is started. TCPSocketConnection Clnt; led4 = 1; // Indicate we are waiting for a new connection 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"); led2 = 0; m_bServerListening = false; m_pSvr->close(); delete m_pSvr; m_pSvr = NULL; led4 = 0; led3 = 1; // ERROR led2 = 0; led1 = 0; return -1; } else { led4 = 0; // a new connection was received INFO("Client (IP=%s) is connected !\n", Clnt.get_address()); // Start the main connection thread led3 = 1; led2 = 1; HTTPConnection con; int c = con.poll(); if (c == 0) { // Handle the request HandleRequest(con.m_Msg, Clnt); } led2 = 0; led3 = 0; } INFO("Leaving polling thread"); return 0; } void HTTPServer::HandleRequest(HTTPMessage& msg, TCPSocketConnection& tcp) { static char echoHeader[256] = {}; static const char* szPage = { "<HTML>\r\n" "<HEAD>\r\n" "<META content=\"text/html\" http-equiv=Content-Type>\r\n" "</HEAD>\r\n" "<BODY>\r\n" "<h1>ERROR 404</h1>\r\n" "<P>File not found<P>\r\n" "</BODY>\r\n" "</HTML>\r\n\r\n"}; map<string, HTTPRequestHandlerFunction>::iterator it; it = m_pHandlers.find(msg.uri); if (it == m_pHandlers.end()) { // There is no such handler, so return invalid 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\nConnection: Close\r\n\r\n",strlen(szPage)); tcp.send(echoHeader,strlen(echoHeader)); tcp.send((char*)szPage,strlen(szMsgs)); INFO("Webrequest left unhandled."); } else { // Handler was found so pass action to handler INFO("Routing webrequest !"); (it->second)(msg, tcp); } }