A simple web server that can be bound to either the EthernetInterface or the WiflyInterface.

Dependents:   Smart-WiFly-WebServer WattEye X10Svr SSDP_Server

Revision:
59:9a71ac02c782
Parent:
58:5303e962f711
--- a/SW_HTTPServer.cpp	Sun Nov 18 04:04:16 2018 +0000
+++ b/SW_HTTPServer.cpp	Tue Feb 26 22:45:55 2019 +0000
@@ -13,7 +13,7 @@
 #include "mbed.h"
 #include "SW_String.h"      // Secure methods and others that were missing
 
-#define DEBUG "HTTP"
+//#define DEBUG "HTTP"
 #include <cstdio>
 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
 #define DBG(x, ...)  std::printf("[DBG %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
@@ -27,8 +27,6 @@
 #define INFO(x, ...)
 #endif
 
-extern void ShowSignOfLife(int which);
-
 #include "SW_HTTPServer.h"      // define DEBUG before this
 
 #define CHUNK_SIZE 1500     // max size of a single chunk (probably limited by Ethernet to 1500)
@@ -85,15 +83,16 @@
     {NULL, 0}
 };
 
-#if 0 && defined(DEBUG)
+#if 1 && defined(DEBUG)
 // Haven't learned anything from this in a long time, so disabled.
 // This uses standard library dynamic memory management, but for an
 // embedded system there are alternates that may make better sense -
 // search the web for embedded system malloc alternates.
-void * HTTPServer::MyMalloc(int x, int y)
+void * HTTPServer::MyMalloc(int Bytes, int LINE)
 {
-    pc->printf("[INF HTTP%4d] malloc(%d)\r\n", y, x);
-    return malloc(x);
+    void * pMem = malloc(Bytes);
+    pc->printf("[INF %s %4d] MyMalloc %p = malloc(%d)\r\n", DEBUG, LINE, pMem, Bytes);
+    return pMem;
 }
 char HTTPServer::toP(void * x)
 {
@@ -103,9 +102,11 @@
     else
         return '.';
 }
-#define mymalloc(x) MyMalloc(x, __LINE__)
+#define mymalloc(Bytes) MyMalloc(Bytes, __LINE__)
 #define myfree(x) \
-    pc->printf("[INF HTTP%4d] free(%02x %02x %02x %02x %02x ... %c%c%c%c%c)\r\n", __LINE__, \
+    pc->printf("[INF %s %4d] MyMalloc %p = free(%02x %02x %02x %02x %02x ... %c%c%c%c%c)\r\n", \
+        DEBUG, __LINE__, \
+        x, \
         *x, *(x+1), *(x+2), *(x+3), *(x+4), \
         toP(x), toP(x+1), toP(x+2), toP(x+3), toP(x+4) ); \
     free(x);
@@ -147,13 +148,14 @@
     postParamCount = 0;
     maxdynamicpages = _maxdynamicpages;
     handlers = (handler *)malloc(maxdynamicpages * sizeof(handler));
+    handlercount = 0;
+    ndxActiveHandler = -1;
     headerbuffersize = _allocforheader;
     headerbuffer = (char *)malloc(headerbuffersize);
     pc = _pc;
     queryType = NULL;
     queryString = NULL;
     postQueryString = NULL;
-    handlercount = 0;
     maxheaderbytes = 0;
     server = new TCPSocketServer();
     server->bind(port);
@@ -200,6 +202,14 @@
     }
 }
 
+const char * HTTPServer::GetActiveHandlerPath(void)
+{
+    if (ndxActiveHandler >= 0)
+        return handlers[ndxActiveHandler].path;
+    else
+        return NULL;
+}
+
 // Poll()
 //
 // *OPEN*GET /x=1 HTTP/1.1
@@ -239,7 +249,6 @@
             break;
 
         case Idle:
-            ShowSignOfLife(3);
             PerformanceTimer.reset();
             t_ref = (unsigned int)PerformanceTimer.read_us();
             bPtr = headerbuffer;
