Changed RPC sucessful execution code from 1 to 200. Included RpcHandler.h in main header file. Effectively allows RPC through HTTP.

Dependents:   RPC_HTTP RPC_HTTP_WIZnetInterface RPC_HTTP rpc_over_http_TL_interrupter_gatePJ

Fork of HTTPServer by Henry Leinen

Files at this revision

API Documentation at this revision

Comitter:
leihen
Date:
Wed Jun 05 23:39:24 2013 +0000
Parent:
11:3943841e1798
Child:
13:aa5338a5e452
Commit message:
Improved throughput of data.
; fixed incorrect Header handling.
; Fixed Support for other FileSystem Handler

Changed in this revision

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
Handler/FsHandler.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/HTTPRequestHandler.cpp	Sun Jun 02 22:59:51 2013 +0000
+++ b/HTTPRequestHandler.cpp	Wed Jun 05 23:39:24 2013 +0000
@@ -1,6 +1,7 @@
 /* HTTPRequestHandler.cpp */
 #include "mbed.h"
 #include "HTTPRequestHandler.h"
+#include <ctype.h>
 
 #define _DEBUG 0
 
@@ -20,21 +21,72 @@
 const char hdrDNT[] = "DNT: 1\r\n";
 const char hdrMaxAge[] = "MaxAge: 0\r\n";
 const char hdrConClose[] = "Connection: Keep-Alive\r\n";
+//const char hdrTrsfrEnc[] = "Transfer-Encoding: Chunked\r\n";
 const char hdrContent[] = "Content-Type: text/html\r\n";
 const char hdrServer[] = "Server: mbed embedded\r\n";
 const char hdrEndl[] = "\r\n";
 
+
+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"   }};
+    
 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;
@@ -107,6 +159,7 @@
         tcp.send_all((char*)hdrDNT, strlen(hdrDNT));
         tcp.send_all((char*)hdrMaxAge, strlen(hdrMaxAge));
         tcp.send_all((char*)hdrContent, strlen(hdrContent));
+//        tcp.send_all((char*)hdrTrsfrEnc, strlen(hdrTrsfrEnc));
         tcp.send_all((char*)hdrServer, strlen(hdrServer));
         tcp.send_all((char*)hdrEndl, strlen(hdrEndl));
     }
--- a/HTTPRequestHandler.h	Sun Jun 02 22:59:51 2013 +0000
+++ b/HTTPRequestHandler.h	Wed Jun 05 23:39:24 2013 +0000
@@ -132,6 +132,8 @@
         /** 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__
\ No newline at end of file
--- a/HTTPServer.cpp	Sun Jun 02 22:59:51 2013 +0000
+++ b/HTTPServer.cpp	Wed Jun 05 23:39:24 2013 +0000
@@ -164,7 +164,7 @@
             if (c == 0) {
                 //  Handle the request
                 HandleRequest(con.m_Msg, Clnt);
-                INFO("Closing connection.\n");
+//                INFO("Closing connection.\n");
 //                if (!m_wifly.close()) {
 //                    ERR("Failed to close connection !\n");
 //                }
--- a/Handler/FsHandler.cpp	Sun Jun 02 22:59:51 2013 +0000
+++ b/Handler/FsHandler.cpp	Wed Jun 05 23:39:24 2013 +0000
@@ -16,9 +16,17 @@
 #endif
 
 
-#define MAX_BUFFERSIZE  512
-static char buffer[MAX_BUFFERSIZE];
 
+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;
  
@@ -28,16 +36,29 @@
     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
-        if (m_rootPath.find( it->second ) == 0) {
-            m_rootPath = it->first;
-            break;
+        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();
 }
 
@@ -47,7 +68,14 @@
 
 int HTTPFsRequestHandler::handleGetRequest()
 {
-    INFO("Handling Get Request.");
+    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;
 
@@ -63,6 +91,15 @@
         
     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
@@ -72,11 +109,12 @@
     
         startResponse(200, size);
         while(!feof(fp) && !ferror(fp)) {
-            int cnt = fread(buffer, 1, MAX_BUFFERSIZE , fp);
+            int cnt = fread(pBuffer, 1, sz , fp);
             if (cnt < 0)
                 cnt = 0;
-            processResponse(cnt, buffer);
+            processResponse(cnt, pBuffer);
         }
+        delete pBuffer;
         endResponse();
         fclose(fp);
     }