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

Dependents:   Smart-WiFly-WebServer WattEye X10Svr SSDP_Server

Revision:
39:0427544a5c08
Parent:
38:c8fa31e6fe02
Child:
40:02c49fadbb94
--- a/SW_HTTPServer.h	Sat Jul 26 19:49:13 2014 +0000
+++ b/SW_HTTPServer.h	Mon Sep 01 20:53:19 2014 +0000
@@ -2,9 +2,6 @@
 #ifndef SW_HTTPSERVER_H
 #define SW_HTTPSERVER_H
 #include "mbed.h"
-//#include "MODSERIAL.h"    // would like to hook in mod serial for higher performance, less blocking
-//#include "RawSerial.h"
-//#include "Wifly.h"
 #include "TCPSocketServer.h"
 #include "TCPSocketConnection.h"
 
@@ -28,7 +25,7 @@
 #define MAX_HEADER_SIZE 1000
 
 
-/// HTTPServer is a simple web server using the WiFly module.
+/// HTTPServer is a simple web server leveraging a network interface.
 ///
 /// While simple, it is a capable, web server. The basic mode
 /// of operation is for it to serve static web pages from an available
@@ -45,7 +42,7 @@
 /// or signaling outputs.
 ///
 /// @code
-///     HTTPServer svr(&wifly, HTTP_SERVER_PORT, "/local", 15, 30, 10, &pc);
+///     HTTPServer svr(HTTP_SERVER_PORT, "/local", 15, 30, 10, &pc);
 ///     svr.RegisterHandler("/dyn1", SimpleDynamicPage);
 ///     while (true)
 ///        {
@@ -56,9 +53,6 @@
 /// This web server used nweb as a starting point, but expanded well beyond there.
 ///  http://www.ibm.com/developerworks/systems/library/es-nweb/sidefile1.html
 ///
-/// @note This server uses a modified version of the mbed WiflyInterface - there
-/// were a number of performance issues identified and resolved in the local version.
-///
 /// Given: scheme://server:port/path?query_string#fragment_id
 /// @li scheme is "http"
 /// @li server is whatever IP the server has
@@ -77,17 +71,19 @@
 ///     depending on the actions being performed and can span hundreds of msec.
 ///
 /// Limitations:
-/// @li Supports only a single connection at a time.
-///     A web page with served objects (img src=...) is rarely served properly. It
-///       might trace to forcing the connection to close, but not yet sure.
-///       Explore "Set Uart Rx Data Buffer" in WiFly manual 2.3.65.
-///       This is a limitation of the Wifly module. No solution is forthcoming,
-///       so a simple workaround is to use javascript to load the images after
-///       the page loads.
+/// @li When used with Wifly network interface it supports only a single 
+///     connection at a time. A web page with served objects (img src=...) 
+///     is rarely served properly. It might trace to forcing the connection to 
+///     close, but not yet sure. Explore "Set Uart Rx Data Buffer" in
+///     WiFly manual 2.3.65. This is a limitation of the Wifly module. 
+///     No solution is forthcoming, so a crude workaround is to use javascript 
+///     to load the images after the page loads.
 /// @li Rapid requests for page objects (e.g. embedded images) are lost. Still
 ///     working to understand this issue.
 ///
 /// Improvements:
+/// @li removed the relationship to the Wifly module, which caused an API change
+///       in the constructor by elimination of the first parameter.
 /// @li hunted down several lengthy operations - the speed of the file system
 ///       and the "close" operation which requires <delay 0.25s>$$$<delay>close\r.
 /// @li parses the header similar to the query string, and then makes
@@ -230,7 +226,6 @@
     /**
     * Create the HTTPServer object.
     *
-    * @param wifly is the serial port with the wifly interface. This is not longer used.
     * @param port is the optional parameter for the port number to use, default is 80.
     * @param webroot is a file system path to the root folder for the web space. If any trailing '/'
     *        is included (e.g. "/web/path/") it will be removed (to "/web/path").
@@ -244,7 +239,7 @@
     * @param allocforfile is the memory allocation to support sending a file to the client. This is 
     *        typically sized to fit an ethernet frame.
     */