@@ -256,6 +265,7 @@
         case ReceivingHeader:
             n = client.receive(bPtr, headerbuffersize - (bPtr - headerbuffer));
             INFO("client.receive() returned %d, from %s", n, client.get_address());
+            INFO("  ReceivingHeader: %s", bPtr);
             if (n == -2) {
                 //   was hang here waiting ... op = Sending; which causes misses
                 op = WaitingToClose;
@@ -512,6 +522,12 @@
         return NULL;
 }
 
+int HTTPServer::ParsePostParameters(char * pPostString)
+{
+    return ParseParameters(postParams, &postParamCount, maxPostParams, pPostString);
+}
+
+
 // this=that&who=what&more=stuff...
 // ^   ^    ^
 int HTTPServer::ParseParameters(namevalue * qP, int * qpCount, int maxP, char * pName)
@@ -679,11 +695,12 @@
     bool regHandled = false;
 
     // If this queryString is in the list of registered handlers, call that
-    for (int i=0; i<handlercount; i++) {
-        if (strcmp(handlers[i].path, queryString) == 0) {
-            INFO("CheckDynamicHandlers - SEND_PAGE %s", handlers[i].path);
-            (*handlers[i].callback)(this, SEND_PAGE, queryString, queryParams, queryParamCount);
+    for (ndxActiveHandler=0; ndxActiveHandler<handlercount; ndxActiveHandler++) {
+        if (strcmp(handlers[ndxActiveHandler].path, queryString) == 0) {
+            INFO("CheckDynamicHandlers - SEND_PAGE %s", handlers[ndxActiveHandler].path);
+            (*handlers[ndxActiveHandler].callback)(this, SEND_PAGE, queryString, queryParams, queryParamCount);
             regHandled = true;
+            ndxActiveHandler = -1;
             break;      // we only execute the first one
         }
     }
@@ -727,6 +744,10 @@
     INFO("  SendResponse complete at                      %8u us", 
         (unsigned int)PerformanceTimer.read_us());
 
+    if (postQueryString) {
+        myfree(postQueryString);
+        postQueryString = NULL;
+    }
     if (queryType) {
         myfree(queryType);
         queryType = NULL;
@@ -735,10 +756,6 @@
         myfree(queryString);
         queryString = NULL;
     }
-    if (postQueryString) {
-        myfree(postQueryString);
-        postQueryString = NULL;
-    }
     INFO("  SendResponse free at                          %8u us", 
         (unsigned int)PerformanceTimer.read_us());
 }
@@ -890,7 +907,7 @@
                     dblCR += 4;     // There may be some after the double CR that we need
                     ttlCount = strlen(dblCR);
                     strcpy_s(postQueryString, CHUNK_SIZE, dblCR);
-                    //INFO("  {%s}", postQueryString);
+                    INFO("  {%s}", postQueryString);
                     while ((!postBytes || ttlCount < postBytes) && !escape) {
                         INFO("ttlCount: %d < postBytes: %d, of max chunk alloc %d", ttlCount, postBytes, CHUNK_SIZE);
                         len = client.receive(postQueryString + ttlCount, CHUNK_SIZE - ttlCount);
@@ -913,13 +930,14 @@
                             break;
                     }
                     //postParamCount = 0;
-                    //INFO("post: %s", postQueryString);
+                    INFO("post: %s", postQueryString);
                     //We're after the header, so there is "body" stuff which could be anything...
                     //but probably html or xml stuff...
                     //ParseParameters(postParams, &postParamCount, maxPostParams, postQueryString);
                     acceptIt = (*handlers[ndxHandler].callback)(this, DATA_TRANSFER, postQueryString, NULL, ttlCount);
-                    INFO("..processing exit");
+                    INFO("..processing exit [%d]", acceptIt);
                     acceptIt = (*handlers[ndxHandler].callback)(this, DATA_TRANSFER_END, NULL, NULL, 0);
+                    INFO("..transfer end[%d]", acceptIt);
                 } else {
                     ERR("attempt to allocate %d failed.", CHUNK_SIZE);
                 }