HTTPServer

Files at this revision

API Documentation at this revision

Comitter:
jphuc96
Date:
Sat Sep 16 02:39:55 2017 +0000
Commit message:
v1

Changed in this revision

HTTPConnection.cpp Show annotated file Show diff for this revision Revisions of this file
HTTPConnection.h Show annotated file Show diff for this revision Revisions of this file
HTTPRequestHandler.cpp Show annotated file Show diff for this revision Revisions of this file
HTTPRequestHandler.h Show annotated file Show diff for this revision Revisions of this file
HTTPServer.cpp Show annotated file Show diff for this revision Revisions of this file
HTTPServer.h Show annotated file Show diff for this revision Revisions of this file
Handler/FsHandler.cpp Show annotated file Show diff for this revision Revisions of this file
Handler/FsHandler.h Show annotated file Show diff for this revision Revisions of this file
Handler/RpcHandler.cpp Show annotated file Show diff for this revision Revisions of this file
Handler/RpcHandler.h Show annotated file Show diff for this revision Revisions of this file
hl_debug.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r caf5feddac47 HTTPConnection.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPConnection.cpp	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,264 @@
+/* HTTPConnection.cpp */
+
+#include "mbed.h"
+#include "HTTPConnection.h"
+#define DEBUG
+#include "hl_debug.h"
+
+#include <vector>
+using std::vector;
+
+using std::string;
+
+
+
+const struct HTTPRequestConfig {
+    const char* request_string;
+    HTTPRequestType request_type;
+} g_requestConfig[] = {
+    { "GET",    HTTP_RT_GET },
+    { "POST",   HTTP_RT_POST},
+    { "PUT",    HTTP_RT_PUT},
+    { "OPTIONS",HTTP_RT_OPTIONS},
+    { "HEAD",   HTTP_RT_HEAD},
+    { "DELETE", HTTP_RT_DELETE},
+    { "TRACE",  HTTP_RT_TRACE},
+    { "CONNECT",HTTP_RT_CONNECT}
+};
+
+
+HTTPConnection::HTTPConnection(TCPSocketConnection& clnt) : m_Tcp(clnt)
+{
+}
+
+
+HTTPConnection::~HTTPConnection()
+{
+    close();
+}
+
+void HTTPConnection::close()
+{
+    m_Msg.headers.clear();
+}
+
+int HTTPConnection::poll()
+{
+    static char buffer[256] = {};
+
+    
+    int rcvd= 0;
+    INFO("Waiting for new data in connection");
+    //  Try receiving request line
+    rcvd = receiveLine(buffer, 255, 3000); 
+    if (rcvd == -1) {
+        //  there was an error, probably the connection was closed, so close this connection as well
+        INFO("No more data available. Will close this connection now.");
+        close();
+        return -1;
+    }
+
+    //  The Request has not yet been received so try it
+    rcvd = parse(buffer);
+    if (rcvd == -1) {
+        //  Invalid content received, so close the 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));
+        close();
+        rcvd = -1;
+        return -1;
+    }
+    //  The request has been received, try receive the body
+    while(rcvd > 0) {
+        rcvd = receiveLine((char*)buffer, 255, 3000); 
+        //  First check if we received an empty line. This would indicate the end of the message or message body.
+        if (rcvd < 0) {
+            //  there was an empty line, so we can start with performing the request
+            INFO("Request Header was received completely. Performing request.");
+            rcvd = 0;
+            break;
+        }
+        else {
+            //  add message body
+            if (parseHeader(buffer) == 0) {
+            }
+            else {
+                WARN("Invalid message header received !");
+            }
+        }
+    }             
+    INFO("Leaving poll function!");
+    return rcvd;
+}
+
+int HTTPConnection::receiveLine(char* szLine, int nMaxLen, int nTimeout, char cLineTerm)
+{
+    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;
+    
+    //  Try to receive up to the max number of characters
+    for (i = 0 ; i < nMaxLen-1 ; i++) {
+        int c;
+        c = m_Tcp.receive( szLine + i, 1 );
+        //  Check that - if no character was currently received - the timeout period is reached.
+        if ((c == 0) || (c==-1)) {
+            //  no character was read, so check if operation timed out
+            if (tm.read_ms() > nTimeout) {
+                //  Operation timed out
+                INFO("Timeout occured in function 'receiveLine'.");
+                return -1;
+            }
+        }
+        
+        //  Check if line terminating character was received
+        if (szLine[i] == cLineTerm)
+        {   
+            break;
+        }
+    }
+    //  Terminate with \0
+    szLine[i] = 0;
+
+    //  Trim for '\r' linefeed at the end
+    if( (i >0) && (szLine[i-1] == '\r')) {
+        i--;
+        szLine[i] = 0;
+    }
+    
+    //  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')))
+    {
+        //  empty line received, so return -2
+        return -2;
+    }
+    return i;    
+}
+
+int HTTPConnection::parse(char* buffer)
+{
+    //  Check if buffer is invalid or its content not long enough.
+    if ((buffer == NULL) || (strlen(buffer) < 4)) {
+        ERR("Buffer content is invalid or too short.");
+        return -1;
+    }
+    
+    std::vector<std::string> args;
+    args.clear();
+    
+    int argno = 0;
+    //  decompose string into a list of arguments
+    char s = 0; // current starting char
+    int nLen = strlen(buffer)+1;
+    for (int i = 0 ; i < nLen ; i++) {
+        if ((buffer[i] == ' ') || (buffer[i] == '\n') || (buffer[i] == 0)) {
+            // new arg found
+            buffer[i] = 0;
+            if (argno++ == 1) {
+                //  its the uri
+                // parse the uri args
+                parseUriArgs(&buffer[s], m_Msg.args);
+            }
+            INFO("Found argument \"%s\"", &buffer[s]);
+            args.push_back(&buffer[s]);
+            s = i+1;
+        }
+    }
+    
+    // store the uri and the HTTP version
+    m_Msg.uri = args[1];
+    m_Msg.version = args[2];    
+    
+    //  Find matching request type
+    for (int i = 0 ; i < sizeof(g_requestConfig)/sizeof(struct HTTPRequestConfig) ; i++) {
+        if (args.at(0) == g_requestConfig[i].request_string) {
+            m_Msg.request = g_requestConfig[i].request_type;
+        }
+    }
+    args.clear();
+    
+    return 1;
+}
+
+
+int HTTPConnection::parseHeader(char *buffer)
+{
+    //  Check if the buffer is invalid or if the content is too short to be meaningful
+    if ((strlen(buffer) <3) || (buffer == NULL))
+        return -1;
+        
+    //  decompose string into a touple of <field name> : <field value>
+    int value_start = 0;
+    int buflen = strlen(buffer)+1;
+    for (int i = 0 ; i < buflen ; i++) {
+        if (buffer[i] == ':') {
+            //  touple found
+            buffer[i] = 0;
+            value_start = i+1;    
+            m_Msg.headers[buffer] = &buffer[value_start];
+            
+            INFO("Header name=\"%s\" : value=\"%s\".", buffer, &buffer[value_start]);            
+            return 0;
+        }
+    }
+    
+    ERR("Did not recieve a valid header : \"%s\".", buffer);
+    return -1;
+}
+
+int HTTPConnection::parseUriArgs(char *buffer, map<string,string>&args)
+{
+    // Check if the buffer is invalid or if the content is too short to be meaningful
+    if ((strlen(buffer) <3) || (buffer == NULL))
+        return -1;
+        
+    int args_start = -1;
+    int value_start = -1;
+    int buflen = strlen(buffer) +1;
+    const char* argname = NULL;
+    const char* valuename = NULL;
+    for (int i = 0; i < buflen ; i++) {
+        if (args_start == -1) {  // args section not yet found
+            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 !");
+            }
+        }
+        else {                  // search arg-value touples
+            if (argname == NULL) {    //  arg-name found ?
+                if (buffer[i] == '=') {
+                    //  yes, separate the arg-name
+                    buffer[i] = 0;
+                    argname = &buffer[args_start];
+                    value_start = i+1;
+                    INFO("Argument name %s", argname);
+                }
+            }
+            else { // search for end of value
+                if ((buffer[i] == '&') || (buffer[i] == 0) || (buffer[i] == '\r') || (buffer[i] == '\n')) {
+                    buffer[i] = 0;
+                    valuename = &buffer[value_start];
+                    INFO("Argument value %s", valuename);
+                    args[argname] = valuename;
+                    //  reset all indicators
+                    argname = NULL;
+                    valuename = NULL;
+                }
+            }
+        }
+    }
+    
+    return 0;
+}
diff -r 000000000000 -r caf5feddac47 HTTPConnection.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPConnection.h	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,139 @@
+/* HTTPConnection.h */
+/*
+Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
+ 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef __HTTPConnection_H__
+#define __HTTPConnection_H__
+
+#include "mbed.h"
+#include "TCPSocketConnection.h"
+
+#include <string>
+#include <map>
+
+class HTTPServer;
+
+/** Type HTTPRequestType enumerates request types
+*/
+typedef enum 
+{
+    HTTP_RT_GET,        /*!< GET request */
+    HTTP_RT_POST,       /*!< POST request */
+    HTTP_RT_PUT,        /*!< PUT request */
+    HTTP_RT_OPTIONS,    /*!< OPTIONS request */
+    HTTP_RT_HEAD,       /*!< HEAD request */
+    HTTP_RT_DELETE,     /*!< DELETE request */
+    HTTP_RT_TRACE,      /*!< TRACE request */
+    HTTP_RT_CONNECT     /*!< CONNECT request */
+} HTTPRequestType;
+
+/** class HTTPConnection, encapsulates one connection being made throught the HTTPServer
+ *
+ */
+class HTTPConnection {
+    public:
+        
+        /** HTTPMessage contains all the details of the request received by external HTTP client.
+        */
+        typedef struct 
+        {
+            /** Specifies the request type received
+            */
+            HTTPRequestType                         request;
+            /** The uri associated with the request.
+            */
+            std::string                             uri;
+            /** Contains the HTTP/1.1 or HTTP/1.0 version requested by client.
+            */
+            std::string                             version;
+            /** Map of headers provided by the client in the form <HeaderName>:<HeaderValue>
+            */
+            std::map<std::string, std::string>      headers;
+            /** Map of arguments that came with the uri string
+            */
+            std::map<std::string, std::string>      args;
+        } HTTPMessage;
+        
+        /** Public constructor for HTTPConnection objects.
+         *
+         */
+        HTTPConnection (TCPSocketConnection& clnt);
+        
+        /** Destructor for HTTPConnection objects.
+        *
+        */
+        ~HTTPConnection();
+        
+        /** Query if this connection is already closed and can be deleted.
+        @returns true, if connection is closed.
+        */
+        bool is_closed();
+        
+        /** Polling function for the connection.
+        * @returns -1 if connection is not required anymore. In the current version of this library this should be the normal case. This may change in future versions.
+        */
+        int poll();
+    
+    protected:
+        
+        /** Function to close this connection. To be called from internally.
+        */
+        void close();
+
+        friend class HTTPServer;
+                        
+        TCPSocketConnection m_Tcp;
+        HTTPMessage m_Msg;
+
+        /** parse a HTTP request line from the content of the buffer. 
+        * @param buffer : the request received from the client in the form <RequestType> <uri> <Http Version>
+        * @returns -1 if the request is invalid or 0 if the request is valid
+        */
+        int parse(char *buffer);
+        
+        /** parses the received string in \c buffer for HTTP request headers.
+        * @param buffer : buffer which contains the string to parse for headers.
+        * @returns -1 in case of an error, otherwise returns 0
+        */
+        int parseHeader(char *buffer);
+        int receiveHeaders(const char* buffer, int nBuffSize);
+        
+        /** Function which receives a line from the current Socket
+        * @param szline : will contain one line received from the socket
+        * @param nMaxLen : the size of the buffer. If the line is longer than the buffer the line is cropped at the end.
+        * @param nTimeout : if the timeout elapses, only the portion that has been received within this time will be returned.
+        * @param szLineTerm : the \c end-of-line character to be used to detect the end of the line.
+        * @returns -1 in case of an error or timeout, -2 in case of an empty line or the number of received characters.
+        */
+        int receiveLine(char* szLine, int nMaxLen, int nTimeout = -1, char szLineTerm = '\n');
+
+    
+        /** parse the receoved \c uri_string for arguments which will be stored in the \c args map.
+        * @parse uri_string : the uri string which was received from the client.
+        * @parse args : the args map which will receive the argument:value touples from the \c uri_string.
+        * @returns -1 if an error occured, otherwise returns 0.
+        */
+        int parseUriArgs(char *uri_string, map<string,string>& args);
+
+};
+
+#endif // __HTTPConnection_H__
+
diff -r 000000000000 -r caf5feddac47 HTTPRequestHandler.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPRequestHandler.cpp	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,176 @@
+/* HTTPRequestHandler.cpp */
+#include "mbed.h"
+#include "HTTPRequestHandler.h"
+#define DEBUG
+#include "hl_debug.h"
+#include <ctype.h>
+
+
+static char buffer[128];
+
+
+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)
+{
+    int la = strlen(a);
+    int lb = strlen(b);
+    for (int i = 0 ; i < min(la, lb) ; i++) {
+        if (tolower((int)a[i]) != tolower((int)b[i]))
+            return i;
+    }
+    return 0;
+}
+
+
+static const struct mapping_t {
+    const char* key;
+    const char* value;
+} fileTypeMapping[]  = {
+        {".gif", "Content-Type: image/gif\r\n"   },
+    {".jpg", "Content-Type: image/jpeg\r\n"  },
+    {".jpeg","Content-Type: image/jpeg\r\n"  },
+    {".ico", "Content-Type: image/x-icon\r\n"},
+    {".png", "Content-Type: image/png\r\n"   },
+    {".zip", "Content-Type: image/zip\r\n"   },
+    {".gz",  "Content-Type: image/gz\r\n"    },
+    {".tar", "Content-Type: image/tar\r\n"   },
+    {".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"   },
+    {".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)
+{
+    msg = Msg;
+    tcp = Tcp;
+
+}
+
+HTTPRequestHandler::~HTTPRequestHandler()
+{
+}
+
+void HTTPRequestHandler::getStandardHeaders(HTTPHeaders& header, const char* fext)
+{
+    header.clear();
+    header["DNT"] = "1";
+    header["MaxAge"] = "0";
+    header["Connection"] = "Keep-Alive";
+    header["Server"] = "mbed Embedded";
+    if (fext == NULL)
+        header["Content-Type"] = "text/html";
+    else {
+        for (int i = 0 ; i < sizeof(fileTypeMapping)/sizeof(struct mapping_t) ;i++) {
+            if (_stricmp(fileTypeMapping[i].key, fext) == 0) {
+                header["Content-Type"] = fileTypeMapping[i].value;
+                break;
+            }
+        }
+    }
+}
+
+void HTTPRequestHandler::handleRequest()
+{
+    int err = 0;
+    
+    switch (msg.request) {
+        case HTTP_RT_GET:
+            INFO("Dispatching GET Request.");
+            err = handleGetRequest();
+            break;
+            
+        case HTTP_RT_POST:
+            INFO("Dispatching POST request.");
+            err = handlePostRequest();
+            break;
+            
+        case HTTP_RT_PUT:
+            INFO("Dispatching PUT request.");
+            err = handlePutRequest();
+            break;
+            
+        default:
+            INFO("Error in handleRequest, unhandled request type.");
+            err = HTTP_NotImplemented;
+            break;
+    }
+    
+    //  if any of these functions returns a negative number, call the error handler
+    if (err > 0) {
+        handleError(err);
+    }        
+}
+
+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(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));
+    tcp.send(buffer, strlen(buffer));
+    if (header == NULL) {
+        sprintf(buffer, "Content-Type: text/html\r\nServer: mbed embedded\r\n\n\r");
+        tcp.send(buffer, strlen(buffer));
+    }
+    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",2);
+        }
+        tcp.send("\r\n",2);
+    }
+    tcp.send((char*)szErrorPage, strlen(szErrorPage));
+}
+
+
+void HTTPRequestHandler::startResponse(int returnCode, long nLen, HTTPHeaders* header)
+{
+    INFO("Starting response (%ld bytes in total)!", nLen);
+    tcp.set_blocking(false, 1500);
+    sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode);
+    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 !");
+    if (header == NULL) {
+        tcp.send_all((char*)hdrStandard, strlen(hdrStandard));
+    }
+    else {
+        for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
+            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
+}
+
+void HTTPRequestHandler::processResponse(int nLen, char* body)
+{
+    INFO("Processing Response (%d bytes)!\n",nLen);
+    tcp.send_all(body, nLen);
+}
+
+void HTTPRequestHandler::endResponse()
+{
+    INFO("Ending Response !");
+}
diff -r 000000000000 -r caf5feddac47 HTTPRequestHandler.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPRequestHandler.h	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,139 @@
+/* HTTPRequestHandler.h */
+/*
+Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
+ 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef __HTTPREQUESTHANDLER_H__
+#define __HTTPREQUESTHANDLER_H__
+
+#include "mbed.h"
+#include "HTTPConnection.h"
+
+#include <map>
+
+typedef std::map<const char*,const char*> HTTPHeaders;
+
+typedef enum {
+    HTTP_Continue                       = 100,  // 100
+    HTTP_SwitchingProtocols             = 101,  // 101
+    HTTP_Ok                             = 200,  // 200
+    HTTP_Created                        = 201,  // 201
+    HTTP_Accepted                       = 202,  // 202
+    HTTP_NonAuthoritativeInformation    = 203,  // 203
+    HTTP_NoContent                      = 204,  // 204
+    HTTP_ResetContent                   = 205,  // 205
+    HTTP_PartialContent                 = 206,  // 206
+    HTTP_MultipleChoices                = 300,  // 300
+    HTTP_MovedPermanently               = 301,  // 301
+    HTTP_Found                          = 302,  // 302
+    HTTP_SeeOther                       = 303,  // 303
+    HTTP_NotModified                    = 304,  // 304
+    HTTP_UseProxy                       = 305,  // 305
+    HTTP_TemporaryRedirect              = 307,  // 307
+    HTTP_BadRequest                     = 400,  // 400
+    HTTP_Unauthorized                   = 401,  // 401
+    HTTP_PaymentRequired                = 402,  // 402
+    HTTP_Forbidden                      = 403,  // 403
+    HTTP_NotFound                       = 404,  // 404
+    HTTP_MethodNotAllowed               = 405,  // 405
+    HTTP_NotAcceptable                  = 406,  // 406
+    HTTP_ProxyAuthRequired              = 407,  // 407
+    HTTP_RequestTimeOut                 = 408,  // 408
+    HTTP_Conflict                       = 409,  // 409
+    HTTP_Gone                           = 410,  // 410
+    HTTP_LengthRequired                 = 411,  // 411
+    HTTP_PreconditionFailed             = 412,  // 412
+    HTTP_RequestEntityTooLarge          = 413,  // 413
+    HTTP_RequestURITooLarge             = 414,  // 414
+    HTTP_UnsupportedMediaType           = 415,  // 415
+    HTTP_RequestedRangeNotSatisfiable   = 416,  // 416
+    HTTP_ExpectationFailed              = 417,  // 417
+    HTTP_InternalServerError            = 500,  // 500
+    HTTP_NotImplemented                 = 501,  // 501
+    HTTP_BadGateway                     = 502,  // 502
+    HTTP_ServiceUnavailable             = 503,  // 503
+    HTTP_GatewayTimeout                 = 504,  // 504
+    HTTP_HTTPVersionNotSupported        = 505,  // 505
+} HTTPResponseCode;
+
+/** class HTTPRequestHandler is the base class for HTTP Handler request implementations.
+*
+*/
+class HTTPRequestHandler
+{
+    protected:
+        HTTPConnection::HTTPMessage& msg;
+        TCPSocketConnection& tcp;
+        
+    public:
+        /** Constructor for HTTPRequestHandler objects.
+         */
+        HTTPRequestHandler(HTTPConnection::HTTPMessage&, TCPSocketConnection&);
+        
+        /** Destructor for HTTPRequestHandler objects.
+        */
+        virtual ~HTTPRequestHandler();
+        
+        /** Handler function which will be used by the HTTPServer to serve requests.
+        * The default version of this function will dispatch respective handler member
+        * functions according to the request type given in the HTTPMessage object.
+        * The list of possible functions dispatched is :
+        * * handleGetRequest
+        * * handlePostRequest
+        * * handlePutRequest
+        */
+        virtual void handleRequest();
+        
+        /** Handler function which will handle errors and return errors correctly
+        * @param errorCode : The error code returned by the HTTP Server to represent the error condition.
+        * @param msg : Request Message information.
+        * @param tcp : The socket which represents the active connection to the client.
+        */
+        virtual void handleError(int errorCode, HTTPHeaders* header = NULL);
+
+        /** Function sends the response header which consists of the return code and the headers section
+        * the response header also contains the length (in bytes) of the body. You need to send the body
+        * right after calling this function. Please note that you do not need to consider the terminating
+        * CR+LF after your last CR+LF. This will be sent automatically once \c endResponse is called. Also
+        * the Length given in \c nLen does not need to consider this additional chars. It will also be
+        * automatically added in \c startResponse. if you need to change the headers, please do NOT 
+        * specify the \c Content-Length Header. This is done automatically be the function.
+        */
+        void startResponse(int returnCode, long nLen, HTTPHeaders* header = NULL);
+        void processResponse(int nLen, char* body );
+        void endResponse();
+
+    protected:
+        /** Handler function to serve GET requests. Download ressource from server from \c uri location.
+        */
+        virtual int handleGetRequest() = 0;
+        
+        /** Handler function to serve PUT requests. Upload ressource to server to \c uri location.
+        */
+        virtual int handlePutRequest() = 0;
+        
+        /** Handler function to serve POST requests. Send data to webserver. Can also be appended to uri.
+        */
+        virtual int handlePostRequest() = 0;
+        
+        void getStandardHeaders(HTTPHeaders& header, const char* fext = NULL);
+};
+
+#endif //   __HTTPREQUESTHANDLER_H__
diff -r 000000000000 -r caf5feddac47 HTTPServer.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPServer.cpp	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,153 @@
+#include "mbed.h"
+#include "HTTPServer.h"
+#define DEBUG
+#include "hl_debug.h"
+
+
+
+/* Constructor */
+/* initialize all members and set the standard error handler. */
+HTTPServer::HTTPServer()
+    : m_pEthernet(NULL)
+{
+    m_pErrorHandler = StdErrorHandler;
+}
+
+HTTPServer::~HTTPServer()
+{
+    if (m_pEthernet == NULL) {
+        INFO("Deleting EthernetInterface Object.\n");
+        delete m_pEthernet;
+    }
+}
+
+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[256];
+    tcp.set_blocking(true, 1500);
+    sprintf(echoHeader,"HTTP/1.0 404 Fail\r\nConnection: close\r\nContent-Length: %d\r\nContent-Type: text/html\r\nServer: mbed embedded\r\n\n\r",strlen(szStdErrorPage));
+    tcp.send(echoHeader, strlen(echoHeader));
+    tcp.send((char*)szStdErrorPage, strlen(szStdErrorPage));
+}
+
+
+bool HTTPServer::start(int port, EthernetInterface* pEthernet)
+{
+    //  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) {
+        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;
+        }
+
+        //  Initiaize the network
+        INFO("Initializing network\n");
+        if (m_pEthernet->init() != 0) {
+            ERR("Failed to initialize the ethernet interface !");
+            delete m_pEthernet;
+            m_pEthernet = NULL;
+            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 !");
+            delete m_pEthernet;
+            m_pEthernet = NULL;
+            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("Binding to port %d...", port);
+    if (m_Svr.bind(port) < 0) {
+        ERR("Failed to bind to port !\n");
+        error("Binding");
+        return false;
+    }
+
+    INFO("Listening ...");
+    if (m_Svr.listen(1) < 0) {
+        ERR("Failed to listen !\n");
+        error("Listening");
+        return false;
+    }
+
+    INFO("Connected !");
+    //  set into non blocking operation
+    m_Svr.set_blocking(false, 100);
+
+    return true;
+}
+
+
+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;
+    }
+
+    //   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;
+}
+
+void HTTPServer::HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp)
+{
+    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) {
+            // firts matching handler found, we just take it and we'll be happy
+            localPath = msg.uri.substr(curpth.length());
+            break;
+        }
+    }
+
+    if (it == m_lpHandlers.end()) {
+        //  There is no such handler, so return invalid
+
+        m_pErrorHandler(msg, tcp);
+        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;
+    }
+}
diff -r 000000000000 -r caf5feddac47 HTTPServer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPServer.h	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,212 @@
+/* HTTPServer.cpp */
+/*
+Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
+ 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef __HTTPSERVER_H__
+#define __HTTPSERVER_H__
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "HTTPConnection.h"
+#include "HTTPRequestHandler.h"
+#include "RpcHandler.h"
+
+#include <map>
+using std::map;
+#include <string>
+using std::string;
+
+#include <TCPSocketConnection.h>
+#include <TCPSocketServer.h>
+
+/** Typedefinition for a handler function
+*/
+typedef void (*HTTPRequestHandlerFunction)(HTTPConnection::HTTPMessage&, TCPSocketConnection&);
+
+
+/** Class HTTPServer for use with <a href="http://mbed.org/users/samux/code/WiflyInterface/">WiflyInterface</a>.
+* This class is a simple implementation of an HTTP Server for use with the WiFly interface.
+* The class will listen for incoming connections on the (configurable) HTTP port. For each 
+* incoming connection, one request will be processed. 
+* After instantiating this class, add all required handlers using the \c addHandler function,
+* replace the default error handler using \c addErrorHandler if needed and call the \c start
+* method to initialize the class.
+* You need to continuously poll for any new incoming connections after one request has been
+* served using the \c poll member function.
+*
+* \b Example:
+* @code
+* #include "mbed.h"
+* #include "HTTPServer.h"
+* #include "LocalFileSystem.h"
+*
+* LocalFileSystem local("local"); 
+*
+* void main(void)
+* {
+*     HTTPServer svr;
+*     svr.mount("/local/", "/");
+*     svr.addHandler<HTTPFsRequestHandler>( "/" );
+*     svr.start();
+*     while(1)
+*     {
+*         if (svr.poll() < 0)
+*             exit(0);
+*     }
+* }
+* @endcode
+*
+* An alternate approach e.g. if you need to perform additional tasks using the EthernetInterface
+* there is the possibility to provide the EthernetInterface object in an initialized and connected
+* state. __NOTE: You should choose this scenario for compatibility reasons.___
+*
+* \b Example2:
+* @code
+* #include "mbed.h"
+* #include "HTTPServer.h"
+* #include "EthernetInterface.h"
+* #include "LocalFileSystem.h"
+*
+* LocalFileSystem local("local");
+* EthernetInterface eth;
+*
+* void main(void)
+* {
+*     HTTPServer svr;
+*     //    Initialize the ethernet interface
+*     if (eth.init() != 0) {
+*         printf("Initialization of EthernetInterface failed !");
+*         exit(0);
+*     }
+*     //    Connect using DHCP
+*     if (eth.connect() !=0) {
+*         printf("Failed to connect using DHCP !");
+*         exit(0);
+*     }
+*     
+*     // Moint the local file system and provide a handler for 'root'.
+*     svr.mount("/local/", "/");
+*     svr.addHandler<HTTPFsRequestHandler>( "/" );
+*     // Start the server on port 80, providing our own ethernet interface object.
+*     svr.start(80, &eth);
+*     while(1)
+*     {
+*         if (svr.poll() < 0)
+*             exit(0);
+*     }
+* }
+* @endcode
+*     
+*/
+class HTTPServer
+{
+        TCPSocketServer         m_Svr;
+        bool                    m_bServerListening;
+        EthernetInterface*      m_pEthernet;
+       
+    public:
+        /** Constructor for HTTPServer objects.
+        */
+        HTTPServer();
+        
+        /** Destructor for HTTPServer objects.
+        */
+        ~HTTPServer();
+
+        /**
+        * Structure which will allow to order the stored handlers according to their associated path.
+        */
+        struct handlersComp //Used to order handlers in the right way
+        {
+            bool operator() (const string& handler1, const string& handler2) const
+            {
+                //The first handler is longer than the second one
+                if (handler1.length() > handler2.length())
+                    return true; //Returns true if handler1 is to appear before handler2
+                else if (handler1.length() < handler2.length())
+                    return false;
+                else //To avoid the == case, sort now by address
+                    return ((&handler1)>(&handler2));
+            }
+        };
+
+        /**
+        * Adds a request handler to the handlers list. You will have to use one of the existing implementations.
+        * With each handler a \c uri or \c path is associated. Whenever a request is received the server will
+        * walk through all registered handlers and check which \c path is matching.
+        * @param T : class which will be instanciated to serve these requests for the associated \b path.
+        * @param path : request uri starting with this \c path will be served using this handler.
+        */
+        template<typename T>
+        void addHandler(const char* path)
+        { m_lpHandlers[path] = &T::create; }
+    
+        /**
+        * Replaces the standard error Handler. The error Handler will be called everytime a request is not
+        * matching any of the registered \c paths or \c uris.
+        * @param hdlFunc: User specified handler function which will be used in error conditions.
+        */
+        void addErrorHandler(HTTPRequestHandlerFunction hdlFunc)
+        { 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
+        * @param port : port on which to listen for incoming connections
+        * @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);
+        
+        /** 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.
+        */
+        int poll(bool blocking = true);
+        
+    private:
+        
+        /** The standard error handler function.
+        * @param msg : Request message data.
+        * @param tcp : Socket to be used for responding.
+        */
+        static void StdErrorHandler(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp);
+        
+        /** Internal function which processes a request and which will try to find the matching handler function
+        * for the given request. Please note that the function will search through the list of handlers, iterating
+        * from longest to shortest \c paths. If the registered \c path is a subset of the request the associated
+        * handler is considered as being a match.
+        * @param msg : Request message data. Contains the requested logical \c uri. 
+        * @param tcp : Socket to be used for communication with the client.
+        */
+        void HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp);
+    
+        /** Map of handler objects. Can be any object derived from \ref HTTPRequestHeader. Use the \ref addHandler function
+        * to register new handler objects.
+        */
+        map<string, HTTPRequestHandler* (*)(const char*, const char*, HTTPConnection::HTTPMessage&, TCPSocketConnection&), handlersComp>   m_lpHandlers;
+        HTTPRequestHandlerFunction m_pErrorHandler;
+        
+ };
+ 
+ #endif //__HTTPSERVER_H__
+ 
\ No newline at end of file
diff -r 000000000000 -r caf5feddac47 Handler/FsHandler.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/FsHandler.cpp	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,126 @@
+/* FsHandler.cpp */
+#include "mbed.h"
+#include "FsHandler.h"
+#define DEBUG
+#include "hl_debug.h"
+
+
+
+static int matchstrings(const char* one, const char* two)
+{
+    int m = 0;
+    
+    for (m = 0; m < min(strlen(one), strlen(two)) ; m++) {
+        if (one[m] != two[m])
+            return m;
+    }
+    return m;
+}
+
+std::map<const char*, const char*> HTTPFsRequestHandler::m_fsMap;
+ 
+HTTPFsRequestHandler::HTTPFsRequestHandler(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp)
+    : HTTPRequestHandler(Msg, Tcp)
+{
+    m_rootPath = rootPath;
+    m_localPath = localPath;
+    
+    string myPath = m_rootPath + m_localPath;
+    
+    //  Now replace the virtual root path with a mounted device path
+    std::map<const char*, const char*>::iterator it;
+    const char *bestMatch = NULL;
+    const char *bestMatchExchange = NULL;
+    int match_ind = -1;
+    for (it = m_fsMap.begin() ; it != m_fsMap.end() ; it++) {
+        //  find best match (if the given logical path is containted in the root
+        int s = matchstrings(myPath.c_str(), it->second);
+        INFO("Matching Root %s with handler %s results in %d identical characters\n", myPath.c_str(), it->second, s);
+        if ((s == strlen(it->second)) && (s > match_ind)) {
+            match_ind = s;
+            bestMatch = it->first;
+            bestMatchExchange = it->second;
+        }
+    }
+
+    if (bestMatch != NULL) {
+        m_rootPath = bestMatch;
+        m_localPath = string(myPath).substr(strlen(bestMatchExchange));
+    }
+            
+    handleRequest();
+}
+
+HTTPFsRequestHandler::~HTTPFsRequestHandler()
+{
+}
+
+int HTTPFsRequestHandler::handleGetRequest()
+{
+    HTTPHeaders headers;
+    
+    if (m_localPath.length() > 4) 
+        getStandardHeaders(headers, m_localPath.substr(m_localPath.length()-4).c_str());
+    else
+        getStandardHeaders(headers);
+    
+    INFO("Handling Get Request (root = %s, local = %s).", m_rootPath.c_str(), m_localPath.c_str());
+    int retval = 0;   //success
+    std::string reqPath;
+
+    //  Check if we received a directory with the local bath
+    if ((m_localPath.length() == 0) || (m_localPath.substr( m_localPath.length()-1, 1) == "/")) {
+        //  yes, we shall append the default page name
+        m_localPath += "index.html";
+    }
+    
+    reqPath = m_rootPath + m_localPath;
+    
+    INFO("Mapping \"%s\" to \"%s\"", msg.uri.c_str(), reqPath.c_str());
+        
+    FILE *fp = fopen(reqPath.c_str(), "r");
+    if (fp != NULL) {
+        char * pBuffer = NULL;
+        int sz = 8192;
+        while( pBuffer == NULL) {
+            sz /= 2;
+            pBuffer = (char*)malloc(sz);
+            if (sz < 128)
+                error ("OutOfMemory");
+        }
+        
+        //  File was found and can be returned
+    
+        //  first determine the size
+        fseek(fp, 0, SEEK_END);
+        long size = ftell(fp);
+        fseek(fp, 0, SEEK_SET);
+    
+        startResponse(200, size);
+        while(!feof(fp) && !ferror(fp)) {
+            int cnt = fread(pBuffer, 1, sz , fp);
+            if (cnt < 0)
+                cnt = 0;
+            processResponse(cnt, pBuffer);
+        }
+        delete pBuffer;
+        endResponse();
+        fclose(fp);
+    }
+    else {
+        retval = 404;
+        ERR("Requested file was not found !");
+    }
+    
+    return retval;
+}
+
+int HTTPFsRequestHandler::handlePostRequest()
+{
+    return 404;
+}
+
+int HTTPFsRequestHandler::handlePutRequest()
+{
+    return 404;
+}
diff -r 000000000000 -r caf5feddac47 Handler/FsHandler.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/FsHandler.h	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,81 @@
+/* FsHandler.h */
+/*
+Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
+ 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef __FSHANDLER_H__
+#define __FSHANDLER_H__
+
+#include "mbed.h"
+#include "HTTPRequestHandler.h"
+
+#include <map>
+#include <string>
+
+/** class HTTPFsRequestHandler serves requests with file-system objects
+*/
+class HTTPFsRequestHandler : public HTTPRequestHandler
+{
+        std::string m_rootPath;
+        std::string m_localPath;
+
+    public:
+        /** constructor for HTTPFsRequestHandler object and stores the request related data locally. 
+        * the request handling will be initiated from within the constructor.
+        * @param rootPath : The path under which the handler was registered.
+        * @param localPath : The path which is relative to the registered file system root.
+        * @param Msg : Message request information that comes with the request.
+        * @param Tcp : The socket connection for communicating with the client.
+        */
+        HTTPFsRequestHandler(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp);
+        
+        /** Destructor 
+        */
+        virtual ~HTTPFsRequestHandler();
+  
+        /** static creation function for this object.
+        */
+        static inline HTTPRequestHandler* create(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp) { return new HTTPFsRequestHandler(rootPath, localPath, msg, tcp); }
+              
+        /** Handler function to serve GET requests
+        */
+        virtual int handleGetRequest();
+        
+        /** Handler function to serve PUT requests
+        */
+        virtual int handlePutRequest();
+        
+        /** Handler function to serve POST requests
+        */
+        virtual int handlePostRequest();
+
+        /** Map to register different file system types and associate them with different root paths
+        */
+        static std::map<const char*, const char*> m_fsMap;
+        
+        /** static function to register a new file system type with a logical root path
+        */
+        static void mount(const char* requestPath, const char* localPath) { m_fsMap[requestPath] = localPath; }
+        
+        /** Parse a uri string for uri file name and argument:value pairs
+        */
+        int parseUriArgs(string uri, map<string, string>& args);
+};
+#endif // __FSHANDLER_H__
diff -r 000000000000 -r caf5feddac47 Handler/RpcHandler.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/RpcHandler.cpp	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,76 @@
+/* FsHandler.cpp */
+#include "mbed.h"
+#include "RpcHandler.h"
+#include "mbed_rpc.h"
+
+
+#define DEBUG 1
+#include "hl_debug.h"
+
+RPC rpc("rpc");
+
+
+HTTPRpcRequestHandler::HTTPRpcRequestHandler(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp)
+    : HTTPRequestHandler(Msg, Tcp)
+{
+    m_rootPath = rootPath;
+    m_localPath = localPath;
+    
+    handleRequest();
+}
+
+
+HTTPRpcRequestHandler::~HTTPRpcRequestHandler()
+{
+}
+
+
+int HTTPRpcRequestHandler::handleGetRequest()
+{
+    char outBuf[256] = {};
+    bool retval = false;
+    int err = 404;
+    string rpc_args("");
+    
+    INFO("Handling RPC Get Requesst.");
+    // 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
+
+    //  Append missing slash if needed
+    if (m_localPath.c_str()[0] != '/') {
+        rpc_args = "/";
+    }
+    // replace the HTTP strings with ascii strings
+    for (int i = 0 ; i < m_localPath.length() ; i++) {
+        if (m_localPath.substr(i,3) == "%20") {
+            rpc_args += " ";
+            i+=2;
+        }
+        else {
+            rpc_args += m_localPath.substr(i,1);
+        }
+    }
+    INFO("RPC to %s", rpc_args.c_str());
+    retval = rpc.call(rpc_args.c_str(),outBuf);
+    INFO("RPC Request returned %d with args : %s", retval==true ? 200 : 0, outBuf);
+    if (retval) {
+        //  No error
+        startResponse(200, strlen(outBuf));
+        processResponse(strlen(outBuf), outBuf);
+        endResponse();
+        err = 0;
+    }
+    
+    return err;
+}
+
+int HTTPRpcRequestHandler::handlePutRequest()
+{
+    return 404;
+}
+
+int HTTPRpcRequestHandler::handlePostRequest()
+{
+    return 404;
+}
\ No newline at end of file
diff -r 000000000000 -r caf5feddac47 Handler/RpcHandler.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/RpcHandler.h	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,68 @@
+/* RpcHandler.h */
+/*
+Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
+ 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef __RPCHANDLER_H__
+#define __RPCHANDLER_H__
+
+#include "mbed.h"
+#include "HTTPRequestHandler.h"
+
+class HTTPRpcRequestHandler : public HTTPRequestHandler
+{
+        std::string m_rootPath;
+        std::string m_localPath;
+
+    public:
+        /** constructor for HTTPRpcRequestHandler object and stores the request related data locally. 
+        * the request handling will be initiated from within the constructor.
+        * @param rootPath : The path under which the handler was registered.
+        * @param localPath : The path which is relative to the registered file system root.
+        * @param Msg : Message request information that comes with the request.
+        * @param Tcp : The socket connection for communicating with the client.
+        */
+        HTTPRpcRequestHandler(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp);
+        
+        /** Destructor 
+        */
+        virtual ~HTTPRpcRequestHandler();
+  
+        /** static creation function for this object.
+        */
+        static inline HTTPRequestHandler* create(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp) { return new HTTPRpcRequestHandler(rootPath, localPath, msg, tcp); }
+              
+        /** Handler function to serve GET requests
+        */
+        virtual int handleGetRequest();
+        
+        /** Handler function to serve PUT requests
+        */
+        virtual int handlePutRequest();
+        
+        /** Handler function to serve POST requests
+        */
+        virtual int handlePostRequest();
+
+        /** Parse a uri string for uri file name and argument:value pairs
+        */
+//        int parseUriArgs(string uri, string map<string, string>& args);
+};
+#endif //   __RPCHANDLER_H__
diff -r 000000000000 -r caf5feddac47 hl_debug.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hl_debug.h	Sat Sep 16 02:39:55 2017 +0000
@@ -0,0 +1,16 @@
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+
+#ifdef DEBUG
+#define INFO(x, ...) std::printf("[INFO: %s:%d]"x"\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[WARN: %s:%d]"x"\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define ERR(x, ...) std::printf("[ERR: %s:%d]"x"\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define INFO(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+#endif
+
+
+#endif //   __DEBUG_H__#ifndef __DEBUG_H__