Adaptation of the HttpServer by user yueee_yt. This version has improved handling of the HTTP headers (**NOTE**: There are limitations with this implementation and it is not fully functional. Use it only as a starting point.)

Dependents:   DMSupport DMSupport DMSupport DMSupport

Fork of DM_HttpServer by EmbeddedArtists AB

Files at this revision

API Documentation at this revision

Comitter:
yueee_yt
Date:
Thu Feb 20 05:36:19 2014 +0000
Child:
1:f5f79412e1aa
Commit message:
Initialize version

Changed in this revision

HTTPRequestDispatcher.h Show annotated file Show diff for this revision Revisions of this file
HTTPRequestDispatcher.txt 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.h Show annotated file Show diff for this revision Revisions of this file
HTTPServer.txt Show annotated file Show diff for this revision Revisions of this file
HTTPServer2.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
Handler/SimpleHandler.cpp Show annotated file Show diff for this revision Revisions of this file
Handler/SimpleHandler.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPRequestDispatcher.h	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,78 @@
+
+/*
+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 HTTP_REQUEST_DISPATCHER_H
+#define HTTP_REQUEST_DISPATCHER_H
+
+//class HTTPServer;
+
+//*#include "api/TCPSocket.h"
+//#include "HTTPServer.h"
+//*#include "core/netservice.h"
+
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "HTTPRequestHandler.h"
+#include "HTTPServer2.h"
+#define HTTP_REQUEST_TIMEOUT 5000
+
+#include <string>
+using std::string;
+#include <map>
+using std::map;
+
+//struct handlersComp;
+
+class HTTPRequestDispatcher //: public NetService
+{
+public:
+  HTTPRequestDispatcher(map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocketConnection* ), handlersComp > lpHandlers,TCPSocketConnection* client);
+  virtual ~HTTPRequestDispatcher();
+  
+private:
+
+  enum HTTP_METH
+  {
+    HTTP_GET,
+    HTTP_POST,
+    HTTP_HEAD
+  };
+  
+  void dispatchRequest();
+  
+  virtual void close(); //Close TCPSocket and destroy data
+  
+//* void onTCPSocketEvent(/**TCPSocketEvent e**/);
+  
+  void onTimeout(); //Connection has timed out
+
+  bool getRequest(string* path, string* meth);
+  
+  //HTTPServer* m_pSvr;
+ TCPSocketConnection* m_pTCPSocketConnection;
+ map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocketConnection* ), handlersComp > m_lpHandlers;
+    Timeout m_watchdog;
+  bool m_closed;
+};
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPRequestDispatcher.txt	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,217 @@
+/*
+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.
+*/
+
+//*#include "core/netservice.h"
+#include "HTTPRequestDispatcher.h"
+#include "HTTPRequestHandler.h"
+#include <string>
+using std::string;
+
+#include <map>
+using std::map;
+
+
+//#define __DEBUG
+#include "dbg/dbg.h"
+
+HTTPRequestDispatcher::HTTPRequestDispatcher(map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocketConnection* ), handlersComp > lpHandlers,TCPSocketConnection* client) : /*NetService(), m_pSvr(pSvr),m_watchdog(),*/m_pTCPSocketConnection(client),  m_closed(false), m_lpHandlers(lpHandlers)
+{
+//*  m_pTCPSocket->setOnEvent(this, &HTTPRequestDispatcher::onTCPSocketEvent); *//
+//*  m_watchdog.attach_us<HTTPRequestDispatcher>(this, &HTTPRequestDispatcher::onTimeout, HTTP_REQUEST_TIMEOUT * 1000); *//
+   printf("(Dispatcher)Connection from %s\r\n", client->get_address());
+   dispatchRequest();  
+}
+
+HTTPRequestDispatcher::~HTTPRequestDispatcher()
+{
+  close();
+}
+
+void HTTPRequestDispatcher::dispatchRequest()
+{
+  string path;
+  string meth;
+  HTTP_METH methCode;
+  
+  printf("Dispatching req\r\n");
+  
+  if( !getRequest(&path, &meth ) )
+  {
+     printf("HTTPRequestDispatcher::dispatchRequest() Invalid request\r\n");
+       close();
+    return; //Invalid request
+  }
+  
+  if( !meth.compare("GET") )
+  {
+     printf("HTTPRequestDispatcher::dispatchRequest() HTTP_GET\r\n");
+     methCode = HTTP_GET;
+  }
+  else if( !meth.compare("POST") )
+  {
+    printf("HTTPRequestDispatcher::dispatchRequest() HTTP_POST\r\n");
+    methCode = HTTP_POST;
+  }
+  else if( !meth.compare("HEAD") )
+  {
+     printf("HTTPRequestDispatcher::dispatchRequest() HTTP_HEAD\r\n");
+    methCode = HTTP_HEAD;
+  }
+  else
+  {
+    printf("HTTPRequestDispatcher::dispatchRequest() Parse error\r\n");
+    close(); //Parse error
+    return;
+  }
+  
+  printf("Looking for a handler\r\n");
+  map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocketConnection*) >::iterator it;
+//  it = m_pSvr->m_lpHandlers.find(rootPath); //We are friends so we can do that
+// NEW CODE START: 
+  int root_len = 0;
+//**  for (it = m_pSvr->m_lpHandlers.begin(); it != m_pSvr->m_lpHandlers.end(); it++)
+  for (it = m_lpHandlers.begin(); it != m_lpHandlers.end(); it++)
+  {
+    printf("Checking %s...\r\n", (*it).first.c_str());
+    root_len = (*it).first.length();
+    if ( root_len &&
+      !path.compare( 0, root_len, (*it).first ) && 
+      (path[root_len] == '/' || path[root_len] == '\0'))
+    {
+      printf("Found (%s)\r\n", (*it).first.c_str());
+	    // Found!
+	    break;	// for
+	  }
+  }
+// NEW CODE END
+//**  if((it == m_pSvr->m_lpHandlers.end()) && !(m_pSvr->m_lpHandlers.empty()))
+  if((it == m_lpHandlers.end()) && !(m_lpHandlers.empty()))
+  {
+    printf("Using default handler\r\n");
+//**    it = m_pSvr->m_lpHandlers.end();
+    it = m_lpHandlers.end();
+    it--; //Get the last element
+    if( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler
+//**      it = m_pSvr->m_lpHandlers.end();
+      it = m_lpHandlers.end();
+    root_len = 0;
+  }
+//**  if(it == m_pSvr->m_lpHandlers.end())
+  if(it == m_lpHandlers.end())
+  {    
+    printf("No handler found\r\n");
+    close(); //No handler found
+    return;
+  }
+  printf("Handler found.\r\n");
+ 
+//HTTPRequestHandler* pHdlr = (*it).second(rootPath.c_str(), subPath.c_str(), m_pTCPSocket);
+//NEW CODE 1 LINE:
+  HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, m_pTCPSocketConnection);
+  m_pTCPSocketConnection = NULL; //We don't own it anymore
+ 
+  switch(methCode)
+  {
+  case HTTP_GET:
+    pHdlr->doGet();
+    break;
+  case HTTP_POST:
+    pHdlr->doPost();
+    break;
+  case HTTP_HEAD:
+    pHdlr->doHead();
+    break;
+  }
+ 
+  printf("Req handled (or being handled)\r\n");
+  close();
+  //delete pHdlr;
+  //delete m_pTCPSocketConnection;
+}
+
+void HTTPRequestDispatcher::close() //Close socket and destroy data
+{
+  if(m_closed)
+    return;
+  m_closed = true; //Prevent recursive calling or calling on an object being destructed by someone else
+  m_watchdog.detach();
+  /**
+  if(m_pTCPSocket) //m_pTCPSocket Should only be destroyed if ownership not passed to an handler
+  {
+    m_pTCPSocket->resetOnEvent();
+    m_pTCPSocket->close();
+    delete m_pTCPSocket; //This fn might have been called by this socket (through an event), so DO NOT DESTROY IT HERE
+  }
+  NetService::close();
+  **/
+}
+
+
+void HTTPRequestDispatcher::onTimeout() //Connection has timed out
+{
+  close();
+}
+
+bool HTTPRequestDispatcher::getRequest(string* path, string* meth)
+{
+  char req[128];
+  char c_path[128];
+  char c_meth[128];
+  const int maxLen = 128;
+  char* p = req;
+  //Read Line
+  int ret;
+  int len = 0;
+  for(int i = 0; i < maxLen - 1; i++)
+  {
+    ret = m_pTCPSocketConnection->receive(p, 1);
+    if(!ret)
+    {
+      break;
+    }
+    if( (len > 1) && *(p-1)=='\r' && *p=='\n' )
+    {
+      p--;
+      len-=2;
+      break;
+    }
+    else if( *p=='\n' )
+    {
+      len--;
+      break;    
+    }
+    p++;
+    len++;
+  }
+  *p = 0;
+  
+  DBG("Parsing request : %s\r\n", req);
+  
+  ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path);
+  if(ret !=2)
+    return false;
+    
+  *meth = string(c_meth);
+// NEW CODE (old code removed):
+   *path = string(c_path);
+  return true;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPRequestHandler.cpp	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,230 @@
+/*
+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.
+*/
+
+//#include "core/netservice.h"
+#include "HTTPRequestHandler.h"
+
+#include <string.h>
+
+//#define __DEBUG
+//#include "dbg/dbg.h"
+
+#define HTTP_REQUEST_TIMEOUT 5000
+
+//HTTPRequestHandler::HTTPRequestHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : NetService(),
+//   m_pTCPSocketConnection(pTCPSocketConnection), m_reqHeaders(), m_respHeaders(),
+//   m_rootPath(rootPath), m_path(path), m_errc(200),
+//   m_watchdog(), m_timeout(0),**/ m_closed(false), m_headersSent(false) //OK
+HTTPRequestHandler::HTTPRequestHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) :
+    m_pTCPSocketConnection(pTCPSocketConnection), m_reqHeaders(), m_respHeaders(),
+    m_rootPath(rootPath), m_path(path), m_errc(200), m_closed(false), m_headersSent(false)
+{
+    printf("+++(HTTPRequestHandler) init \r\n");
+    //Read & parse headers
+    readHeaders();
+//*  m_pTCPSocket->setOnEvent(this, &HTTPRequestHandler::onTCPSocketEvent);
+//*  setTimeout(HTTP_REQUEST_TIMEOUT);
+    printf("+++(HTTPRequestHandler) init end \r\n");
+}
+
+HTTPRequestHandler::~HTTPRequestHandler()
+{
+    close();
+    printf("+++(HTTPRequestHandler) Destroy end\r\n");
+}
+
+void HTTPRequestHandler::onTimeout() //Connection has timed out
+{
+    close();
+}
+
+void HTTPRequestHandler::close() //Close socket and destroy data
+{
+    if(m_closed)
+        return;
+    m_closed = true; //Prevent recursive calling or calling on an object being destructed by someone else
+    /**  m_watchdog.detach(); **/
+//*  onClose();
+//*  m_pTCPSocket->resetOnEvent();
+//*  m_pTCPSocket->close();
+//*  delete m_pTCPSocket; //Can safely destroy socket
+//*  NetService::close();
+}
+
+map<string, string>& HTTPRequestHandler::reqHeaders() //const
+{
+    return m_reqHeaders;
+}
+
+string& HTTPRequestHandler::path() //const
+{
+    return m_path;
+}
+
+int HTTPRequestHandler::dataLen() const
+{
+    map<string,string>::iterator it;
+    it = m_reqHeaders.find("Content-Length");
+    if( it == m_reqHeaders.end() ) {
+        return 0;
+    }
+    return atoi((*it).second.c_str()); //return 0 if parse fails, so that's fine
+}
+
+int HTTPRequestHandler::readData(char* buf, int len)
+{
+    return m_pTCPSocketConnection->receive(buf, len);
+}
+
+string& HTTPRequestHandler::rootPath() //const
+{
+    return m_rootPath;
+}
+
+void HTTPRequestHandler::setErrCode(int errc)
+{
+    m_errc = errc;
+}
+
+void HTTPRequestHandler::setContentLen(int len)
+{
+    char len_str[6] = {0};
+    sprintf(len_str, "%d", len);
+    respHeaders()["Content-Length"] = len_str;
+}
+
+map<string, string>& HTTPRequestHandler::respHeaders()
+{
+    return m_respHeaders;
+}
+
+int HTTPRequestHandler::writeData(const char* buf, int len)
+{
+    if(!m_headersSent) {
+        m_headersSent = true;
+        writeHeaders();
+    }
+    return m_pTCPSocketConnection->send((char *)buf, len);
+}
+/**
+void HTTPRequestHandler::setTimeout(int ms)
+{
+  m_timeout = 1000*ms;
+  resetTimeout();
+}
+**/
+/**
+void HTTPRequestHandler::resetTimeout()
+{
+  m_watchdog.detach();
+  m_watchdog.attach_us<HTTPRequestHandler>(this, &HTTPRequestHandler::onTimeout, m_timeout);
+}
+**/
+
+void HTTPRequestHandler::readHeaders()
+{
+    static char line[128];
+    static char key[128];
+    static char value[128];
+    while( readLine(line, 128) > 0) { //if == 0, it is an empty line = end of headers
+        int n = sscanf(line, "%[^:]: %[^\n]", key, value);
+        if ( n == 2 ) {
+            printf("\r\n+++(HTTPRequestHandler)Read header : %s : %s\r\n", key, value);
+            m_reqHeaders[key] = value;
+        }
+        //TODO: Impl n==1 case (part 2 of previous header)
+    }
+}
+
+void HTTPRequestHandler::writeHeaders() //Called at the first writeData call
+{
+    static char line[128];
+
+    //Response line
+    sprintf(line, "HTTP/1.1 %d MbedInfo\r\n", m_errc); //Not a violation of the standard not to include the descriptive text
+    m_pTCPSocketConnection->send(line, strlen(line));
+
+    map<string,string>::iterator it;
+    while( !m_respHeaders.empty() ) {
+        it = m_respHeaders.begin();
+        sprintf(line, "%s: %s\r\n", (*it).first.c_str(), (*it).second.c_str() );
+        printf("\r\n+++(HTTPRequestHandler)%s", line);
+        m_pTCPSocketConnection->send(line, strlen(line));
+        m_respHeaders.erase(it);
+    }
+    m_pTCPSocketConnection->send("\r\n",2); //End of head
+}
+
+int HTTPRequestHandler::readLine(char* str, int maxLen)
+{
+    int ret;
+    int len = 0;
+    for(int i = 0; i < maxLen - 1; i++) {
+        ret = m_pTCPSocketConnection->receive(str, 1);
+        if(!ret) {
+            break;
+        }
+        if( (len > 1) && *(str-1)=='\r' && *str=='\n' ) {
+            str--;
+            len-=2;
+            break;
+        } else if( *str=='\n' ) {
+            len--;
+            break;
+        }
+        str++;
+        len++;
+    }
+    *str = 0;
+    return len;
+}
+/**
+void HTTPRequestHandler::onTCPSocketEvent(TCPSocketEvent e)
+{
+  //printf("\r\nEvent %d in HTTPRequestHandler\r\n", e);
+  printf("\r\n+++(HTTPRequestHandler)Event in HTTPRequestHandler\r\n");
+
+  if(m_closed)
+  {
+    printf("\r\n+++(HTTPRequestHandler)WARN: Discarded\r\n");
+    return;
+  }
+
+  switch(e)
+  {
+        case TCPSOCKET_READABLE:
+    resetTimeout();
+   onReadable();
+    break;
+  case TCPSOCKET_WRITEABLE:
+    resetTimeout();
+    onWriteable();
+    break;
+  case TCPSOCKET_CONTIMEOUT:
+  case TCPSOCKET_CONRST:
+  case TCPSOCKET_CONABRT:
+  case TCPSOCKET_ERROR:
+  case TCPSOCKET_DISCONNECTED:
+    DBG("\r\nConnection error in handler\r\n");
+    close();
+    break;
+  }
+}
+**/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPRequestHandler.h	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,102 @@
+
+/*
+Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+ 
+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.
+*/
+
+/**
+HTTP Request Handler header file.
+*/
+
+#ifndef HTTP_REQUEST_HANDLER_H
+#define HTTP_REQUEST_HANDLER_H
+
+//*#include "api/TCPSocket.h"
+//#include "HTTPServer.h"
+
+#include "mbed.h"
+#include "EthernetInterface.h"
+//*#include "core/netservice.h"
+
+#include <string>
+using std::string;
+
+#include <map>
+using std::map;
+
+///HTTP Server's generic request handler
+class HTTPRequestHandler //*: public NetService
+{
+public:
+  ///Instantiated by the HTTP Server
+ HTTPRequestHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection);
+  virtual ~HTTPRequestHandler();
+
+//protected:
+  virtual void doGet() = 0;
+  virtual void doPost() = 0;
+  virtual void doHead() = 0;
+  
+  virtual void onReadable() = 0; //Data has been read
+  virtual void onWriteable() = 0; //Data has been written & buf is free
+  virtual void onTimeout(); //Connection has timed out
+  virtual void onClose() = 0; //Connection is closing
+  
+  virtual void close(); //Close socket and destroy data
+
+protected:  
+  map<string, string>& reqHeaders() /*const*/;
+  string& path() /*const*/;
+  int dataLen() const;
+  int readData(char* buf, int len);
+  string& rootPath() /*const*/;
+  
+  void setErrCode(int errc);
+  void setContentLen(int len);
+  
+  map<string, string>& respHeaders();
+  int writeData(const char* buf, int len);
+  
+//* void setTimeout(int ms);
+//*  void resetTimeout();
+
+private:
+  void readHeaders(); //Called at instanciation
+  void writeHeaders(); //Called at the first writeData call
+  //**void onTCPSocketEvent(/**TCPSocketEvent e**/);
+   
+  TCPSocketConnection* m_pTCPSocketConnection;
+  map<string, string> m_reqHeaders;
+  map<string, string> m_respHeaders;
+  string m_rootPath;
+  string m_path;
+  int m_errc; //Response code
+  
+//*  Timeout m_watchdog;
+//*  int m_timeout;
+  
+  bool m_closed;
+  bool m_headersSent;
+  
+  int readLine(char* str, int maxLen);
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPServer.h	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,244 @@
+#ifndef HTTP_SERVER_H
+#define HTTP_SERVER_H
+
+#include <string>
+using std::string;
+
+#include <map>
+using std::map;
+
+#include "HTTPRequestHandler.h"
+#include "rtos.h"
+#include "mbed.h"
+#include "EthernetInterface.h"
+//#include "HTTPRequestDispatcher.h"
+
+//#include "dbg/dbg.h"
+
+#define THREAD_MAX 5
+Thread *threads[THREAD_MAX];
+Thread *xthread;
+//#include "HTTPServer2.h"
+
+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));
+    }
+};
+
+map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocketConnection* ), handlersComp > m_lpHandlers;
+template<typename T>
+void HTTPServerAddHandler(const char* path)  //Template decl in header
+{
+    m_lpHandlers[path] = &T::inst;
+}
+
+void ListenThread(void const *args);
+//DigitalOut _led(LED4);
+//bool serverIsListened;
+//bool clientIsConnected;
+enum HTTP_METH {
+    HTTP_GET,
+    HTTP_POST,
+    HTTP_HEAD
+};
+
+bool getRequest(TCPSocketConnection* client,string* path, string* meth)
+{
+    char req[128];
+    char c_path[128];
+    char c_meth[128];
+    const int maxLen = 128;
+    char* p = req;
+    //Read Line
+    int ret;
+    int len = 0;
+    for(int i = 0; i < maxLen - 1; i++) {
+        ret = client->receive(p, 1);
+        if(!ret) {
+            break;
+        }
+        if( (len > 1) && *(p-1)=='\r' && *p=='\n' ) {
+            p--;
+            len-=2;
+            break;
+        } else if( *p=='\n' ) {
+            len--;
+            break;
+        }
+        p++;
+        len++;
+    }
+    *p = 0;
+
+    printf("Parsing request : %s\r\n", req);
+    ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path);
+    if(ret !=2)        return false;
+    *meth = string(c_meth);
+    *path = string(c_path);
+    return true;
+}
+
+void dispatchRequest(TCPSocketConnection* client)
+{
+    string path;
+    string meth;
+    HTTP_METH methCode;
+
+    printf("Dispatching req\r\n");
+
+    if( !getRequest(client,&path, &meth ) ) {
+        printf("dispatchRequest Invalid request\r\n");
+        //close();
+        return; //Invalid request
+    }
+    if( !meth.compare("GET") ) {
+        printf("dispatchRequest HTTP_GET\r\n");
+        methCode = HTTP_GET;
+    } else if( !meth.compare("POST") ) {
+        printf("dispatchRequest HTTP_POST\r\n");
+        methCode = HTTP_POST;
+    } else if( !meth.compare("HEAD") ) {
+        printf("dispatchRequest HTTP_HEAD\r\n");
+        methCode = HTTP_HEAD;
+    } else {
+        printf("dispatchRequest() Parse error\r\n");
+        //close(); //Parse error
+        return;
+    }
+    
+    printf("Looking for a handler\r\n");
+    map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocketConnection*) >::iterator it;
+    int root_len = 0;
+    for (it = m_lpHandlers.begin(); it != m_lpHandlers.end(); it++) {
+        printf("Checking %s...\r\n", (*it).first.c_str());
+        root_len = (*it).first.length();
+        if ( root_len &&
+                !path.compare( 0, root_len, (*it).first ) &&
+                (path[root_len] == '/' || path[root_len] == '\0')) {
+            printf("Found (%s)\r\n", (*it).first.c_str());
+            // Found!
+            break;  // for
+        }
+    }
+    if((it == m_lpHandlers.end()) && !(m_lpHandlers.empty())) {
+        printf("Using default handler\r\n");
+        it = m_lpHandlers.end();
+        it--; //Get the last element
+        if( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler
+            it = m_lpHandlers.end();
+        root_len = 0;
+    }
+    if(it == m_lpHandlers.end()) {
+        printf("No handler found\r\n");
+        return;
+    }
+    printf("Handler found.\r\n");
+   
+    HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, client);
+    //****  client = NULL; //We don't own it anymore
+    switch(methCode) {
+        case HTTP_GET:
+            pHdlr->doGet();
+            break;
+        case HTTP_POST:
+            pHdlr->doPost();
+            break;
+        case HTTP_HEAD:
+            pHdlr->doHead();
+            break;
+    }
+    delete pHdlr;
+   // delete client;
+   // delete m_pTCPSocketConnection;
+   printf("(dispatcherRequest)return\r\n");
+   return ;
+}
+
+void HTTPServerChild (void const *arg)
+{
+    printf("HTTPServerChiled Start......\r\n");
+    TCPSocketConnection* client = (TCPSocketConnection*)arg;
+
+    for (;;) {
+        printf("(HTTPServer.h<HTTPServerChild>)Connection from %s\r\n", client->get_address());
+        dispatchRequest(client);
+        printf("(HTTPServer.h<HTTPServerChild>)Close %s\r\n", client->get_address());
+        client->close();
+        client->reset_address();
+        //delete client;
+        Thread::signal_wait(1);
+    }
+}
+
+void HTTPServerCloser (void const *arg)
+{
+    TCPSocketConnection *client = (TCPSocketConnection*)arg;
+
+    for (;;) {
+        client->close();
+        printf("Close %s\r\n", client->get_address());
+        Thread::signal_wait(1);
+    }
+}
+
+void HTTPServerStart(int port = 80)
+{
+    int i, t = 0;
+    TCPSocketConnection clients[THREAD_MAX];
+    TCPSocketConnection xclient;
+
+    for (i = 0; i < THREAD_MAX; i ++) {
+        threads[i] = NULL;
+    }
+    xthread = NULL;
+
+    TCPSocketServer server;
+    server.bind(port);
+    server.listen();
+   // server.set_blocking(false);
+    printf("Wait for new connection...\r\n");
+    for (;;) {
+        printf("**Start Loop** \r\n");
+        if (t >= 0) {
+            if(server.accept(clients[t])==0) {
+                // fork child process
+                if (threads[t]) {
+                    threads[t]->signal_set(1);
+                } else {
+                    threads[t] = new Thread(HTTPServerChild, (void*)&clients[t]);
+                }
+                printf("Forked %d\r\n", t);
+            }
+        } else {
+            if(server.accept(xclient)==0) {
+                // closer process
+                if (xthread) {
+                    xthread->signal_set(1);
+                } else {
+                    xthread = new Thread(HTTPServerCloser, (void*)&xclient);
+                }
+                printf("Connection full\r\n");
+            }
+        }
+
+        t = -1;
+        for (i = 0; i < THREAD_MAX; i ++) {
+            if (threads[i] == NULL || threads[i]->get_state() == Thread::WaitingAnd) {
+                if (t < 0) t = i; // next empty thread
+            }
+        }
+        Thread::wait(100);
+    }
+}
+#include "Handler/RPCHandler.h"
+#include "Handler/FSHandler.h"
+#include "Handler/SimpleHandler.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPServer.txt	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,186 @@
+
+/*
+Copyright (c) 2014 Yasushi TAUCHI
+
+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.
+*/
+#include "rtos.h"
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "HTTPRequestDispatcher.h"
+#include "HTTPServer2.h"
+
+#define THREAD_MAX 5
+Thread *threads[THREAD_MAX];
+Thread *xthread;
+
+
+
+//#define __DEBUG
+#include "dbg/dbg.h"
+void ListenThread(void const *args);
+DigitalOut _led(LED4);
+
+//class HTTPRequestDispatcher;
+//    TCPSocketServer TcpSocketServer;
+bool serverIsListened;
+//    TCPSocketConnection client;
+bool clientIsConnected;
+void onTCPSocketEvent(/**TCPSocketEvent e**/);
+/**
+map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocketConnection* ), handlersComp > m_lpHandlers;
+template<typename T>
+void HTTPServerAddHandler(const char* path)  //Template decl in header
+{
+    m_lpHandlers[path] = &T::inst;
+}
+**/
+//*  TCPSocket* m_pTCPSocket;
+//map< string, HTTPRequestHandler*(*)(const char*, const char* /**, TCPSocket* **/), handlersComp > m_lpHandlers;
+/**
+template<typename T>
+void HTTPServerAddHandler(const char* path)   //Template decl in header
+{
+    m_lpHandlers[path] = &T::inst;
+}
+**/
+void HTTPServerChild (void const *arg)
+{
+    int i;
+    char buf[256];
+    TCPSocketConnection* client = (TCPSocketConnection*)arg;
+
+    for (;;) {
+        printf("Connection from %s\r\n", client->get_address());
+//        client->set_blocking(false, 1500); // Timeout after (1.5)s
+//        printf("\r\nHTTPServer::onTCPSocketEvent : Event %d\r\n", e);
+        //TCPSocket* pTCPSocket;
+        //Host client;
+
+//        if( !!m_pTCPSocket->accept(&client, &pTCPSocket) )
+        //      {
+        //      DBG("\r\nHTTPServer::onTCPSocketEvent : Could not accept connection.\r\n");
+        //     return; //Error in accept, discard connection
+        //     }
+
+        //     HTTPRequestDispatcher* pDispatcher = new HTTPRequestDispatcher(this, client); //TCPSocket ownership is passed to dispatcher
+        HTTPRequestDispatcher* pDispatcher ;
+        pDispatcher= new HTTPRequestDispatcher(m_lpHandlers,client); //TCPSocket ownership is passed to dispatcher
+        //The dispatcher object will destroy itself when done, or will be destroyed on Server destruction
+
+        /**
+                for (;;) {
+                    i = client->receive(buf, sizeof(buf));
+                    if (i < 0) break;
+                    if (i == 0) continue;
+                    buf[i] = 0;
+                    printf("Recv '%s'\r\n", buf);
+                    if (client->send(buf, i) < 0) break;
+                }
+        **/
+        delete pDispatcher;
+        client->close();
+        printf("Close %s\r\n", client->get_address());
+
+        Thread::signal_wait(1);
+    }
+}
+
+void HTTPServerCloser (void const *arg)
+{
+    TCPSocketConnection *client = (TCPSocketConnection*)arg;
+
+    for (;;) {
+        client->close();
+        printf("Close %s\r\n", client->get_address());
+
+        Thread::signal_wait(1);
+    }
+}
+
+void HTTPServerStart(int port /*= 80*/)
+{
+    int i, t = 0;
+    TCPSocketConnection clients[THREAD_MAX];
+    TCPSocketConnection xclient;
+
+    for (i = 0; i < THREAD_MAX; i ++) {
+        threads[i] = NULL;
+    }
+    xthread = NULL;
+
+    TCPSocketServer server;
+    server.bind(port);
+    server.listen();
+
+    printf("Wait for new connection...\r\n");
+    for (;;) {
+        if (t >= 0) {
+            server.accept(clients[t]);
+            // fork child process
+            if (threads[t]) {
+                threads[t]->signal_set(1);
+            } else {
+                threads[t] = new Thread(HTTPServerChild, (void*)&clients[t]);
+            }
+            printf("Forked %d\r\n", t);
+        } else {
+            server.accept(xclient);
+            // closer process
+            if (xthread) {
+                xthread->signal_set(1);
+            } else {
+                xthread = new Thread(HTTPServerCloser, (void*)&xclient);
+            }
+            printf("Connection full\r\n");
+        }
+
+        t = -1;
+        for (i = 0; i < THREAD_MAX; i ++) {
+            if (threads[i] == NULL || threads[i]->get_state() == Thread::WaitingAnd) {
+                if (t < 0) t = i; // next empty thread
+            }
+        }
+    }
+}
+
+//void HTTPServer::onTCPSocketEvent(/**TCPSocketEvent e**/)
+/**
+void HTTPServerOnTCPSocketEvent(TCPSocketEvent e)
+{
+
+    DBG("\r\nHTTPServer::onTCPSocketEvent : Event %d\r\n", e);
+      if(e==TCPSOCKET_ACCEPT)
+      {
+        TCPSocket* pTCPSocket;
+        Host client;
+
+        if( !!m_pTCPSocket->accept(&client, &pTCPSocket) )
+        {
+          DBG("\r\nHTTPServer::onTCPSocketEvent : Could not accept connection.\r\n");
+          return; //Error in accept, discard connection
+        }
+
+        HTTPRequestDispatcher* pDispatcher = new HTTPRequestDispatcher(this, pTCPSocket); //TCPSocket ownership is passed to dispatcher
+        //The dispatcher object will destroy itself when done, or will be destroyed on Server destruction
+
+      }
+}
+     **/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPServer2.h	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,109 @@
+/*
+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.
+*/
+
+/** \file
+HTTP Server header file
+*/
+
+#ifndef HTTP_SERVER_2_H
+#define HTTP_SERVER_2_H
+
+//class HTTPRequestHandler;
+//class HTTPRequestDispatcher;
+
+//*#include "core/net.h"
+#include "HTTPRequestHandler.h"
+#include "HTTPRequestDispatcher.h"
+#include "EthernetInterface.h"
+
+#include <string>
+using std::string;
+
+#include <map>
+using std::map;
+
+
+///A simple HTTP server implementation
+/**
+The HTTPServer is composed of:
+- The actual server (HTTPServer)
+- A request dispatcher, instanciated on each request (HTTPRequestDispatcher)
+- Request handlers instanciated by the dispatcher(deriving from HTTPRequestHandler)
+*/
+//class HTTPServer
+//{
+//public:
+//    ///Instantiates the HTTP Server
+//    HTTPServer();
+//    ~HTTPServer();
+
+
+///Adds a handler
+/**
+Appends a handler to the handlers list
+@param T : class which will be instanciated to serve these requests
+@param path : requests starting with this path will be served using this handler
+*/
+
+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));
+    }
+};
+
+/*
+template<typename T>
+void HTTPServerAddHandler(const char* path)  //Template decl in header
+{
+    m_lpHandlers[path] = &T::inst;
+}
+*/
+
+//map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocketConnection* ), handlersComp > m_lpHandlers;
+/**
+template<typename T>
+void HTTPServerAddHandler(const char* path)  //Template decl in header
+{
+    m_lpHandlers[path] = &T::inst;
+}
+**/
+///Starts listening
+/**
+Binds server to a specific port and starts listening
+@param port : port on which to listen for incoming connections
+*/
+
+
+
+//};
+
+//Including handlers here for more convenience
+#include "Handler/RPCHandler.h"
+#include "Handler/FSHandler.h"
+#include "Handler/SimpleHandler.h"
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/FSHandler.cpp	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,161 @@
+/*
+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.
+*/
+
+#include "FSHandler.h"
+
+//#define __DEBUG
+//#include "dbg/dbg.h"
+
+#define CHUNK_SIZE 128
+
+#define DEFAULT_PAGE "/index.htm"
+
+//*FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : HTTPRequestHandler(rootPath, path, pTCPSocket), m_err404(false)
+FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) : HTTPRequestHandler(rootPath, path, pTCPSocketConnection), m_err404(false)
+{}
+
+FSHandler::~FSHandler()
+{
+  if(m_fp)
+    fclose(m_fp);
+  printf("\r\nHandler destroyed\r\n");
+}
+
+//static init
+map<string,string> FSHandler::m_lFsPath = map<string,string>();
+
+void FSHandler::mount(const string& fsPath, const string& rootPath)
+{
+  m_lFsPath[rootPath]=fsPath;
+}
+
+void FSHandler::doGet()
+{
+  printf("\r\nIn FSHandler::doGet() - rootPath=%s, path=%s\r\n", rootPath().c_str(), path().c_str());
+  //FIXME: Translate path to local/path
+  string checkedRootPath = rootPath();
+  if(checkedRootPath.empty())
+    checkedRootPath="/";
+  string filePath = m_lFsPath[checkedRootPath];
+  if (path().size() > 1)
+  {
+    filePath += path();
+  }
+  else
+  {
+    filePath += DEFAULT_PAGE;
+  }
+  
+  printf("Trying to open %s\n", filePath.c_str());
+
+  m_fp = fopen(filePath.c_str(), "r"); //FIXME: if null, error 404
+  
+  if(!m_fp)
+  {
+    m_err404 = true;
+    setErrCode(404);
+    const char* msg = "File not found.";
+    setContentLen(strlen(msg));
+    respHeaders()["Content-Type"] = "text/html";
+    respHeaders()["Connection"] = "close";
+    writeData(msg,strlen(msg)); //Only send header
+    printf("\r\nExit FSHandler::doGet() w Error 404\r\n");
+    return;
+  }
+    
+  //Seek EOF to get length
+  fseek(m_fp, 0, SEEK_END);
+  setContentLen( ftell(m_fp) );
+  fseek(m_fp, 0, SEEK_SET); //Goto SOF
+
+  respHeaders()["Connection"] = "close";
+  onWriteable();
+  printf("\r\nExit SimpleHandler::doGet()\r\n");
+}
+
+void FSHandler::doPost()
+{
+
+}
+
+void FSHandler::doHead()
+{
+
+}
+
+void FSHandler::onReadable() //Data has been read
+{
+
+}
+
+void FSHandler::onWriteable() //Data has been written & buf is free
+{
+  printf("\r\nFSHandler::onWriteable() event\r\n");
+  if(m_err404)
+  {
+    //Error has been served, now exit
+    close();
+    return;
+  }
+  
+  static char rBuf[CHUNK_SIZE];
+  while(true)
+  {
+    int len = fread(rBuf, 1, CHUNK_SIZE, m_fp);
+    if(len>0)
+    {
+      int writtenLen = writeData(rBuf, len);
+      if(writtenLen < 0) //Socket error
+      {
+        printf("FSHandler: Socket error %d\n", writtenLen);
+        /**
+        if(writtenLen == TCPSOCKET_MEM)
+        {
+          fseek(m_fp, -len, SEEK_CUR);
+          return; //Wait for the queued TCP segments to be transmitted
+        }
+        else
+        {
+          //This is a critical error
+          close();
+          return; 
+        }
+        **/
+      }
+      else if(writtenLen < len) //Short write, socket's buffer is full
+      {
+        fseek(m_fp, writtenLen - len, SEEK_CUR);
+        return;
+      }
+    }
+    else
+    {
+      close(); //Data written, we can close the connection
+      return;
+    }
+  }
+}
+
+void FSHandler::onClose() //Connection is closing
+{
+  if(m_fp)
+    fclose(m_fp);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/FSHandler.h	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,58 @@
+/*
+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 FS_HANDLER_H
+#define FS_HANDLER_H
+
+#include "../HTTPRequestHandler.h"
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include <map>
+using std::map;
+
+#include <string>
+using std::string;
+
+class FSHandler : public HTTPRequestHandler
+{
+public:
+  FSHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection);
+  virtual ~FSHandler();
+  
+  static void mount(const string& fsPath, const string& rootPath);
+
+//protected:
+ static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) { return new FSHandler(rootPath, path, pTCPSocketConnection); } //if we ever could do static virtual functions, this would be one
+
+  virtual void doGet();
+  virtual void doPost();
+  virtual void doHead();
+  
+  virtual void onReadable(); //Data has been read
+  virtual void onWriteable(); //Data has been written & buf is free
+  virtual void onClose(); //Connection is closing
+  
+private:
+  FILE* m_fp;
+  bool m_err404;
+  static map<string,string> m_lFsPath;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/RPCHandler.cpp	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,111 @@
+/*
+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.
+*/
+
+#include "RPCHandler.h"
+#include "rpc.h"
+
+//#define __DEBUG
+//#include "dbg/dbg.h"
+
+#define RPC_DATA_LEN 128
+
+RPCHandler::RPCHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) : HTTPRequestHandler(rootPath, path, pTCPSocketConnection)
+{}
+
+RPCHandler::~RPCHandler()
+{
+  printf("\r\nHandler destroyed\r\n");
+}
+
+void RPCHandler::doGet()
+{
+  printf("\r\nIn RPCHandler::doGet()\r\n");
+  char resp[RPC_DATA_LEN] = {0};
+  char req[RPC_DATA_LEN] = {0};
+  
+  printf("\r\nPath : %s\r\n", path().c_str());
+  printf("\r\nRoot Path : %s\r\n", rootPath().c_str());
+  
+  //Remove path
+  strncpy(req, path().c_str(), RPC_DATA_LEN-1);
+  printf("\r\nRPC req : %s\r\n", req);
+  
+  //Remove %20, +, from req
+  cleanReq(req);
+  printf("\r\nRPC req : %s\r\n", req);
+  
+  //Do RPC Call
+ //* mbed::rpc(req, resp); //FIXME: Use bool result
+  
+  //Response
+  setContentLen( strlen(resp) );
+  
+  //Make sure that the browser won't cache this request
+  respHeaders()["Cache-control"]="no-cache;no-store";
+ // respHeaders()["Cache-control"]="no-store";
+  respHeaders()["Pragma"]="no-cache";
+  respHeaders()["Expires"]="0";
+  
+  //Write data
+  respHeaders()["Connection"] = "close";
+  writeData(resp, strlen(resp));
+  printf("\r\nExit RPCHandler::doGet()\r\n");
+}
+
+void RPCHandler::doPost()
+{
+
+}
+
+void RPCHandler::doHead()
+{
+
+}
+
+  
+void RPCHandler::onReadable() //Data has been read
+{
+
+}
+
+void RPCHandler::onWriteable() //Data has been written & buf is free
+{
+  printf("\r\nRPCHandler::onWriteable() event\r\n");
+  close(); //Data written, we can close the connection
+}
+
+void RPCHandler::onClose() //Connection is closing
+{
+  //Nothing to do
+}
+
+void RPCHandler::cleanReq(char* data)
+{
+  char* p;
+  static const char* lGarbage[2] = {"%20", "+"};
+  for(int i = 0; i < 2; i++)
+  {
+    while( p = strstr(data, lGarbage[i]) )
+    {
+      memset((void*) p, ' ', strlen(lGarbage[i]));
+    }
+  }
+}
+  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/RPCHandler.h	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,51 @@
+
+/*
+Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+ 
+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 RPC_HANDLER_H
+#define RPC_HANDLER_H
+
+#include "../HTTPRequestHandler.h"
+
+class RPCHandler : public HTTPRequestHandler
+{
+public:
+  RPCHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection);
+  virtual ~RPCHandler();
+
+//protected:
+  static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) { return new RPCHandler(rootPath, path, pTCPSocketConnection); } //if we ever could do static virtual functions, this would be one
+
+  virtual void doGet();
+  virtual void doPost();
+  virtual void doHead();
+  
+  virtual void onReadable(); //Data has been read
+  virtual void onWriteable(); //Data has been written & buf is free
+  virtual void onClose(); //Connection is closing
+
+protected:
+  void cleanReq(char* data);
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/SimpleHandler.cpp	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,74 @@
+
+/*
+Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+ 
+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.
+*/
+
+#include "SimpleHandler.h"
+
+//#define __DEBUG
+//#include "dbg/dbg.h"
+
+SimpleHandler::SimpleHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) : HTTPRequestHandler(rootPath, path, pTCPSocketConnection)
+{
+    printf("++++(SimpleHeader)Initialize\r\n");
+}
+
+SimpleHandler::~SimpleHandler()
+{
+  printf("++++(SimpleHeader)Handler destroyed\r\n");
+}
+
+void SimpleHandler::doGet()
+{
+  printf("++++(SimpleHeader) doGet()\r\n");
+  const char* resp = "Hello world !";
+  setContentLen( strlen(resp) );
+  respHeaders()["Connection"] = "close";
+  writeData(resp, strlen(resp));
+  printf("++++(SimpleHeader) doGet Exit\r\n");
+}
+
+void SimpleHandler::doPost()
+{
+
+}
+
+void SimpleHandler::doHead()
+{
+
+}
+
+  
+void SimpleHandler::onReadable() //Data has been read
+{
+
+}
+
+void SimpleHandler::onWriteable() //Data has been written & buf is free
+{
+  printf("\r\n++++SimpleHandler::onWriteable() event\r\n");
+  close(); //Data written, we can close the connection
+}
+
+void SimpleHandler::onClose() //Connection is closing
+{
+  //Nothing to do
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/SimpleHandler.h	Thu Feb 20 05:36:19 2014 +0000
@@ -0,0 +1,47 @@
+
+/*
+Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+ 
+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 SIMPLE_HANDLER_H
+#define SIMPLE_HANDLER_H
+
+#include "../HTTPRequestHandler.h"
+
+class SimpleHandler : public HTTPRequestHandler
+{
+public:
+  SimpleHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection);
+  virtual ~SimpleHandler();
+
+//protected:
+  static inline HTTPRequestHandler* inst(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) { return new SimpleHandler(rootPath, path, pTCPSocketConnection); } //if we ever could do static virtual functions, this would be one
+
+  virtual void doGet();
+  virtual void doPost();
+  virtual void doHead();
+  
+  virtual void onReadable(); //Data has been read
+  virtual void onWriteable(); //Data has been written & buf is free
+  virtual void onClose(); //Connection is closing
+};
+
+#endif