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

Dependents:   Smart-WiFly-WebServer WattEye X10Svr SSDP_Server

Committer:
WiredHome
Date:
Thu Sep 26 23:47:50 2013 +0000
Revision:
21:660143f20b04
Parent:
18:6199558632c0
Child:
22:55974de690c1
Child:
24:062431453abb
Making one API deprecated - the one which fetches the IP of the connected client. This is based on the WiflyInterface, and makes that more compatible with EthernetInterface.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 1:54353af0d20a 1
WiredHome 1:54353af0d20a 2 #ifndef SW_HTTPSERVER_H
WiredHome 1:54353af0d20a 3 #define SW_HTTPSERVER_H
WiredHome 1:54353af0d20a 4 #include "mbed.h"
WiredHome 1:54353af0d20a 5 //#include "MODSERIAL.h" // would like to hook in mod serial for higher performance, less blocking
WiredHome 1:54353af0d20a 6 #include "Wifly.h"
WiredHome 1:54353af0d20a 7 #include "TCPSocketServer.h"
WiredHome 1:54353af0d20a 8 #include "TCPSocketConnection.h"
WiredHome 1:54353af0d20a 9
WiredHome 1:54353af0d20a 10 #ifdef MODSERIAL_H
WiredHome 1:54353af0d20a 11 #define PC MODSERIAL
WiredHome 1:54353af0d20a 12 #else
WiredHome 1:54353af0d20a 13 #define PC Serial
WiredHome 1:54353af0d20a 14 #endif
WiredHome 1:54353af0d20a 15
WiredHome 9:2ea342765c9d 16 /// This is the default buffer size used to send files. You might size
WiredHome 9:2ea342765c9d 17 /// this to be equal or less than the payload size of 1460 bytes.
WiredHome 9:2ea342765c9d 18 /// See User Manual 3.6.1.
WiredHome 9:2ea342765c9d 19 #define FILESEND_BUF_SIZE 1460
WiredHome 3:17928786bdb5 20
WiredHome 3:17928786bdb5 21
WiredHome 12:109bf1558300 22 /// MAX_HEADER_SIZE is the default size to contain the largest header.
WiredHome 9:2ea342765c9d 23 /// This is the size of the URL and query string, and also all the
WiredHome 3:17928786bdb5 24 /// other header information about the client. This can be
WiredHome 12:109bf1558300 25 /// a couple of K, larger if you have big forms as it includes the
WiredHome 3:17928786bdb5 26 /// form data that is submitted.
WiredHome 3:17928786bdb5 27 #define MAX_HEADER_SIZE 1000
WiredHome 3:17928786bdb5 28
WiredHome 9:2ea342765c9d 29
WiredHome 21:660143f20b04 30 /// INCLUDE_GETREMOTE is used for backward compatibility, however
WiredHome 21:660143f20b04 31 /// this makes the server dependent on the WiFly module. By not
WiredHome 21:660143f20b04 32 /// defining this, the web server can be more readily adapted to
WiredHome 21:660143f20b04 33 /// a wired interface using EthernetInterface.
WiredHome 21:660143f20b04 34 //#define INCLUDE_GETREMOTE
WiredHome 21:660143f20b04 35
WiredHome 21:660143f20b04 36
WiredHome 1:54353af0d20a 37 /// HTTPServer is a simple web server using the WiFly module.
WiredHome 12:109bf1558300 38 ///
WiredHome 3:17928786bdb5 39 /// While simple, it is a capable, web server. The basic mode
WiredHome 3:17928786bdb5 40 /// of operation is for it to serve static web pages from an available
WiredHome 3:17928786bdb5 41 /// file system.
WiredHome 12:109bf1558300 42 ///
WiredHome 3:17928786bdb5 43 /// The default page is index.htm (compile time defined)
WiredHome 3:17928786bdb5 44 /// standard support to serve a number of standard file types;
WiredHome 3:17928786bdb5 45 /// gif, jpg, jpeg, ico, png, zip, gz, tar, txt, pdf, htm, html
WiredHome 3:17928786bdb5 46 /// (this list is also compile time defined)
WiredHome 3:17928786bdb5 47 ///
WiredHome 3:17928786bdb5 48 /// It can also serve dynamically generated pages, and therefore
WiredHome 3:17928786bdb5 49 /// respond to form submission. Through the dynamic interface it is
WiredHome 3:17928786bdb5 50 /// then quite easy to interact with the hardware, reading the inputs
WiredHome 3:17928786bdb5 51 /// or signaling outputs.
WiredHome 3:17928786bdb5 52 ///
WiredHome 3:17928786bdb5 53 /// @code
WiredHome 13:8975d7928678 54 /// HTTPServer svr(&wifly, HTTP_SERVER_PORT, "/local/", 15, 30, 10, &pc);
WiredHome 3:17928786bdb5 55 /// svr.RegisterHandler("/dyn1", SimpleDynamicPage);
WiredHome 3:17928786bdb5 56 /// while (true)
WiredHome 3:17928786bdb5 57 /// {
WiredHome 3:17928786bdb5 58 /// svr.Poll(); // this is non blocking process, but variable execution
WiredHome 3:17928786bdb5 59 /// }
WiredHome 3:17928786bdb5 60 /// @endcode
WiredHome 3:17928786bdb5 61 ///
WiredHome 3:17928786bdb5 62 /// This web server used nweb as a starting point, but expanded well beyond there.
WiredHome 0:729320f63c5c 63 /// http://www.ibm.com/developerworks/systems/library/es-nweb/sidefile1.html
WiredHome 0:729320f63c5c 64 ///
WiredHome 3:17928786bdb5 65 /// @note This server uses a modified version of the mbed WiflyInterface - there
WiredHome 3:17928786bdb5 66 /// were a number of performance issues identified and resolved in the local version.
WiredHome 0:729320f63c5c 67 ///
WiredHome 3:17928786bdb5 68 /// Given: scheme://server:port/path?query_string#fragment_id
WiredHome 0:729320f63c5c 69 /// @li scheme is "http"
WiredHome 3:17928786bdb5 70 /// @li server is whatever IP the server has
WiredHome 0:729320f63c5c 71 /// @li port is the registered port
WiredHome 0:729320f63c5c 72 /// @li /path is the reference to the file (actual or logical) on the server
WiredHome 0:729320f63c5c 73 /// @li query_string is any combination of name=value pairs
WiredHome 0:729320f63c5c 74 /// @li fragment_id is a reference to an anchor on the page
WiredHome 0:729320f63c5c 75 ///
WiredHome 3:17928786bdb5 76 /// Features:
WiredHome 3:17928786bdb5 77 /// @li Serves static pages from a file system. Many normal filetypes are
WiredHome 3:17928786bdb5 78 /// supported.
WiredHome 3:17928786bdb5 79 /// @li Compile time configurable for the "default" file, typically index.htm.
WiredHome 3:17928786bdb5 80 /// @li Provides a registration interface for dynamically generated pages that
WiredHome 3:17928786bdb5 81 /// can then interact with other hardware.
WiredHome 3:17928786bdb5 82 /// @li Revised to be Non-blocking, however the execution time is variable
WiredHome 7:99ad7a67f05e 83 /// depending on the actions being performed and can span hundreds of msec.
WiredHome 3:17928786bdb5 84 ///
WiredHome 3:17928786bdb5 85 /// Limitations:
WiredHome 3:17928786bdb5 86 /// @li Supports only a single connection at a time.
WiredHome 18:6199558632c0 87 /// A web page with served objects (img src=...) is rarely served properly. It
WiredHome 18:6199558632c0 88 /// might trace to forcing the connection to close, but not yet sure.
WiredHome 18:6199558632c0 89 /// Explore "Set Uart Rx Data Buffer" in WiFly manual 2.3.65.
WiredHome 18:6199558632c0 90 /// This is a limitation of the Wifly module. No solution is forthcoming,
WiredHome 18:6199558632c0 91 /// so a simple workaround is to use javascript to load the images after
WiredHome 18:6199558632c0 92 /// the page loads.
WiredHome 3:17928786bdb5 93 /// @li Rapid requests for page objects (e.g. embedded images) are lost. Still
WiredHome 3:17928786bdb5 94 /// working to understand this issue.
WiredHome 3:17928786bdb5 95 ///
WiredHome 18:6199558632c0 96 /// Improvements:
WiredHome 18:6199558632c0 97 /// @li hunted down several lengthy operations - the speed of the file system
WiredHome 18:6199558632c0 98 /// and the "close" operation which requires <delay 0.25s>$$$<delay>close\r.
WiredHome 18:6199558632c0 99 /// @li parses the header similar to the query string, and then makes
WiredHome 18:6199558632c0 100 /// those parameters accessible.
WiredHome 18:6199558632c0 101 /// @li Added basic password capability to dynamic web pages.
WiredHome 18:6199558632c0 102 ///
WiredHome 3:17928786bdb5 103 /// ToDo:
WiredHome 3:17928786bdb5 104 /// @li move part of the POST method handler to the registered handler, so
WiredHome 0:729320f63c5c 105 /// it can decide if it should allocate the needed memory.
WiredHome 3:17928786bdb5 106 /// @li transform the pc serial interface to a log interface, which might
WiredHome 0:729320f63c5c 107 /// be more useful.
WiredHome 3:17928786bdb5 108 /// @li Add ability to put WiFly in AP mode and then configuration pages
WiredHome 2:a29c32190037 109 /// to find and join a network.
WiredHome 3:17928786bdb5 110 /// @li Add ability to change/update SW in the WiFly module
WiredHome 3:17928786bdb5 111 /// @li Add ability to upload a new application to the mbed
WiredHome 2:a29c32190037 112 ///
WiredHome 2:a29c32190037 113 /// History:
WiredHome 2:a29c32190037 114 /// @li 20130530 Initial version
WiredHome 2:a29c32190037 115 /// @li 20130601 Renamed ip_process to Poll
WiredHome 3:17928786bdb5 116 /// @li 20130617 Cleaned up some of the documentation changes
WiredHome 3:17928786bdb5 117 /// @li 20130623 Make it non-blocking. "Poll" takes a variable amount
WiredHome 3:17928786bdb5 118 /// of time, based on whether it is idle, or how much it
WiredHome 3:17928786bdb5 119 /// has to do.
WiredHome 18:6199558632c0 120 /// @li 20130911 Lots of incremental changes along this way, this update
WiredHome 18:6199558632c0 121 /// refreshes the documentation.
WiredHome 0:729320f63c5c 122 ///
WiredHome 0:729320f63c5c 123 /// @note Copyright &copy; 2013 by Smartware Computing, all rights reserved.
WiredHome 0:729320f63c5c 124 /// Individuals may use this application for evaluation or non-commercial
WiredHome 0:729320f63c5c 125 /// purposes. Within this restriction, changes may be made to this application
WiredHome 0:729320f63c5c 126 /// as long as this copyright notice is retained. The user shall make
WiredHome 0:729320f63c5c 127 /// clear that their work is a derived work, and not the original.
WiredHome 0:729320f63c5c 128 /// Users of this application and sources accept this application "as is" and
WiredHome 0:729320f63c5c 129 /// shall hold harmless Smartware Computing, for any undesired results while
WiredHome 0:729320f63c5c 130 /// using this application - whether real or imagined.
WiredHome 0:729320f63c5c 131 ///
WiredHome 0:729320f63c5c 132 /// @author David Smart, Smartware Computing
WiredHome 0:729320f63c5c 133 ///
WiredHome 0:729320f63c5c 134 class HTTPServer
WiredHome 0:729320f63c5c 135 {
WiredHome 0:729320f63c5c 136 public:
WiredHome 0:729320f63c5c 137 /**
WiredHome 3:17928786bdb5 138 * name-value pairs for parameters
WiredHome 0:729320f63c5c 139 */
WiredHome 3:17928786bdb5 140 typedef struct NAMEVALUE {
WiredHome 0:729320f63c5c 141 char * name;
WiredHome 0:729320f63c5c 142 char * value;
WiredHome 0:729320f63c5c 143 } namevalue;
WiredHome 12:109bf1558300 144
WiredHome 2:a29c32190037 145 /**
WiredHome 3:17928786bdb5 146 * Indicates the purpose of the Handler callback
WiredHome 3:17928786bdb5 147 *
WiredHome 12:109bf1558300 148 * Application code in a dynamic page uses this to determine the state
WiredHome 3:17928786bdb5 149 * and therefore the needed operation to be performed.
WiredHome 3:17928786bdb5 150 *
WiredHome 3:17928786bdb5 151 * @code
WiredHome 13:8975d7928678 152 * bool SimpleDynamicPage(HTTPServer *svr, HTTPServer::CallBackType type,
WiredHome 13:8975d7928678 153 * const char * path, const HTTPServer::namevalue *queryParams,
WiredHome 13:8975d7928678 154 * int queryParamCount) {
WiredHome 3:17928786bdb5 155 * char buf[100];
WiredHome 3:17928786bdb5 156 * bool ret = false;
WiredHome 12:109bf1558300 157 *
WiredHome 3:17928786bdb5 158 * switch (type) {
WiredHome 3:17928786bdb5 159 * case HTTPServer::SEND_PAGE:
WiredHome 3:17928786bdb5 160 * svr->header(200, "OK", "Content-Type: text/html\r\n");
WiredHome 3:17928786bdb5 161 * svr->send("<html><head><title>Dynamic Page</title></head>\r\n");
WiredHome 3:17928786bdb5 162 * svr->send("<body>\r\n");
WiredHome 3:17928786bdb5 163 * svr->send("This page was generated dynamically. Create your own name=value pairs on the URL "
WiredHome 3:17928786bdb5 164 * "which uses the GET method.<br/>\r\n");
WiredHome 13:8975d7928678 165 * sprintf(buf, "%d parameters passed to {%s}:<br/>\r\n", queryParamCount, path);
WiredHome 3:17928786bdb5 166 * svr->send(buf);
WiredHome 13:8975d7928678 167 * for (int i=0; i<queryParamCount; i++) {
WiredHome 13:8975d7928678 168 * sprintf(buf, "%d: %s = %s<br/>\r\n", i, queryParams[i].name, queryParams[i].value);
WiredHome 3:17928786bdb5 169 * svr->send(buf);
WiredHome 3:17928786bdb5 170 * }
WiredHome 3:17928786bdb5 171 * svr->send("<br/><a href='/'>back to main</a></body></html>\r\n");
WiredHome 3:17928786bdb5 172 * ret = true;
WiredHome 3:17928786bdb5 173 * break;
WiredHome 3:17928786bdb5 174 * case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 3:17928786bdb5 175 * ret = true;
WiredHome 3:17928786bdb5 176 * break;
WiredHome 3:17928786bdb5 177 * case HTTPServer::DATA_TRANSFER:
WiredHome 3:17928786bdb5 178 * ret = true;
WiredHome 3:17928786bdb5 179 * break;
WiredHome 3:17928786bdb5 180 * default:
WiredHome 3:17928786bdb5 181 * ret = false;
WiredHome 3:17928786bdb5 182 * break;
WiredHome 3:17928786bdb5 183 * }
WiredHome 3:17928786bdb5 184 * return ret;
WiredHome 3:17928786bdb5 185 * }
WiredHome 3:17928786bdb5 186 * @endcode
WiredHome 2:a29c32190037 187 */
WiredHome 3:17928786bdb5 188 typedef enum CALLBACKTYPE {
WiredHome 14:19c5f6151319 189 CONTENT_LENGTH_REQUEST, ///< ask the client if they wish to accept the data, typically from a POST event
WiredHome 3:17928786bdb5 190 DATA_TRANSFER, ///< not currently used, may allow "chunking" the data to the client
WiredHome 3:17928786bdb5 191 SEND_PAGE, ///< the activated method should now send the page
WiredHome 2:a29c32190037 192 } CallBackType;
WiredHome 0:729320f63c5c 193
WiredHome 12:109bf1558300 194 /**
WiredHome 3:17928786bdb5 195 * This is the prototype for custom handlers that are activated via a callback
WiredHome 0:729320f63c5c 196 *
WiredHome 3:17928786bdb5 197 * This callback gets overloaded for a few purposes, which can be identified by the \see CallBackType parameter
WiredHome 12:109bf1558300 198 * @li SEND_PAGE - the callback should now send the html page, using as many svr->send() as needed.
WiredHome 2:a29c32190037 199 * When the callback returns, it should always indicate true.
WiredHome 2:a29c32190037 200 * @li CONTENT_LENGTH_REQUEST - the server is asking the callback if it wants to receive the message,
WiredHome 2:a29c32190037 201 * which may require significant memory. If the request is accepted, true should be returned.
WiredHome 2:a29c32190037 202 * If the request is denied, false should be returned.
WiredHome 12:109bf1558300 203 *
WiredHome 0:729320f63c5c 204 * @param svr is a handle to this class, so the callback has access to member functions
WiredHome 13:8975d7928678 205 * @param queryParams is a pointer to an array of name value pairs
WiredHome 13:8975d7928678 206 * @queryParamCount is the number of parameters.
WiredHome 2:a29c32190037 207 * @return true if command was accepted
WiredHome 0:729320f63c5c 208 */
WiredHome 13:8975d7928678 209 typedef bool (* Handler)(HTTPServer * svr, CallBackType type, const char *path, const namevalue *queryParams, int queryParamCount);
WiredHome 12:109bf1558300 210
WiredHome 0:729320f63c5c 211 /**
WiredHome 0:729320f63c5c 212 * Create the HTTPServer object.
WiredHome 12:109bf1558300 213 *
WiredHome 0:729320f63c5c 214 * @param wifly is the serial port with the wifly interface.
WiredHome 0:729320f63c5c 215 * @param port is the optional parameter for the port number to use, default is 80.
WiredHome 0:729320f63c5c 216 * @param webroot is a file system path to the root folder for the web space.
WiredHome 13:8975d7928678 217 * @param maxheaderParams defines the maximum number of parameters to extract from a header (Host: 192..\r\nConnection: keep-alive\r\n...)
WiredHome 13:8975d7928678 218 * @param maxqueryParams defines the maximum number of query parameters to a dynamic function (and the memory to support them).
WiredHome 0:729320f63c5c 219 * @param maxdynamicpages defines the maximum number of dynamic pages that can be registered.
WiredHome 0:729320f63c5c 220 * @param pc is the serial port for debug information (I should transform this to a log interface)
WiredHome 3:17928786bdb5 221 * @param allocforheader is the memory allocation to support the largest expected header from a client
WiredHome 12:109bf1558300 222 * @param allocforfile is the memory allocation to support sending a file to the client. This is typically sized to fit
WiredHome 3:17928786bdb5 223 * an ethernet frame.
WiredHome 0:729320f63c5c 224 */
WiredHome 13:8975d7928678 225 HTTPServer(Wifly * wifly, int port = 80, const char * webroot = "/", int maxheaderParams = 15, int maxqueryParams = 30, int maxdynamicpages = 10,
WiredHome 12:109bf1558300 226 PC * pc = NULL, int _allocforheader = MAX_HEADER_SIZE, int _allocforfile = FILESEND_BUF_SIZE);
WiredHome 12:109bf1558300 227
WiredHome 0:729320f63c5c 228 /**
WiredHome 3:17928786bdb5 229 * Destructor, which can clean up memory.
WiredHome 0:729320f63c5c 230 */
WiredHome 0:729320f63c5c 231 ~HTTPServer();
WiredHome 12:109bf1558300 232
WiredHome 0:729320f63c5c 233 /**
WiredHome 3:17928786bdb5 234 * The process to call whenever there is free time, as this basically does
WiredHome 0:729320f63c5c 235 * all the work to monitor for connections and handle replies.
WiredHome 2:a29c32190037 236 *
WiredHome 2:a29c32190037 237 * 20130601 Renamed from ip_process to Poll
WiredHome 0:729320f63c5c 238 */
WiredHome 2:a29c32190037 239 void Poll();
WiredHome 12:109bf1558300 240
WiredHome 0:729320f63c5c 241 /**
WiredHome 12:109bf1558300 242 * Send typical header data, and some optional data back to the client.
WiredHome 3:17928786bdb5 243 *
WiredHome 3:17928786bdb5 244 * This forms and sends the typical header back to the client. It may also send
WiredHome 3:17928786bdb5 245 * optional data (which must end with "\r\n"). It then sends the second newline
WiredHome 3:17928786bdb5 246 * sequence that signals the end of the header.
WiredHome 0:729320f63c5c 247 *
WiredHome 0:729320f63c5c 248 * @param code is the optional return code; 200 = OK, if not provided then 404 = Not found is returned
WiredHome 0:729320f63c5c 249 * @param code_text is the text to align with the code (e.g. 404, "Not Found")
WiredHome 0:729320f63c5c 250 * @param content_type is a pointer to "Content-Type: text/html\r\n" (for example)
WiredHome 3:17928786bdb5 251 * @param optional_text is a pointer to any other text that is part of the header, which must
WiredHome 3:17928786bdb5 252 * have \r\n termination.
WiredHome 0:729320f63c5c 253 */
WiredHome 0:729320f63c5c 254 void header(int code = 404, const char * code_text = "Not Found", const char * content_type = NULL, const char * optional_text = NULL);
WiredHome 0:729320f63c5c 255
WiredHome 0:729320f63c5c 256 /**
WiredHome 0:729320f63c5c 257 * Send text to the client
WiredHome 0:729320f63c5c 258 *
WiredHome 3:17928786bdb5 259 * This sends the specified text to the client. If the number of bytes is not set,
WiredHome 3:17928786bdb5 260 * then it calculates the number of bytes as a string. For binary transfers, the
WiredHome 3:17928786bdb5 261 * number of bytes to send is required for proper operation.
WiredHome 3:17928786bdb5 262 *
WiredHome 0:729320f63c5c 263 * @param msg is the text string to send
WiredHome 0:729320f63c5c 264 * @param bytes is the number of bytes to send. If not set, then strlen is calculated.
WiredHome 0:729320f63c5c 265 */
WiredHome 0:729320f63c5c 266 void send(const char * msg, int bytes = -1);
WiredHome 12:109bf1558300 267
WiredHome 0:729320f63c5c 268 /**
WiredHome 3:17928786bdb5 269 * Send a referenced file to the client, including the header
WiredHome 3:17928786bdb5 270 *
WiredHome 3:17928786bdb5 271 * This sends a file from the filesystem to the client. It must be of a supported type
WiredHome 3:17928786bdb5 272 * in order to properly create the header.
WiredHome 0:729320f63c5c 273 *
WiredHome 0:729320f63c5c 274 * @param filename is the fully qualified path and filename
WiredHome 3:17928786bdb5 275 * @param filetype is the header information (e.g. "Content-Type: application/pdf")
WiredHome 0:729320f63c5c 276 * @return true if it thinks it sent ok, false otherwise.
WiredHome 0:729320f63c5c 277 */
WiredHome 0:729320f63c5c 278 bool SendFile(const char * filename, const char * filetype);
WiredHome 12:109bf1558300 279
WiredHome 12:109bf1558300 280 /**
WiredHome 0:729320f63c5c 281 * register a handler for a specific URL.
WiredHome 0:729320f63c5c 282 *
WiredHome 3:17928786bdb5 283 * This api lets you register a dynamic handler in the web server. This is
WiredHome 3:17928786bdb5 284 * most useful for interactive web pages, rather than simply serving static
WiredHome 3:17928786bdb5 285 * pages.
WiredHome 3:17928786bdb5 286 *
WiredHome 3:17928786bdb5 287 * @code
WiredHome 12:109bf1558300 288 *
WiredHome 3:17928786bdb5 289 * ...
WiredHome 3:17928786bdb5 290 * svr.RegisterHandler("/dyn1", SimpleDynamicPage);svr.RegisterHandler("/dyn1", SimpleDynamicPage);
WiredHome 3:17928786bdb5 291 * ...
WiredHome 3:17928786bdb5 292 *
WiredHome 13:8975d7928678 293 * bool SimpleDynamicPage(HTTPServer *svr, HTTPServer::CallBackType type, const char * path, const HTTPServer::namevalue *queryParams, int queryParamCount) {
WiredHome 3:17928786bdb5 294 * char buf[100];
WiredHome 3:17928786bdb5 295 * bool ret = false;
WiredHome 12:109bf1558300 296 *
WiredHome 3:17928786bdb5 297 * switch (type) {
WiredHome 3:17928786bdb5 298 * case HTTPServer::SEND_PAGE:
WiredHome 3:17928786bdb5 299 * svr->header(200, "OK", "Content-Type: text/html\r\n");
WiredHome 3:17928786bdb5 300 * svr->send("<html><head><title>Dynamic Page</title></head>\r\n");
WiredHome 3:17928786bdb5 301 * svr->send("<body>\r\n");
WiredHome 3:17928786bdb5 302 * svr->send("This page was generated dynamically. Create your own name=value pairs on the URL "
WiredHome 3:17928786bdb5 303 * "which uses the GET method.<br/>\r\n");
WiredHome 13:8975d7928678 304 * sprintf(buf, "%d parameters passed to {%s}:<br/>\r\n", queryParamCount, path);
WiredHome 3:17928786bdb5 305 * svr->send(buf);
WiredHome 13:8975d7928678 306 * for (int i=0; i<queryParamCount; i++) {
WiredHome 13:8975d7928678 307 * sprintf(buf, "%d: %s = %s<br/>\r\n", i, queryParams[i].name, queryParams[i].value);
WiredHome 3:17928786bdb5 308 * svr->send(buf);
WiredHome 3:17928786bdb5 309 * }
WiredHome 3:17928786bdb5 310 * svr->send("Stats:<br/>\r\n");
WiredHome 3:17928786bdb5 311 * sprintf(buf,"Free memory space: %d<br/>\r\n", Free());
WiredHome 3:17928786bdb5 312 * svr->send(buf);
WiredHome 3:17928786bdb5 313 * sprintf(buf,"Max Header size: %d<br/>\r\n", svr->GetMaxHeaderSize());
WiredHome 3:17928786bdb5 314 * svr->send(buf);
WiredHome 3:17928786bdb5 315 * svr->send("<br/><a href='/'>back to main</a></body></html>\r\n");
WiredHome 3:17928786bdb5 316 * ret = true;
WiredHome 3:17928786bdb5 317 * break;
WiredHome 3:17928786bdb5 318 * case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 3:17928786bdb5 319 * ret = true;
WiredHome 3:17928786bdb5 320 * break;
WiredHome 3:17928786bdb5 321 * case HTTPServer::DATA_TRANSFER:
WiredHome 3:17928786bdb5 322 * ret = true;
WiredHome 3:17928786bdb5 323 * break;
WiredHome 3:17928786bdb5 324 * default:
WiredHome 3:17928786bdb5 325 * ret = false;
WiredHome 3:17928786bdb5 326 * break;
WiredHome 3:17928786bdb5 327 * }
WiredHome 3:17928786bdb5 328 * return ret;
WiredHome 3:17928786bdb5 329 * }
WiredHome 3:17928786bdb5 330 * @endcode
WiredHome 3:17928786bdb5 331 *
WiredHome 0:729320f63c5c 332 * @param path to register
WiredHome 0:729320f63c5c 333 * @param callback of type Handler
WiredHome 0:729320f63c5c 334 * @return true if successfully registered
WiredHome 0:729320f63c5c 335 */
WiredHome 0:729320f63c5c 336 bool RegisterHandler(const char * path, Handler callback);
WiredHome 12:109bf1558300 337
WiredHome 0:729320f63c5c 338 /**
WiredHome 16:6ebacf2946d8 339 * determine if the named file is a supported type (htm, html, jpg, etc)
WiredHome 0:729320f63c5c 340 *
WiredHome 3:17928786bdb5 341 * if you pass in a filename, it will attempt to extract the extension
WiredHome 3:17928786bdb5 342 * and compare that to the list of supported file types. If it finds a
WiredHome 3:17928786bdb5 343 * match, then it will return a pointer to the content-type string.
WiredHome 3:17928786bdb5 344 *
WiredHome 3:17928786bdb5 345 * @code
WiredHome 3:17928786bdb5 346 * fType = GetSupportedType("mypix.jpg");
WiredHome 3:17928786bdb5 347 * if (fType) {
WiredHome 3:17928786bdb5 348 * ...
WiredHome 3:17928786bdb5 349 * @endcode
WiredHome 12:109bf1558300 350 *
WiredHome 0:729320f63c5c 351 * @param filename is the filename to test, based on the extension
WiredHome 0:729320f63c5c 352 * @return pointer to a Content-Type string if supported, or NULL if not.
WiredHome 0:729320f63c5c 353 */
WiredHome 0:729320f63c5c 354 const char * GetSupportedType(const char * filename);
WiredHome 0:729320f63c5c 355
WiredHome 0:729320f63c5c 356 /**
WiredHome 0:729320f63c5c 357 * search the available parameters for 'name' and if found, return the 'value'
WiredHome 0:729320f63c5c 358 *
WiredHome 12:109bf1558300 359 * After the querystring is parsed, the server maintains an array of
WiredHome 3:17928786bdb5 360 * name=value pairs. This Get function will search for the passed in name
WiredHome 3:17928786bdb5 361 * and provide access to the value.
WiredHome 3:17928786bdb5 362 *
WiredHome 3:17928786bdb5 363 * @code
WiredHome 3:17928786bdb5 364 * BusOut leds(LED1,LED2,LED3,LED4);
WiredHome 3:17928786bdb5 365 * ...
WiredHome 3:17928786bdb5 366 * leds = atoi(svr->GetParameter("leds"));
WiredHome 3:17928786bdb5 367 * @endcode
WiredHome 3:17928786bdb5 368 *
WiredHome 0:729320f63c5c 369 * @param name is the name to search for
WiredHome 0:729320f63c5c 370 * @return pointer to the value, or NULL
WiredHome 0:729320f63c5c 371 */
WiredHome 0:729320f63c5c 372 const char * GetParameter(const char * name);
WiredHome 0:729320f63c5c 373
WiredHome 0:729320f63c5c 374 /**
WiredHome 12:109bf1558300 375 * Parse the text string into name=value parameters.
WiredHome 3:17928786bdb5 376 *
WiredHome 12:109bf1558300 377 * This will directly modify the referenced string. If there is a
WiredHome 3:17928786bdb5 378 * #fragment_id on the end of the string, it will be removed.
WiredHome 0:729320f63c5c 379 *
WiredHome 0:729320f63c5c 380 * @param pString is a pointer to the string.
WiredHome 0:729320f63c5c 381 */
WiredHome 0:729320f63c5c 382 void ParseParameters(char * pString);
WiredHome 12:109bf1558300 383
WiredHome 0:729320f63c5c 384 /**
WiredHome 16:6ebacf2946d8 385 * Unescape string converts a coded string "in place" into a normal string.
WiredHome 3:17928786bdb5 386 *
WiredHome 3:17928786bdb5 387 * A query string will have a number of characters replaced for communication
WiredHome 3:17928786bdb5 388 * which includes spaces, quotes, question marks and more. Most of them
WiredHome 12:109bf1558300 389 * will be replaced with a %xx format, where xx is the hex code for the
WiredHome 3:17928786bdb5 390 * character. Since the string will only get shorter when this happens
WiredHome 3:17928786bdb5 391 * the operation is performed in place.
WiredHome 3:17928786bdb5 392 *
WiredHome 0:729320f63c5c 393 * this "This%20is%20a%20question%3F%20and%20an%20answer."
WiredHome 12:109bf1558300 394 *
WiredHome 0:729320f63c5c 395 * becomes "This is a question? and an answer."
WiredHome 3:17928786bdb5 396 *
WiredHome 0:729320f63c5c 397 * @note '+' is another form of space, so is converted to a space before the %xx
WiredHome 0:729320f63c5c 398 *
WiredHome 0:729320f63c5c 399 * @param encoded string to be converted
WiredHome 0:729320f63c5c 400 */
WiredHome 0:729320f63c5c 401 void UnescapeString(char * encoded);
WiredHome 12:109bf1558300 402
WiredHome 21:660143f20b04 403
WiredHome 21:660143f20b04 404 #ifdef INCLUDE_GETREMOTE
WiredHome 0:729320f63c5c 405 /**
WiredHome 0:729320f63c5c 406 * Get the IP address of the remote node to which we are connected.
WiredHome 3:17928786bdb5 407 *
WiredHome 3:17928786bdb5 408 * This will get the IP address of the remote node to which we are
WiredHome 12:109bf1558300 409 * currently connected. This is written into the buffer in
WiredHome 3:17928786bdb5 410 * "192.168.100.234" format. If the buffer size is note >= 16 bytes,
WiredHome 3:17928786bdb5 411 * it will set the buffer to null.
WiredHome 12:109bf1558300 412 *
WiredHome 21:660143f20b04 413 * @deprecated This binds the web server to only network interfaces
WiredHome 21:660143f20b04 414 * that support this API (WiFly), so can limit its use.
WiredHome 21:660143f20b04 415 * This API will be removed.
WiredHome 21:660143f20b04 416 *
WiredHome 3:17928786bdb5 417 * @note This switches the module into, and out of, command mode
WiredHome 12:109bf1558300 418 * which has quite a time penalty.
WiredHome 3:17928786bdb5 419 *
WiredHome 3:17928786bdb5 420 * @param str is the string to write the address into, which should be at
WiredHome 3:17928786bdb5 421 * least as large as "192.168.100.203" (16-bytes).
WiredHome 4:f34642902056 422 * @param strSize of the str buffer must be >=16, so it will not buffer overrun.
WiredHome 5:c9b27e718054 423 * @returns true if it succeeded, false otherwise
WiredHome 0:729320f63c5c 424 */
WiredHome 5:c9b27e718054 425 bool GetRemoteAddr(char * str, int strSize);
WiredHome 21:660143f20b04 426 #endif
WiredHome 0:729320f63c5c 427
WiredHome 12:109bf1558300 428 /**
WiredHome 16:6ebacf2946d8 429 * This is used to force a connection to close.
WiredHome 3:17928786bdb5 430 *
WiredHome 3:17928786bdb5 431 * This switches the module into command mode, performs the close,
WiredHome 3:17928786bdb5 432 * then switches it back to data mode. So, this is a time-expensive
WiredHome 3:17928786bdb5 433 * command.
WiredHome 7:99ad7a67f05e 434 *
WiredHome 7:99ad7a67f05e 435 * @returns true if successful
WiredHome 0:729320f63c5c 436 */
WiredHome 7:99ad7a67f05e 437 bool close_connection();
WiredHome 12:109bf1558300 438
WiredHome 3:17928786bdb5 439 /**
WiredHome 16:6ebacf2946d8 440 * Diagnostic to get the size of the largest header.
WiredHome 3:17928786bdb5 441 *
WiredHome 12:109bf1558300 442 * This is a diagnostic function, so you can resize the allocated
WiredHome 12:109bf1558300 443 * buffer for your application. With proper sizing, more of the
WiredHome 3:17928786bdb5 444 * system memory is available for your application.
WiredHome 3:17928786bdb5 445 *
WiredHome 3:17928786bdb5 446 * @code
WiredHome 3:17928786bdb5 447 * sprintf(buf,"Max Header size: %d<br/>\r\n", svr->GetMaxHeaderSize());
WiredHome 3:17928786bdb5 448 * svr->send(buf);
WiredHome 3:17928786bdb5 449 * @endcode
WiredHome 12:109bf1558300 450 *
WiredHome 3:17928786bdb5 451 * @returns size in bytes of the larger header measured.
WiredHome 3:17928786bdb5 452 */
WiredHome 3:17928786bdb5 453 int GetMaxHeaderSize();
WiredHome 3:17928786bdb5 454
WiredHome 13:8975d7928678 455 /**
WiredHome 16:6ebacf2946d8 456 * Get a value from the http header, if it exists.
WiredHome 13:8975d7928678 457 *
WiredHome 13:8975d7928678 458 * @param hdr is the string to search for (e.g. "Content-Length")
WiredHome 13:8975d7928678 459 *
WiredHome 13:8975d7928678 460 * @returns pointer to the value associated with that header.
WiredHome 13:8975d7928678 461 * @returns NULL if the header is not found.
WiredHome 13:8975d7928678 462 */
WiredHome 13:8975d7928678 463 const char * GetHeaderValue(const char * hdr);
WiredHome 3:17928786bdb5 464
WiredHome 3:17928786bdb5 465 /**
WiredHome 3:17928786bdb5 466 * Performance parameter
WiredHome 3:17928786bdb5 467 */
WiredHome 3:17928786bdb5 468 typedef struct SW_PERFPARAM {
WiredHome 3:17928786bdb5 469 unsigned long long TotalTime_us;
WiredHome 3:17928786bdb5 470 unsigned long Samples;
WiredHome 3:17928786bdb5 471 unsigned long MaxTime_us;
WiredHome 3:17928786bdb5 472 } SW_PerformanceParam;
WiredHome 12:109bf1558300 473
WiredHome 3:17928786bdb5 474 /**
WiredHome 3:17928786bdb5 475 * Performance metrics
WiredHome 3:17928786bdb5 476 */
WiredHome 3:17928786bdb5 477 typedef struct SW_PERFDATA {
WiredHome 17:69ff00ce39f4 478 SW_PerformanceParam ConnectionAccepted;
WiredHome 17:69ff00ce39f4 479 SW_PerformanceParam HeaderParsed;
WiredHome 17:69ff00ce39f4 480 SW_PerformanceParam ResponseSent;
WiredHome 17:69ff00ce39f4 481 SW_PerformanceParam ConnectionClosed;
WiredHome 3:17928786bdb5 482 //SW_PerformanceParam SendFile;
WiredHome 3:17928786bdb5 483 } SW_PerformanceData;
WiredHome 12:109bf1558300 484
WiredHome 3:17928786bdb5 485 /**
WiredHome 3:17928786bdb5 486 * Get performance metrics from the web server.
WiredHome 3:17928786bdb5 487 *
WiredHome 3:17928786bdb5 488 * This is a diagnostic function, and gathers data on the internal
WiredHome 3:17928786bdb5 489 * performance of the server, as it works various actions.
WiredHome 3:17928786bdb5 490 *
WiredHome 3:17928786bdb5 491 * @param p is a pointer to a SW_PerformanceData structure to be populated
WiredHome 3:17928786bdb5 492 */
WiredHome 3:17928786bdb5 493 void GetPerformanceData(SW_PerformanceData * p);
WiredHome 12:109bf1558300 494
WiredHome 3:17928786bdb5 495 /**
WiredHome 3:17928786bdb5 496 * Reset performance metrics.
WiredHome 3:17928786bdb5 497 */
WiredHome 3:17928786bdb5 498 void ResetPerformanceData();
WiredHome 17:69ff00ce39f4 499
WiredHome 17:69ff00ce39f4 500 /**
WiredHome 17:69ff00ce39f4 501 * Get performance clock
WiredHome 17:69ff00ce39f4 502 */
WiredHome 17:69ff00ce39f4 503 unsigned int GetPerformanceClock();
WiredHome 12:109bf1558300 504
WiredHome 5:c9b27e718054 505 /**
WiredHome 5:c9b27e718054 506 * Get the underlying wifly object.
WiredHome 6:fdce4464d92b 507 *
WiredHome 6:fdce4464d92b 508 * This lets you get to the underlying wifly object in order to
WiredHome 6:fdce4464d92b 509 * interact with it.
WiredHome 6:fdce4464d92b 510 *
WiredHome 6:fdce4464d92b 511 * @code
WiredHome 13:8975d7928678 512 * HTTPServer svr(&wifly, HTTP_SERVER_PORT, "/local/", 15, 30, 10, &pc);
WiredHome 6:fdce4464d92b 513 * ...
WiredHome 6:fdce4464d92b 514 * svr->GetWifly()->getWiflyVerString()
WiredHome 6:fdce4464d92b 515 * @endcode
WiredHome 6:fdce4464d92b 516 *
WiredHome 6:fdce4464d92b 517 * returns the wifly option.
WiredHome 5:c9b27e718054 518 */
WiredHome 12:109bf1558300 519 Wifly * GetWifly() {
WiredHome 12:109bf1558300 520 return wifly;
WiredHome 12:109bf1558300 521 };
WiredHome 0:729320f63c5c 522
WiredHome 0:729320f63c5c 523 private:
WiredHome 0:729320f63c5c 524 Wifly * wifly;
WiredHome 0:729320f63c5c 525 char * webroot;
WiredHome 0:729320f63c5c 526 PC * pc;
WiredHome 0:729320f63c5c 527 TCPSocketServer * server;
WiredHome 0:729320f63c5c 528 TCPSocketConnection client;
WiredHome 0:729320f63c5c 529 char * rewriteWithDefaultFile(char * queryString);
WiredHome 0:729320f63c5c 530 char * rewritePrependWebroot(char * queryString);
WiredHome 13:8975d7928678 531
WiredHome 13:8975d7928678 532 namevalue *queryParams; // Query Parameters from the URL this=that&sky=blue&...
WiredHome 13:8975d7928678 533 int maxqueryParams;
WiredHome 13:8975d7928678 534 int queryParamCount;
WiredHome 13:8975d7928678 535
WiredHome 13:8975d7928678 536 namevalue *headerParams; // Header params Host: 192.168...\r\nConnection: keep-alive\r\n...
WiredHome 13:8975d7928678 537 int maxheaderParams;
WiredHome 13:8975d7928678 538 int headerParamCount;
WiredHome 13:8975d7928678 539
WiredHome 3:17928786bdb5 540 int maxheaderbytes;
WiredHome 3:17928786bdb5 541 char * headerbuffer;
WiredHome 3:17928786bdb5 542 int headerbuffersize;
WiredHome 12:109bf1558300 543
WiredHome 10:9c8d2c6a3469 544 Timer PerformanceTimer;
WiredHome 3:17928786bdb5 545 /**
WiredHome 3:17928786bdb5 546 * Records performance data
WiredHome 12:109bf1558300 547 *
WiredHome 3:17928786bdb5 548 * This will take a pointer to a SW_PerformanceParam, and it will
WiredHome 3:17928786bdb5 549 * take the time when the performance measurement started. It locally
WiredHome 3:17928786bdb5 550 * accesses the current time to measure the elapsed.
WiredHome 3:17928786bdb5 551 *
WiredHome 3:17928786bdb5 552 * @param param is the performance parameter to update
WiredHome 3:17928786bdb5 553 * @param value is the reference time.
WiredHome 3:17928786bdb5 554 * @returns the current time which may be used as the reference time
WiredHome 3:17928786bdb5 555 * for further measurements.
WiredHome 3:17928786bdb5 556 */
WiredHome 16:6ebacf2946d8 557 unsigned int RecordPerformanceData(SW_PerformanceParam * param, unsigned int value);
WiredHome 3:17928786bdb5 558 SW_PerformanceData perfData;
WiredHome 12:109bf1558300 559
WiredHome 3:17928786bdb5 560 typedef struct HANDLER {
WiredHome 0:729320f63c5c 561 char * path;
WiredHome 0:729320f63c5c 562 Handler callback;
WiredHome 0:729320f63c5c 563 } handler;
WiredHome 0:729320f63c5c 564 int maxdynamicpages;
WiredHome 0:729320f63c5c 565 handler *handlers;
WiredHome 0:729320f63c5c 566 int handlercount;
WiredHome 3:17928786bdb5 567
WiredHome 3:17928786bdb5 568 char * queryType;
WiredHome 3:17928786bdb5 569 char * queryString;
WiredHome 3:17928786bdb5 570 char * postQueryString;
WiredHome 12:109bf1558300 571
WiredHome 0:729320f63c5c 572 /**
WiredHome 8:262583f054f6 573 * Extract the parameter from the record, by searching for the needle in the haystack.
WiredHome 8:262583f054f6 574 *
WiredHome 8:262583f054f6 575 * The parameter of interest follows the needle, and may be ' ' delimited
WiredHome 0:729320f63c5c 576 * Can damage haystack while processing it.
WiredHome 0:729320f63c5c 577 *
WiredHome 0:729320f63c5c 578 * @param haystack is the record to search
WiredHome 0:729320f63c5c 579 * @param needle is the text to search for, which precedes the text to return
WiredHome 0:729320f63c5c 580 * @param string is the text following the needle
WiredHome 0:729320f63c5c 581 * @return true if it extracted something successfully
WiredHome 0:729320f63c5c 582 */
WiredHome 0:729320f63c5c 583 bool Extract(char * rec, char * needle, char ** string);
WiredHome 0:729320f63c5c 584
WiredHome 3:17928786bdb5 585 void SendResponse();
WiredHome 3:17928786bdb5 586 bool ParseHeader(char * bPtr);
WiredHome 3:17928786bdb5 587 bool CheckDynamicHandlers();
WiredHome 3:17928786bdb5 588
WiredHome 0:729320f63c5c 589 int HexCharToInt(char c);
WiredHome 0:729320f63c5c 590 char HexPairToChar(char * p);
WiredHome 0:729320f63c5c 591 };
WiredHome 0:729320f63c5c 592 #endif //SW_HTTPSERVER_H
WiredHome 4:f34642902056 593
WiredHome 7:99ad7a67f05e 594