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
Revision 17:d7186c696729, committed 2014-05-15
- Comitter:
- cabledev
- Date:
- Thu May 15 16:09:51 2014 +0000
- Parent:
- 16:cc3f5c53d0d5
- Commit message:
- - converted to blocking mode & removed polling; greatly improving stability, but HTTP server must be started from a separate thread (not the main app thread); - moved ethernet interface and port assignment out of start() method; - updated log messages
Changed in this revision
--- a/HTTPConnection.cpp Sat Aug 17 16:17:55 2013 +0000 +++ b/HTTPConnection.cpp Thu May 15 16:09:51 2014 +0000 @@ -62,7 +62,7 @@ rcvd = parse(buffer); if (rcvd == -1) { // Invalid content received, so close the connection - INFO("Invalid message received, so sending negative response and closing connection !"); + INFO("Invalid message received, so sending negative response and closing connection!"); sprintf(buffer,"HTTP/1.1 400 BadRequest\n\rContent-Length: %d\n\rContent-Type: text\n\r\n\r\n\r",0); m_Tcp.set_blocking(true, 1500); m_Tcp.send(buffer,strlen(buffer)); @@ -85,7 +85,7 @@ if (parseHeader(buffer) == 0) { } else { - WARN("Invalid message header received !"); + WARN("Invalid message header received!"); } } } @@ -102,7 +102,7 @@ m_Tcp.set_blocking(false); if (!m_Tcp.is_connected()) { - error("NOT COnnected anymore"); + error("NOT connected anymore"); return -1; } Timer tm; @@ -233,7 +233,7 @@ if (buffer[i] == '?') { // starts with a question mark, so got it buffer[i] = 0; args_start = i; // set the start of the args section - INFO("Argument section found !"); + INFO("Argument section found!"); } } else { // search arg-value touples
--- a/HTTPRequestHandler.cpp Sat Aug 17 16:17:55 2013 +0000 +++ b/HTTPRequestHandler.cpp Thu May 15 16:09:51 2014 +0000 @@ -116,7 +116,7 @@ void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header) { - INFO("Handling error !"); + INFO("Handling error!"); tcp.set_blocking(false, 1500); sprintf(buffer,"HTTP/1.1 %d Error\r\n", errorCode); tcp.send(buffer, strlen(buffer)); @@ -147,7 +147,7 @@ tcp.send(buffer, strlen(buffer)); sprintf(buffer, "Content-Length: %ld\r\n", nLen); // Add 2 chars for the terminating CR+LF tcp.send(buffer, strlen(buffer)); - INFO("Sending standard headers !"); + INFO("Sending standard headers!"); if (header == NULL) { tcp.send_all((char*)hdrStandard, strlen(hdrStandard)); } @@ -160,7 +160,7 @@ } tcp.send_all("\r\n", 2); } - INFO("Proceeding !"); + INFO("Proceeding!"); // other content must be sent using the 'processResponse' function } @@ -172,5 +172,5 @@ void HTTPRequestHandler::endResponse() { - INFO("Ending Response !"); + INFO("Ending Response!"); }
--- a/HTTPServer.cpp Sat Aug 17 16:17:55 2013 +0000 +++ b/HTTPServer.cpp Thu May 15 16:09:51 2014 +0000 @@ -8,7 +8,7 @@ /* Constructor */ /* initialize all members and set the standard error handler. */ HTTPServer::HTTPServer() - : m_pEthernet(NULL) + : m_port(80), m_pEthernet(NULL) { m_pErrorHandler = StdErrorHandler; } @@ -32,91 +32,104 @@ tcp.send((char*)szStdErrorPage, strlen(szStdErrorPage)); } +void HTTPServer::setPort(int port) +{ + m_port = port; +} -bool HTTPServer::start(int port, EthernetInterface* pEthernet) +void HTTPServer::setEthernetInterface(EthernetInterface* pEthernet) +{ + m_pEthernet = pEthernet; +} + +void HTTPServer::start() { // If no ethernet interface is provided, instantiate own on the heap. This has to be deleted later in the destructor. // If a valid pointer to an thernet interface is proveded, we can simply use it. - if (pEthernet == NULL) { + if (m_pEthernet == NULL) { INFO("Creating EthernetInterface object\n"); m_pEthernet = new EthernetInterface(); if (m_pEthernet == NULL) { ERR("Out of memory, unable to instantiate an EthernetInterface object."); - return false; + //return false; } // Initiaize the network INFO("Initializing network\n"); if (m_pEthernet->init() != 0) { - ERR("Failed to initialize the ethernet interface !"); + ERR("Failed to initialize the ethernet interface!"); delete m_pEthernet; m_pEthernet = NULL; - return false; + //return false; } // Connect to the network using DHCP INFO("Connecting to the network using DHCP..."); if (m_pEthernet->connect() != 0) { - ERR("Failed to connect to the ethernet !"); + ERR("Failed to connect to the ethernet!"); delete m_pEthernet; m_pEthernet = NULL; - return false; + //return false; } INFO("Connected IP %s", m_pEthernet->getIPAddress()); } else { // In the case that the ethernet interface is provided, it is assumed that a connection has already been created. - INFO("Using connection IP %s", pEthernet->getIPAddress()); + INFO("Using connection IP %s", m_pEthernet->getIPAddress()); } - INFO("Binding to port %d...", port); - if (m_Svr.bind(port) < 0) { - ERR("Failed to bind to port !\n"); + INFO("Binding to port %d...", m_port); + if (m_Svr.bind(m_port) < 0) { + ERR("Failed to bind to port!\n"); error("Binding"); - return false; + //return false; } - + INFO("Listening ..."); if (m_Svr.listen(1) < 0) { - ERR("Failed to listen !\n"); + ERR("Failed to listen!\n"); error("Listening"); - return false; + //return false; } + + m_Svr.set_blocking(true); - INFO("Connected !"); - // set into non blocking operation - m_Svr.set_blocking(false, 100); - - return true; -} - + INFO("Connected!"); + + //osThreadSetPriority( Thread::gettid() , osPriorityBelowNormal ); + + while (1) + { +// INFO("Entering polling thread"); -int HTTPServer::poll(bool blocking) -{ - // 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; - if (m_Svr.accept(Clnt) < 0) { - return -1; - } + // 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; + if (m_Svr.accept(Clnt) < 0) { +// INFO("Failure accepting client connection."); +// return -1; + } - // a new connection was received - INFO("Client (IP=%s) is connected !\n", Clnt.get_address()); - HTTPConnection con(Clnt); - int c = con.poll(); - if (c == 0) { - // Handle the request - INFO("Handling request !"); - HandleRequest(con.m_Msg, Clnt); + // a new connection was received + INFO("Client (IP=%s) is connected!\n", Clnt.get_address()); + HTTPConnection con(Clnt); + int c = con.poll(); + if (c == 0) { + // Handle the request + INFO("Handling request!"); + HandleRequest(con.m_Msg, Clnt); + } + if (c == -1) { +// break; + } + + INFO("Leaving polling thread"); +// return 0; } - if (c == -1) { -// break; - } - - INFO("Leaving polling thread"); - return 0; + + //return true; } void HTTPServer::HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp) @@ -143,7 +156,7 @@ INFO("Webrequest left unhandled."); } else { // Valid handler was found - INFO("Routing webrequest !"); + 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.
--- a/HTTPServer.h Sat Aug 17 16:17:55 2013 +0000 +++ b/HTTPServer.h Thu May 15 16:09:51 2014 +0000 @@ -91,12 +91,12 @@ * HTTPServer svr; * // Initialize the ethernet interface * if (eth.init() != 0) { -* printf("Initialization of EthernetInterface failed !"); +* printf("Initialization of EthernetInterface failed!"); * exit(0); * } * // Connect using DHCP * if (eth.connect() !=0) { -* printf("Failed to connect using DHCP !"); +* printf("Failed to connect using DHCP!"); * exit(0); * } * @@ -118,8 +118,9 @@ { TCPSocketServer m_Svr; bool m_bServerListening; + int m_port; EthernetInterface* m_pEthernet; - + public: /** Constructor for HTTPServer objects. */ @@ -163,24 +164,22 @@ * @param hdlFunc: User specified handler function which will be used in error conditions. */ void addErrorHandler(HTTPRequestHandlerFunction hdlFunc) - { m_pErrorHandler = hdlFunc!=NULL ?hdlFunc : StdErrorHandler; } + { m_pErrorHandler = hdlFunc!=NULL ?hdlFunc : StdErrorHandler; } - /** Binds server to a specific port and starts listening. This member prepares the internal variables and the server socket - * and terminates after successfull initialization + /** Sets the port on which the HTTP server will listen * @param port : port on which to listen for incoming connections + */ + void setPort(int port = 80); + + /** Sets the port on which the HTTP server will listen * @param pEthernet : a pointer to an existing EthernetInterface object or NULL if the HTTPServer shall allocate the object. _Please note that for compatibility reasons * your should consider to create the EthernetInterface as a static variable. Otherwise the the object will be created on the heap._ - * @returns : false if an unrecoverable error occured or if the ethernet interface was not set or not initialized correctly, or true if everything was ok. */ - bool start(int port = 80, EthernetInterface* pEthernet = NULL); + void setEthernetInterface(EthernetInterface* pEthernet = NULL); - /** Performs the regular polling of the server component. Needs to be called cyclically. - * The function will internally check whether new connections are requested by a client and will also poll all existing client connections. - * @param blocking : if true, - * @returns -1 if there was a problem. If 0 is returned, the latest request was served successfully and the server is - * ready for processing the next request. Simply call \c poll as long as you want to serve new incoming requests. + /** Starts listening for incoming connections. This method blocks and should be invoked on a separate thread. */ - int poll(bool blocking = true); + void start(); private:
--- a/Handler/FsHandler.cpp Sat Aug 17 16:17:55 2013 +0000 +++ b/Handler/FsHandler.cpp Thu May 15 16:09:51 2014 +0000 @@ -109,7 +109,7 @@ } else { retval = 404; - ERR("Requested file was not found !"); + ERR("Requested file was not found!"); } return retval;
--- a/Handler/RpcHandler.cpp Sat Aug 17 16:17:55 2013 +0000 +++ b/Handler/RpcHandler.cpp Thu May 15 16:09:51 2014 +0000 @@ -32,7 +32,7 @@ int err = 404; string rpc_args(""); - INFO("Handling RPC Get Requesst."); + INFO("Handling RPC Get Request."); // This version of the RPC handler does only accept native RPC commands in the format // /<class>/<method> <argument1> [<argument2> [<argument3> ...]] // So we can simply pass our local pathg to our rpc