Changed RPC sucessful execution code from 1 to 200. Included RpcHandler.h in main header file. Effectively allows RPC through HTTP.
Dependents: RPC_HTTP RPC_HTTP_WIZnetInterface RPC_HTTP rpc_over_http_TL_interrupter_gatePJ
Fork of HTTPServer by
Revision 13:aa5338a5e452, committed 2013-06-22
- Comitter:
- leihen
- Date:
- Sat Jun 22 15:41:34 2013 +0000
- Parent:
- 12:ba81cc117fb6
- Child:
- 14:011edcd33e86
- Commit message:
- First Version of a working Ethernet HTTP Server.
Changed in this revision
--- a/HTTPConnection.cpp Wed Jun 05 23:39:24 2013 +0000 +++ b/HTTPConnection.cpp Sat Jun 22 15:41:34 2013 +0000 @@ -2,24 +2,14 @@ #include "mbed.h" #include "HTTPConnection.h" - -#define _DEBUG 0 +#define DEBUG +#include "debug.h" #include <vector> using std::vector; using std::string; -#if (_DEBUG && !defined(TARGET_LPC11U24)) -#define INFO(x, ...) std::printf("[HttpConnection : INFO]"x"\r\n", ##__VA_ARGS__); -#define WARN(x, ...) std::printf("[HttpConnection : WARN]"x"\r\n", ##__VA_ARGS__); -#define ERR(x, ...) std::printf("[HttpConnection : ERR]"x"\r\n", ##__VA_ARGS__); -#else -#define INFO(x, ...) -#define WARN(x, ...) -#define ERR(x, ...) -#endif - const struct HTTPRequestConfig { @@ -37,7 +27,7 @@ }; -HTTPConnection::HTTPConnection() +HTTPConnection::HTTPConnection(TCPSocketConnection& clnt) : m_Tcp(clnt) { } @@ -108,8 +98,13 @@ if ((szLine == NULL) || (nMaxLen == 0)) return -1; + szLine[0] = 0; m_Tcp.set_blocking(false); + if (!m_Tcp.is_connected()) { + error("NOT COnnected anymore"); + return -1; + } Timer tm; int i; @@ -129,7 +124,9 @@ // Check if line terminating character was received if (szLine[i] == cLineTerm) + { break; + } } // Terminate with \0 szLine[i] = 0; @@ -139,7 +136,6 @@ i--; szLine[i] = 0; } - INFO("receiveLine : \"%s\".", szLine); // return number of characters received in the line or return -2 if an empty line was received if ((i == 0) || ((i==1) &&(szLine[0] == '\r')))
--- a/HTTPConnection.h Wed Jun 05 23:39:24 2013 +0000 +++ b/HTTPConnection.h Sat Jun 22 15:41:34 2013 +0000 @@ -75,7 +75,7 @@ /** Public constructor for HTTPConnection objects. * */ - HTTPConnection (); + HTTPConnection (TCPSocketConnection& clnt); /** Destructor for HTTPConnection objects. *
--- a/HTTPRequestHandler.cpp Wed Jun 05 23:39:24 2013 +0000 +++ b/HTTPRequestHandler.cpp Sat Jun 22 15:41:34 2013 +0000 @@ -1,30 +1,21 @@ /* HTTPRequestHandler.cpp */ #include "mbed.h" #include "HTTPRequestHandler.h" +#define DEBUG +#include "debug.h" #include <ctype.h> -#define _DEBUG 0 - -#if (_DEBUG && !defined(TARGET_LPC11U24)) -#define INFO(x, ...) std::printf("[HTTPRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__); -#define WARN(x, ...) std::printf("[HTTPRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__); -#define ERR(x, ...) std::printf("[HTTPRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__); -#else -#define INFO(x, ...) -#define WARN(x, ...) -#define ERR(x, ...) -#endif static char buffer[128]; -const char hdrDNT[] = "DNT: 1\r\n"; -const char hdrMaxAge[] = "MaxAge: 0\r\n"; -const char hdrConClose[] = "Connection: Keep-Alive\r\n"; -//const char hdrTrsfrEnc[] = "Transfer-Encoding: Chunked\r\n"; -const char hdrContent[] = "Content-Type: text/html\r\n"; -const char hdrServer[] = "Server: mbed embedded\r\n"; -const char hdrEndl[] = "\r\n"; +const char hdrStandard[] = "DNT: 1\r\n" + "MaxAge: 0\r\n" + "Connection: Keep-Alive\r\n" + "Content-Type: text/html\r\n" + "Server: mbed embedded\r\n" + "Accessible: 1\r\n" + "\r\n"; static int _stricmp(const char* a, const char* b) @@ -54,7 +45,9 @@ {".txt", "Content-Type: plain/text\r\n" }, {".pdf", "Content-Type: application/pdf\r\n" }, {".htm", "Content-Type: text/html\r\n" }, - {".html","Content-Type: text/html\r\n" }}; + {".html","Content-Type: text/html\r\n" }, + {".css", "Content-Type: text/css\r\n" }, + {".js", "Content-Type: text/javascript\r\n"}}; HTTPRequestHandler::HTTPRequestHandler(HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp) : msg(Msg), tcp(Tcp) @@ -119,12 +112,12 @@ } } -static const char* szErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error %d</h1><P>HTTPServer Error<P></BODY></HTML>\r\n\r\n"; +static const char* szErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error</h1><P>HTTPServer Error<P></BODY></HTML>\r\n\r\n"; void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header) { INFO("Handling error !"); - tcp.set_blocking(true, 1500); + tcp.set_blocking(false, 1500); sprintf(buffer,"HTTP/1.1 %d Error\r\n", errorCode); tcp.send(buffer, strlen(buffer)); sprintf(buffer, "Content-Length: %d\r\n", strlen(szErrorPage)); @@ -149,29 +142,25 @@ void HTTPRequestHandler::startResponse(int returnCode, long nLen, HTTPHeaders* header) { INFO("Starting response (%ld bytes in total)!", nLen); - tcp.set_blocking(true, 1500); + tcp.set_blocking(false, 1500); sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode); - tcp.send_all(buffer, strlen(buffer)); - tcp.send_all((char*)hdrConClose, strlen(hdrConClose)); + tcp.send(buffer, strlen(buffer)); sprintf(buffer, "Content-Length: %ld\r\n", nLen); // Add 2 chars for the terminating CR+LF - tcp.send_all(buffer, strlen(buffer)); + tcp.send(buffer, strlen(buffer)); + INFO("Sending standard headers !"); if (header == NULL) { - tcp.send_all((char*)hdrDNT, strlen(hdrDNT)); - tcp.send_all((char*)hdrMaxAge, strlen(hdrMaxAge)); - tcp.send_all((char*)hdrContent, strlen(hdrContent)); -// tcp.send_all((char*)hdrTrsfrEnc, strlen(hdrTrsfrEnc)); - tcp.send_all((char*)hdrServer, strlen(hdrServer)); - tcp.send_all((char*)hdrEndl, strlen(hdrEndl)); + tcp.send_all((char*)hdrStandard, strlen(hdrStandard)); } else { for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) { - tcp.send((char*)cIter->first, strlen(cIter->first)); - tcp.send(": ", 2); - tcp.send((char*)cIter->second, strlen(cIter->second)); - tcp.send("\r\n\r\n",2); + tcp.send_all((char*)cIter->first, strlen(cIter->first)); + tcp.send_all(": ", 2); + tcp.send_all((char*)cIter->second, strlen(cIter->second)); + tcp.send_all("\r\n\r\n",2); } tcp.send_all("\r\n", 2); } + INFO("Proceeding !"); // other content must be sent using the 'processResponse' function } @@ -184,5 +173,4 @@ void HTTPRequestHandler::endResponse() { INFO("Ending Response !"); -// tcp.send("\r\n\r\n", 4); }
--- a/HTTPServer.cpp Wed Jun 05 23:39:24 2013 +0000 +++ b/HTTPServer.cpp Sat Jun 22 15:41:34 2013 +0000 @@ -1,7 +1,9 @@ #include "mbed.h" #include "HTTPServer.h" +#define DEBUG +#include "debug.h" -#define _DEBUG 0 +#define _DEBUG 1 #ifdef _DEBUG DigitalOut led1(LED1); @@ -10,32 +12,17 @@ DigitalOut led4(LED4); #endif -#if (_DEBUG && !defined(TARGET_LPC11U24)) -#define INFO(x, ...) std::printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__); -#define WARN(x, ...) std::printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__); -#define ERR(x, ...) std::printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__); -#else -#define INFO(x, ...) -#define WARN(x, ...) -#define ERR(x, ...) -#endif - +static EthernetInterface eth; /* Constructor */ /* initialize all members and set the standard error handler. */ -HTTPServer::HTTPServer(PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec) - : m_wifly(tx, rx, reset, tcp_status, ssid, phrase, sec) +HTTPServer::HTTPServer() { m_pErrorHandler = StdErrorHandler; - m_pSvr = NULL; } HTTPServer::~HTTPServer() { - if (m_pSvr) { - delete m_pSvr; - m_pSvr = NULL; - } } @@ -51,93 +38,47 @@ } -int HTTPServer::start(int port) +bool 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; - } - INFO("Initializing wifly\n"); - // Initialize the wifly wlan device - m_wifly.init(); + INFO("Initializing network\n"); + eth.init(); INFO("Connecting to network..."); - // Try join the network - while(!m_wifly.connect()) { - INFO("Failed to connect. Trying again\n"); - m_wifly.reset(); - } - INFO("connected\n"); + eth.connect(); - // 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; - } - - // 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"); + INFO("Binding to port %d...", port); + if (m_Svr.bind(port) < 0) { + ERR("Failed to bind to port !\n"); + error("Binding"); + return false; } - // 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"); + INFO("Listening ..."); + if (m_Svr.listen(1) < 0) { + ERR("Failed to listen !\n"); + error("Listening"); + return false; } + ERR("Connected !"); // set into non blocking operation - m_pSvr->set_blocking(false, 100); - - return 0; + m_Svr.set_blocking(false, 100); + + return true; } int HTTPServer::poll(bool blocking) -{ +{ int retval = -1; - INFO("Listening for new connection requests."); +#ifdef _DEBUG + led4 = 1; // Indicate we are waiting for a new connection +#endif // 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; - -#ifdef _DEBUG - led4 = 1; // Indicate we are waiting for a new connection -#endif - m_pSvr->set_blocking(blocking); - retval = m_pSvr->accept(Clnt); - if (retval > 0) { - // no connection availale yet, so just return -#ifdef _DEBUG -led4 = 0; -led3 = 0; -led2 = 0; -#endif - return retval; - } - if ( retval < 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; -#endif - m_pSvr->close(); - delete m_pSvr; - m_pSvr = NULL; + if (m_Svr.accept(Clnt) < 0) { #ifdef _DEBUG led4 = 0; led3 = 1; // ERROR @@ -146,40 +87,35 @@ #endif return -1; } - else { + + // a new connection was received + INFO("Client (IP=%s) is connected !\n", Clnt.get_address()); +#ifdef _DEBUG + led4 = 0; + led3 = 0; + led2 = 0; +#endif + #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 -// while(1) { - - #ifdef _DEBUG - led3 = 1; - led2 = 1; - #endif - HTTPConnection con; - int c = con.poll(); - if (c == 0) { - // Handle the request - HandleRequest(con.m_Msg, Clnt); -// INFO("Closing connection.\n"); -// if (!m_wifly.close()) { -// ERR("Failed to close connection !\n"); -// } - } - if (c == -1) { - // No more data available or error - // break; - } - #ifdef _DEBUG - led2 = 0; - led3 = 0; - #endif -// } + led3 = 1; + led2 = 1; +#endif + 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; + } +#ifdef _DEBUG + led2 = 0; + led3 = 0; +#endif + + INFO("Leaving polling thread"); return 0; } @@ -200,14 +136,13 @@ break; } } - + if (it == m_lpHandlers.end()) { // There is no such handler, so return invalid - m_pErrorHandler(msg, tcp); + m_pErrorHandler(msg, tcp); INFO("Webrequest left unhandled."); - } - else { + } else { // Valid handler was found INFO("Routing webrequest !"); // Instantiate the handler object (handling will be done from withing the object's constructor
--- a/HTTPServer.h Wed Jun 05 23:39:24 2013 +0000 +++ b/HTTPServer.h Sat Jun 22 15:41:34 2013 +0000 @@ -23,7 +23,7 @@ #ifndef __HTTPSERVER_H__ #define __HTTPSERVER_H__ #include "mbed.h" -#include "WiflyInterface.h" +#include "EthernetInterface.h" #include "HTTPConnection.h" #include "HTTPRequestHandler.h" @@ -76,14 +76,13 @@ class HTTPServer { - TCPSocketServer* m_pSvr; + TCPSocketServer m_Svr; bool m_bServerListening; - WiflyInterface m_wifly; public: /** Constructor for HTTPServer objects. */ - HTTPServer(PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec); + HTTPServer(); /** Destructor for HTTPServer objects. */ @@ -130,7 +129,7 @@ * @param port : port on which to listen for incoming connections * @returns : -1 if an unrecoverable error occured, or 0 if everything was ok. */ - int start(int port = 80); + bool start(int port = 80); /** 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. @@ -139,10 +138,7 @@ * ready for processing the next request. Simply call \c poll as long as you want to serve new incoming requests. */ int poll(bool blocking = true); - - string getTime() - { return m_wifly.getTime(false); } - + private: /** The standard error handler function. * @param msg : Request message data.
--- a/Handler/FsHandler.cpp Wed Jun 05 23:39:24 2013 +0000 +++ b/Handler/FsHandler.cpp Sat Jun 22 15:41:34 2013 +0000 @@ -1,19 +1,8 @@ /* FsHandler.cpp */ #include "mbed.h" #include "FsHandler.h" - - -#define _DEBUG 0 - -#if (_DEBUG && !defined(TARGET_LPC11U24)) -#define INFO(x, ...) std::printf("[HTTPFsRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__); -#define WARN(x, ...) std::printf("[HTTPFsRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__); -#define ERR(x, ...) std::printf("[HTTPFsRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__); -#else -#define INFO(x, ...) -#define WARN(x, ...) -#define ERR(x, ...) -#endif +#define DEBUG +#include "debug.h"