-    HTTPServer(void * wifly, int port = 80, const char * webroot = "/", int maxheaderParams = 15, 
+    HTTPServer(int port = 80, const char * webroot = "/", int maxheaderParams = 15, 
         int maxqueryParams = 30, int maxdynamicpages = 10,
         PC * pc = NULL, int _allocforheader = MAX_HEADER_SIZE, int _allocforfile = FILESEND_BUF_SIZE);
 
@@ -393,7 +388,7 @@
     const char * GetSupportedType(const char * filename);
 
     /**
-    * search the available parameters for 'name' and if found, return the 'value'
+    * search the available query parameters for 'name' and if found, return the 'value'
     *
     * After the querystring is parsed, the server maintains an array of
     * name=value pairs. This Get function will search for the passed in name
@@ -411,16 +406,73 @@
     const char * GetParameter(const char * name);
 
     /**
+    * get a pointer to a name-value pair based on the index.
+    *
+    * @param index is the item being referenced
+    * @return pointer to the namevalue, or NULL
+    */
+    namevalue * GetParameter(int index);
+
+    /**
+    * Get the count of query parameters from the active transaction.
+    *
+    * @returns count of parameters.
+    */
+    int GetParameterCount(void) 
+        {
+        return queryParamCount;
+        };
+    
+    /**
+    * search the available post parameters for 'name' and if found, return the 'value'
+    *
+    * After the post parameter string is parsed, the server maintains an array of
+    * name=value pairs. This Get function will search for the passed in name
+    * and provide access to the value.
+    *
+    * @code
+    * BusOut leds(LED1,LED2,LED3,LED4);
+    * ...
+    * leds = atoi(svr->GetPostParameter("leds"));
+    * @endcode
+    *
+    * @param name is the name to search for
+    * @return pointer to the value, or NULL
+    */
+    const char * GetPostParameter(const char * name);
+
+    /**
+    * get a pointer to a post parameter name-value pair based on the index.
+    *
+    * @param index is the item being referenced
+    * @return pointer to the namevalue, or NULL
+    */
+    namevalue * GetPostParameter(int index);
+
+    /**
+    * Get the count of post parameters from the active transaction.
+    *
+    * @returns count of parameters.
+    */
+    int GetPostParameterCount(void) 
+        {
+        return postParamCount;
+        };
+
+    /**
     * Parse the text string into name=value parameters.
     *
     * This will directly modify the referenced string. If there is a
     * #fragment_id on the end of the string, it will be removed.
     *
-    * @param pString is a pointer to the string.
+    * @param qP is a pointer to a namevalue set
+    * @param qpCount is a pointer to a counter of what is in the set
+    * @param maxP is the maximum number of parameters for which space has been allocated.
+    * @param pName is a pointer to the string.
     * @returns The total number of items that have been parsed, 
     *       which can include a count from a url query string.
     */
-    int ParseParameters(char * pString);
+    int ParseParameters(namevalue * qP, int * qpCount, int maxP, char * pName);
 
     /**
     * Unescape string converts a coded string "in place" into a normal string.
@@ -530,6 +582,10 @@
     int maxqueryParams;
     int queryParamCount;
     
+    namevalue *postParams;          // Same as Query params, but for post method
+    int maxPostParams;
+    int postParamCount;
+    
     namevalue *headerParams;    // Header params Host: 192.168...\r\nConnection: keep-alive\r\n...
     int maxheaderParams;
     int headerParamCount;
@@ -563,8 +619,8 @@
     int handlercount;
 
     char * queryType;
-    char * queryString;
-    char * postQueryString;
+    char * queryString;         // the query string [and 'GET' data] passed on the URL (e.g. ?name1=value1&name2=value2...)
+    char * postQueryString;     // the post data
 
     /**
     *  Extract the parameter from the record, by searching for the needle in the haystack.