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:
Sat Apr 08 19:39:51 2017 +0000
Revision:
48:078adbe279ac
Parent:
46:eaa86d48be6f
Child:
49:cd391662f254
Minor change - an additional optional parameter on the constructor that defines the blocking time (in msec) when Poll() is called. The default was way too long for most needs.

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 "TCPSocketServer.h"
WiredHome 1:54353af0d20a 6 #include "TCPSocketConnection.h"
WiredHome 1:54353af0d20a 7
WiredHome 1:54353af0d20a 8 #ifdef MODSERIAL_H
WiredHome 1:54353af0d20a 9 #define PC MODSERIAL
WiredHome 1:54353af0d20a 10 #else
WiredHome 36:1bb5fa6b109c 11 #define PC RawSerial
WiredHome 1:54353af0d20a 12 #endif
WiredHome 1:54353af0d20a 13
WiredHome 9:2ea342765c9d 14 /// This is the default buffer size used to send files. You might size
WiredHome 9:2ea342765c9d 15 /// this to be equal or less than the payload size of 1460 bytes.
WiredHome 44:71f09e4255f4 16 /// For WiFly: see User Manual 3.6.1.
WiredHome 44:71f09e4255f4 17 #define FILESEND_BUF_SIZE 500
WiredHome 3:17928786bdb5 18
WiredHome 3:17928786bdb5 19
WiredHome 12:109bf1558300 20 /// MAX_HEADER_SIZE is the default size to contain the largest header.
WiredHome 9:2ea342765c9d 21 /// This is the size of the URL and query string, and also all the
WiredHome 3:17928786bdb5 22 /// other header information about the client. This can be
WiredHome 12:109bf1558300 23 /// a couple of K, larger if you have big forms as it includes the
WiredHome 3:17928786bdb5 24 /// form data that is submitted.
WiredHome 3:17928786bdb5 25 #define MAX_HEADER_SIZE 1000
WiredHome 3:17928786bdb5 26
WiredHome 9:2ea342765c9d 27
WiredHome 39:0427544a5c08 28 /// HTTPServer is a simple web server leveraging a network interface.
WiredHome 12:109bf1558300 29 ///
WiredHome 3:17928786bdb5 30 /// While simple, it is a capable, web server. The basic mode
WiredHome 3:17928786bdb5 31 /// of operation is for it to serve static web pages from an available
WiredHome 3:17928786bdb5 32 /// file system.
WiredHome 12:109bf1558300 33 ///
WiredHome 3:17928786bdb5 34 /// The default page is index.htm (compile time defined)
WiredHome 3:17928786bdb5 35 /// standard support to serve a number of standard file types;
WiredHome 3:17928786bdb5 36 /// gif, jpg, jpeg, ico, png, zip, gz, tar, txt, pdf, htm, html
WiredHome 3:17928786bdb5 37 /// (this list is also compile time defined)
WiredHome 3:17928786bdb5 38 ///
WiredHome 3:17928786bdb5 39 /// It can also serve dynamically generated pages, and therefore
WiredHome 3:17928786bdb5 40 /// respond to form submission. Through the dynamic interface it is
WiredHome 3:17928786bdb5 41 /// then quite easy to interact with the hardware, reading the inputs
WiredHome 3:17928786bdb5 42 /// or signaling outputs.
WiredHome 3:17928786bdb5 43 ///
WiredHome 3:17928786bdb5 44 /// @code
WiredHome 39:0427544a5c08 45 /// HTTPServer svr(HTTP_SERVER_PORT, "/local", 15, 30, 10, &pc);
WiredHome 3:17928786bdb5 46 /// svr.RegisterHandler("/dyn1", SimpleDynamicPage);
WiredHome 44:71f09e4255f4 47 /// while (true) {
WiredHome 44:71f09e4255f4 48 /// svr.Poll(); // this is non blocking process, with variable execution
WiredHome 44:71f09e4255f4 49 /// }
WiredHome 3:17928786bdb5 50 /// @endcode
WiredHome 3:17928786bdb5 51 ///
WiredHome 44:71f09e4255f4 52 /// This web server used nweb as a starting point, but expanded well beyond that.
WiredHome 46:eaa86d48be6f 53 /// http://nmon.sourceforge.net/pmwiki.php?n=Site.Nweb&cm_mc_uid=21286415979014862330090&cm_mc_sid_50200000=1486233009
WiredHome 0:729320f63c5c 54 ///
WiredHome 3:17928786bdb5 55 /// Given: scheme://server:port/path?query_string#fragment_id
WiredHome 0:729320f63c5c 56 /// @li scheme is "http"
WiredHome 3:17928786bdb5 57 /// @li server is whatever IP the server has
WiredHome 0:729320f63c5c 58 /// @li port is the registered port
WiredHome 0:729320f63c5c 59 /// @li /path is the reference to the file (actual or logical) on the server
WiredHome 0:729320f63c5c 60 /// @li query_string is any combination of name=value pairs
WiredHome 0:729320f63c5c 61 /// @li fragment_id is a reference to an anchor on the page
WiredHome 0:729320f63c5c 62 ///
WiredHome 3:17928786bdb5 63 /// Features:
WiredHome 3:17928786bdb5 64 /// @li Serves static pages from a file system. Many normal filetypes are
WiredHome 3:17928786bdb5 65 /// supported.
WiredHome 3:17928786bdb5 66 /// @li Compile time configurable for the "default" file, typically index.htm.
WiredHome 3:17928786bdb5 67 /// @li Provides a registration interface for dynamically generated pages that
WiredHome 3:17928786bdb5 68 /// can then interact with other hardware.
WiredHome 3:17928786bdb5 69 /// @li Revised to be Non-blocking, however the execution time is variable
WiredHome 44:71f09e4255f4 70 /// depending on the actions being performed and can span hundreds of msec
WiredHome 44:71f09e4255f4 71 /// when using a WiFly module as the network interface.
WiredHome 44:71f09e4255f4 72 /// @li Support for filenames aliases, which permit using long filenames with
WiredHome 44:71f09e4255f4 73 /// the LocalFileSystem (which has an 8.3 constraint).
WiredHome 3:17928786bdb5 74 ///
WiredHome 3:17928786bdb5 75 /// Limitations:
WiredHome 39:0427544a5c08 76 /// @li When used with Wifly network interface it supports only a single
WiredHome 39:0427544a5c08 77 /// connection at a time. A web page with served objects (img src=...)
WiredHome 39:0427544a5c08 78 /// is rarely served properly. It might trace to forcing the connection to
WiredHome 39:0427544a5c08 79 /// close, but not yet sure. Explore "Set Uart Rx Data Buffer" in
WiredHome 39:0427544a5c08 80 /// WiFly manual 2.3.65. This is a limitation of the Wifly module.
WiredHome 39:0427544a5c08 81 /// No solution is forthcoming, so a crude workaround is to use javascript
WiredHome 39:0427544a5c08 82 /// to load the images after the page loads.
WiredHome 3:17928786bdb5 83 /// @li Rapid requests for page objects (e.g. embedded images) are lost. Still
WiredHome 3:17928786bdb5 84 /// working to understand this issue.
WiredHome 3:17928786bdb5 85 ///
WiredHome 43:3fc773c2986e 86 /// Improvements (TODO):
WiredHome 43:3fc773c2986e 87 /// @li Add hook for a custom 404 page, which might show a page, or might redirect.
WiredHome 43:3fc773c2986e 88 /// @li Combine the API for accessing parameters for the GET and POST, as they
WiredHome 43:3fc773c2986e 89 /// are normally [always?] mutually exclusive.
WiredHome 43:3fc773c2986e 90 /// @li Keep only the public functions public, make the rest private/protected.
WiredHome 43:3fc773c2986e 91 /// Add another interface for dynamic pages to give them access to private/protected
WiredHome 43:3fc773c2986e 92 /// functions.
WiredHome 43:3fc773c2986e 93 /// @li Try to reduce the size of the header buffer, since that is quite large.
WiredHome 43:3fc773c2986e 94 /// @li General clean-up, refactoring, de-duplication.
WiredHome 43:3fc773c2986e 95 /// @li Leverage mbed os, so one receive handler can spawn up to N response handlers.
WiredHome 43:3fc773c2986e 96 /// This may improve overall performance.
WiredHome 43:3fc773c2986e 97 /// @li Since some transactions can't be easily buffered (the stream may be too
WiredHome 43:3fc773c2986e 98 /// large, consider how to shuttle parts of the transaction back and forth
WiredHome 43:3fc773c2986e 99 /// between the user-code and the server.
WiredHome 18:6199558632c0 100 ///
WiredHome 43:3fc773c2986e 101 /// History (TO-Done):
WiredHome 48:078adbe279ac 102 /// @li 20170408 Added another optional parameter to the constructor to control the
WiredHome 48:078adbe279ac 103 /// blocking time when Poll() is called.
WiredHome 43:3fc773c2986e 104 /// @li 20140913 Removed the relationship to the Wifly module, which caused an API change
WiredHome 43:3fc773c2986e 105 /// in the constructor by elimination of the first parameter.
WiredHome 43:3fc773c2986e 106 /// @li 20140913 parses the header similar to the query string, and then makes
WiredHome 43:3fc773c2986e 107 /// those parameters accessible.
WiredHome 43:3fc773c2986e 108 /// @li 20140913 Added basic password capability to dynamic web pages.
WiredHome 43:3fc773c2986e 109 /// @li 20140913 move part of the POST method handler to the registered handler, so
WiredHome 0:729320f63c5c 110 /// it can decide if it should allocate the needed memory.
WiredHome 43:3fc773c2986e 111 /// @li 20140201 hunted down several lengthy operations - the speed of the file system
WiredHome 43:3fc773c2986e 112 /// and the "close" operation which requires <delay 0.25s>$$$<delay>close\r.
WiredHome 2:a29c32190037 113 /// @li 20130530 Initial version
WiredHome 2:a29c32190037 114 /// @li 20130601 Renamed ip_process to Poll
WiredHome 3:17928786bdb5 115 /// @li 20130617 Cleaned up some of the documentation changes
WiredHome 3:17928786bdb5 116 /// @li 20130623 Make it non-blocking. "Poll" takes a variable amount
WiredHome 3:17928786bdb5 117 /// of time, based on whether it is idle, or how much it
WiredHome 3:17928786bdb5 118 /// has to do.
WiredHome 18:6199558632c0 119 /// @li 20130911 Lots of incremental changes along this way, this update
WiredHome 18:6199558632c0 120 /// refreshes the documentation.
WiredHome 0:729320f63c5c 121 ///
WiredHome 46:eaa86d48be6f 122 /// @note Copyright &copy; 2014-2017 by Smartware Computing, all rights reserved.
WiredHome 0:729320f63c5c 123 /// Individuals may use this application for evaluation or non-commercial
WiredHome 0:729320f63c5c 124 /// purposes. Within this restriction, changes may be made to this application
WiredHome 0:729320f63c5c 125 /// as long as this copyright notice is retained. The user shall make
WiredHome 0:729320f63c5c 126 /// clear that their work is a derived work, and not the original.
WiredHome 0:729320f63c5c 127 /// Users of this application and sources accept this application "as is" and
WiredHome 0:729320f63c5c 128 /// shall hold harmless Smartware Computing, for any undesired results while
WiredHome 0:729320f63c5c 129 /// using this application - whether real or imagined.
WiredHome 0:729320f63c5c 130 ///
WiredHome 0:729320f63c5c 131 /// @author David Smart, Smartware Computing
WiredHome 0:729320f63c5c 132 ///
WiredHome 0:729320f63c5c 133 class HTTPServer
WiredHome 0:729320f63c5c 134 {
WiredHome 0:729320f63c5c 135 public:
WiredHome 0:729320f63c5c 136 /**
WiredHome 3:17928786bdb5 137 * name-value pairs for parameters
WiredHome 0:729320f63c5c 138 */
WiredHome 3:17928786bdb5 139 typedef struct NAMEVALUE {
WiredHome 0:729320f63c5c 140 char * name;
WiredHome 0:729320f63c5c 141 char * value;
WiredHome 0:729320f63c5c 142 } namevalue;
WiredHome 12:109bf1558300 143
WiredHome 2:a29c32190037 144 /**
WiredHome 3:17928786bdb5 145 * Indicates the purpose of the Handler callback
WiredHome 3:17928786bdb5 146 *
WiredHome 12:109bf1558300 147 * Application code in a dynamic page uses this to determine the state
WiredHome 3:17928786bdb5 148 * and therefore the needed operation to be performed.
WiredHome 3:17928786bdb5 149 *
WiredHome 3:17928786bdb5 150 * @code
WiredHome 13:8975d7928678 151 * bool SimpleDynamicPage(HTTPServer *svr, HTTPServer::CallBackType type,
WiredHome 13:8975d7928678 152 * const char * path, const HTTPServer::namevalue *queryParams,
WiredHome 13:8975d7928678 153 * int queryParamCount) {
WiredHome 3:17928786bdb5 154 * char buf[100];
WiredHome 3:17928786bdb5 155 * bool ret = false;
WiredHome 12:109bf1558300 156 *
WiredHome 3:17928786bdb5 157 * switch (type) {
WiredHome 3:17928786bdb5 158 * case HTTPServer::SEND_PAGE:
WiredHome 3:17928786bdb5 159 * svr->header(200, "OK", "Content-Type: text/html\r\n");
WiredHome 3:17928786bdb5 160 * svr->send("<html><head><title>Dynamic Page</title></head>\r\n");
WiredHome 3:17928786bdb5 161 * svr->send("<body>\r\n");
WiredHome 3:17928786bdb5 162 * svr->send("This page was generated dynamically. Create your own name=value pairs on the URL "
WiredHome 3:17928786bdb5 163 * "which uses the GET method.<br/>\r\n");
WiredHome 13:8975d7928678 164 * sprintf(buf, "%d parameters passed to {%s}:<br/>\r\n", queryParamCount, path);
WiredHome 3:17928786bdb5 165 * svr->send(buf);
WiredHome 13:8975d7928678 166 * for (int i=0; i<queryParamCount; i++) {
WiredHome 13:8975d7928678 167 * sprintf(buf, "%d: %s = %s<br/>\r\n", i, queryParams[i].name, queryParams[i].value);
WiredHome 3:17928786bdb5 168 * svr->send(buf);
WiredHome 3:17928786bdb5 169 * }
WiredHome 3:17928786bdb5 170 * svr->send("<br/><a href='/'>back to main</a></body></html>\r\n");
WiredHome 3:17928786bdb5 171 * ret = true;
WiredHome 3:17928786bdb5 172 * break;
WiredHome 3:17928786bdb5 173 * case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 3:17928786bdb5 174 * ret = true;
WiredHome 3:17928786bdb5 175 * break;
WiredHome 3:17928786bdb5 176 * case HTTPServer::DATA_TRANSFER:
WiredHome 3:17928786bdb5 177 * ret = true;
WiredHome 3:17928786bdb5 178 * break;
WiredHome 3:17928786bdb5 179 * default:
WiredHome 3:17928786bdb5 180 * ret = false;
WiredHome 3:17928786bdb5 181 * break;
WiredHome 3:17928786bdb5 182 * }
WiredHome 3:17928786bdb5 183 * return ret;
WiredHome 3:17928786bdb5 184 * }
WiredHome 3:17928786bdb5 185 * @endcode
WiredHome 2:a29c32190037 186 */
WiredHome 3:17928786bdb5 187 typedef enum CALLBACKTYPE {
WiredHome 14:19c5f6151319 188 CONTENT_LENGTH_REQUEST, ///< ask the client if they wish to accept the data, typically from a POST event
WiredHome 27:90a1f5a5392f 189 DATA_TRANSFER, ///< used when submitting a file via a form
WiredHome 33:ef165a67ab22 190 DATA_TRANSFER_END, ///< used when all data has been given to the client (may be used to close the file)
WiredHome 3:17928786bdb5 191 SEND_PAGE, ///< the activated method should now send the page
WiredHome 2:a29c32190037 192 } CallBackType;
WiredHome 0:729320f63c5c 193
WiredHome 28:f93ef41b78e1 194 typedef enum CALLBACKRESULTS {
WiredHome 28:f93ef41b78e1 195 ACCEPT_ERROR, ///< client not accepting the request.
WiredHome 28:f93ef41b78e1 196 ACCEPT_COMPLETE, ///< client accepted the request, the work is done.
WiredHome 28:f93ef41b78e1 197 ACCEPT_CONTINUE, ///< client accepted the request, additional transactions to complete.
WiredHome 28:f93ef41b78e1 198 } CallBackResults;
WiredHome 28:f93ef41b78e1 199
WiredHome 44:71f09e4255f4 200 /// This is the set of header codes that are generally recognized. Note that many are
WiredHome 44:71f09e4255f4 201 /// not supported, so may not be listed here.
WiredHome 44:71f09e4255f4 202 typedef enum HEADERCODES {
WiredHome 44:71f09e4255f4 203 // 1xx: Information
WiredHome 44:71f09e4255f4 204 //Continue = 100, ///< Server has received the headers, client should send the body.
WiredHome 44:71f09e4255f4 205 //Switching = 101, ///< Request to switch protocols - not supported.
WiredHome 44:71f09e4255f4 206 //Checkpoint = 102, ///< resume aborted PUT/POST - not supported.
WiredHome 44:71f09e4255f4 207
WiredHome 44:71f09e4255f4 208 // 2xx: Successful
WiredHome 44:71f09e4255f4 209 OK = 200, ///< request is OK.
WiredHome 44:71f09e4255f4 210 //Created = 201, ///< The request has been fulfilled - not supported.
WiredHome 44:71f09e4255f4 211 //Accepted = 202, ///< The request has been accepted for processing - not supported.
WiredHome 44:71f09e4255f4 212 //Non_Auth = 203, ///< The request has been successfully processed - not supported.
WiredHome 44:71f09e4255f4 213 //No_Content = 204, ///< The request has been successfully processed, but is not returning any content
WiredHome 44:71f09e4255f4 214 //Reset_Content = 205, ///< The request has been successfully processed, but is not returning any content,
WiredHome 44:71f09e4255f4 215 // /// and requires that the requester reset the document view
WiredHome 44:71f09e4255f4 216 //Partial_Content = 206, /// The server is delivering only part of the resource due to a range header sent by the client
WiredHome 44:71f09e4255f4 217
WiredHome 44:71f09e4255f4 218 // 3xx: Redirection
WiredHome 44:71f09e4255f4 219 //Multiple_Choices = 300, /// A link list. The user can select a link and go to that location. Maximum five addresses.
WiredHome 44:71f09e4255f4 220 Moved_Permanently = 301, ///< The requested page has moved to a new URL.
WiredHome 44:71f09e4255f4 221 //Found = 302, /// The requested page has moved temporarily to a new URL
WiredHome 44:71f09e4255f4 222 //See_Other = 303, /// The requested page can be found under a different URL
WiredHome 44:71f09e4255f4 223 //Not_Modified = 304, /// Indicates the requested page has not been modified since last requested
WiredHome 44:71f09e4255f4 224 // 306 Switch Proxy No longer used
WiredHome 44:71f09e4255f4 225 // 307 Temporary Redirect The requested page has moved temporarily to a new URL
WiredHome 44:71f09e4255f4 226 // 308 Resume Incomplete Used in the resumable requests proposal to resume aborted PUT or POST requests
WiredHome 44:71f09e4255f4 227
WiredHome 44:71f09e4255f4 228 // 4xx: Client Error
WiredHome 44:71f09e4255f4 229 Bad_Request = 400, ///< The request cannot be fulfilled due to bad syntax
WiredHome 44:71f09e4255f4 230 Unauthorized = 401, ///< The request was a legal request, but the server is refusing to respond to it. For use when authentication is possible but has failed or not yet been provided
WiredHome 44:71f09e4255f4 231 // 402 Payment Required Reserved for future use
WiredHome 44:71f09e4255f4 232 // 403 Forbidden The request was a legal request, but the server is refusing to respond to it
WiredHome 44:71f09e4255f4 233 Not_Found = 404, ///< The requested page could not be found but may be available again in the future
WiredHome 44:71f09e4255f4 234 // Method Not Allowed 405 A request was made of a page using a request method not supported by that page
WiredHome 44:71f09e4255f4 235 // Not Acceptable 406 The server can only generate a response that is not accepted by the client
WiredHome 44:71f09e4255f4 236 // Proxy Auth Reqd 407 The client must first authenticate itself with the proxy
WiredHome 44:71f09e4255f4 237 Request_Timeout = 408, ///< The server timed out waiting for the request
WiredHome 44:71f09e4255f4 238 // 409 Conflict The request could not be completed because of a conflict in the request
WiredHome 44:71f09e4255f4 239 // 410 Gone The requested page is no longer available
WiredHome 44:71f09e4255f4 240 // 411 Length Required The "Content-Length" is not defined. The server will not accept the request without it
WiredHome 44:71f09e4255f4 241 // 412 Precondition Failed The precondition given in the request evaluated to false by the server
WiredHome 44:71f09e4255f4 242 // 413 Request Entity Too Large The server will not accept the request, because the request entity is too large
WiredHome 44:71f09e4255f4 243 // 414 Request-URI Too Long The server will not accept the request, because the URL is too long. Occurs when you convert a POST request to a GET request with a long query information
WiredHome 44:71f09e4255f4 244 Unsupported_Media_Type = 415, ///< The server will not accept the request, because the media type is not supported
WiredHome 44:71f09e4255f4 245 // 416 Requested Range Not Satisfiable The client has asked for a portion of the file, but the server cannot supply that portion
WiredHome 44:71f09e4255f4 246 // 417 Expectation Failed The server cannot meet the requirements of the Expect request-header field
WiredHome 44:71f09e4255f4 247
WiredHome 44:71f09e4255f4 248 // 5xx: Server Error
WiredHome 44:71f09e4255f4 249 // Message: Description:
WiredHome 44:71f09e4255f4 250 Server_Error = 500, ///< A generic error message, given when no more specific message is suitable
WiredHome 44:71f09e4255f4 251 // 501 Not Implemented The server either does not recognize the request method, or it lacks the ability to fulfill the request
WiredHome 44:71f09e4255f4 252 // 502 Bad Gateway The server was acting as a gateway or proxy and received an invalid response from the upstream server
WiredHome 44:71f09e4255f4 253 // 503 Service Unavailable The server is currently unavailable (overloaded or down)
WiredHome 44:71f09e4255f4 254 // 504 Gateway Timeout The server was acting as a gateway or proxy and did not receive a timely response from the upstream server
WiredHome 44:71f09e4255f4 255 // 505 HTTP Version Not Supported The server does not support the HTTP protocol version used in the request
WiredHome 44:71f09e4255f4 256 // 511 Network Authentication Required The client needs to authenticate to gain network access
WiredHome 44:71f09e4255f4 257 } HeaderCodes;
WiredHome 44:71f09e4255f4 258
WiredHome 12:109bf1558300 259 /**
WiredHome 3:17928786bdb5 260 * This is the prototype for custom handlers that are activated via a callback
WiredHome 0:729320f63c5c 261 *
WiredHome 37:0cb2774e2410 262 * This callback gets overloaded for a few purposes, which can be identified by the
WiredHome 37:0cb2774e2410 263 * \see CallBackType parameter.
WiredHome 37:0cb2774e2410 264 *
WiredHome 27:90a1f5a5392f 265 * @li CONTENT_LENGTH_REQUEST - the server is asking the callback if it wants to receive the message,
WiredHome 27:90a1f5a5392f 266 * which may require significant memory. If the request is accepted, true should be returned.
WiredHome 27:90a1f5a5392f 267 * If the request is denied, false should be returned.
WiredHome 27:90a1f5a5392f 268 * @li DATA_TRANSFER - the server is handing off a large body of data, which was accepted based
WiredHome 27:90a1f5a5392f 269 * on the CONTENT_LENGTH_REQUEST callback. The data is now available for processing.
WiredHome 27:90a1f5a5392f 270 * The callback should return true to continue the processing.
WiredHome 12:109bf1558300 271 * @li SEND_PAGE - the callback should now send the html page, using as many svr->send() as needed.
WiredHome 29:00116fc9da74 272 * When the callback returns, it should always indicate true that it has sent the page.
WiredHome 27:90a1f5a5392f 273 *
WiredHome 27:90a1f5a5392f 274 * @note The queryParams pointer purpose depends on the callback type.
WiredHome 33:ef165a67ab22 275 * For CONTENT_LENGTH_REQUEST, the pointer points to the name=value pairs from the
WiredHome 27:90a1f5a5392f 276 * header.
WiredHome 33:ef165a67ab22 277 * For DATA_TRANSFER, the pointer points to the start of the actual data.
WiredHome 29:00116fc9da74 278 * For SEND_PAGE, ... <to be determined>
WiredHome 12:109bf1558300 279 *
WiredHome 48:078adbe279ac 280 * @param[in] svr is a handle to this class, so the callback has access to member functions
WiredHome 48:078adbe279ac 281 * @param[in] type is the callback type @see CallBackType
WiredHome 48:078adbe279ac 282 * @param[in] path is the pointer to a large block of information being transferred. This pointer
WiredHome 37:0cb2774e2410 283 * references a dynamically managed resource, so any information of value must be
WiredHome 37:0cb2774e2410 284 * extracted from here, and not referenced into this memory space.
WiredHome 48:078adbe279ac 285 * @param[in] queryParams is a pointer based on the callback type.
WiredHome 48:078adbe279ac 286 * @param[in] count is the number of items - for type = CONTENT_LENGTH_REQUEST this is the number of
WiredHome 33:ef165a67ab22 287 * name=value pars in the queryParams parameter, and for the DATA_TRANSFER this is the
WiredHome 33:ef165a67ab22 288 * number of bytes being passed in the path parameters.
WiredHome 33:ef165a67ab22 289 * @return one of the @see CallBackResults signals indicating error or successes
WiredHome 0:729320f63c5c 290 */
WiredHome 37:0cb2774e2410 291 typedef CallBackResults (* Handler)(HTTPServer * svr, CallBackType type, const char *path,
WiredHome 37:0cb2774e2410 292 const namevalue *queryParams, int queryParamCount);
WiredHome 12:109bf1558300 293
WiredHome 0:729320f63c5c 294 /**
WiredHome 0:729320f63c5c 295 * Create the HTTPServer object.
WiredHome 12:109bf1558300 296 *
WiredHome 48:078adbe279ac 297 * @param[in] port is the optional parameter for the port number to use, default is 80.
WiredHome 48:078adbe279ac 298 * @param[in] webroot is a file system path to the root folder for the web space. If any trailing '/'
WiredHome 27:90a1f5a5392f 299 * is included (e.g. "/web/path/") it will be removed (to "/web/path").
WiredHome 48:078adbe279ac 300 * @param[in] maxheaderParams defines the maximum number of parameters to extract from a header
WiredHome 37:0cb2774e2410 301 * (Host: 192..\r\nConnection: keep-alive\r\n...)
WiredHome 48:078adbe279ac 302 * @param[in] maxqueryParams defines the maximum number of query parameters to a dynamic function
WiredHome 37:0cb2774e2410 303 * (and the memory to support them).
WiredHome 48:078adbe279ac 304 * @param[in] maxdynamicpages defines the maximum number of dynamic pages that can be registered.
WiredHome 48:078adbe279ac 305 * @param[in] pc is the serial port for debug information (I should transform this to a log interface)
WiredHome 48:078adbe279ac 306 * @param[in] allocforheader is the memory allocation to support the largest expected header from a client
WiredHome 48:078adbe279ac 307 * @param[in] allocforfile is the memory allocation to support sending a file to the client. This is
WiredHome 37:0cb2774e2410 308 * typically sized to fit an ethernet frame.
WiredHome 48:078adbe279ac 309 * @param[in] blockingtime is the time that the Poll process will pause, waiting for input.
WiredHome 0:729320f63c5c 310 */
WiredHome 39:0427544a5c08 311 HTTPServer(int port = 80, const char * webroot = "/", int maxheaderParams = 15,
WiredHome 37:0cb2774e2410 312 int maxqueryParams = 30, int maxdynamicpages = 10,
WiredHome 48:078adbe279ac 313 PC * pc = NULL, int _allocforheader = MAX_HEADER_SIZE, int _allocforfile = FILESEND_BUF_SIZE,
WiredHome 48:078adbe279ac 314 int blockingtime = 10);
WiredHome 12:109bf1558300 315
WiredHome 0:729320f63c5c 316 /**
WiredHome 3:17928786bdb5 317 * Destructor, which can clean up memory.
WiredHome 0:729320f63c5c 318 */
WiredHome 0:729320f63c5c 319 ~HTTPServer();
WiredHome 12:109bf1558300 320
WiredHome 0:729320f63c5c 321 /**
WiredHome 27:90a1f5a5392f 322 * Get the path to the webroot, for applications that need to
WiredHome 27:90a1f5a5392f 323 * reference the file system relative to that point.
WiredHome 24:062431453abb 324 *
WiredHome 27:90a1f5a5392f 325 * @note The returned value may not be exactly as set at instantiation
WiredHome 27:90a1f5a5392f 326 * as trailing '/' were removed (unless the web root == "/").
WiredHome 27:90a1f5a5392f 327 * e.g. "/msc/web/" becomes "/msc/web"
WiredHome 27:90a1f5a5392f 328 *
WiredHome 27:90a1f5a5392f 329 * @returns pointer to the webroot string.
WiredHome 24:062431453abb 330 */
WiredHome 24:062431453abb 331 const char * GetWebRoot() {
WiredHome 27:90a1f5a5392f 332 return (const char *)webroot;
WiredHome 27:90a1f5a5392f 333 };
WiredHome 24:062431453abb 334
WiredHome 44:71f09e4255f4 335
WiredHome 44:71f09e4255f4 336 /**
WiredHome 44:71f09e4255f4 337 * Search a haystack of name:value pairs for the needle.
WiredHome 44:71f09e4255f4 338 *
WiredHome 44:71f09e4255f4 339 * This is a case-sensitive search. If it cannot find an alias,
WiredHome 44:71f09e4255f4 340 * it returns the needle.
WiredHome 44:71f09e4255f4 341 *
WiredHome 44:71f09e4255f4 342 * This is used in the web server for conveniently mapping long filenames
WiredHome 44:71f09e4255f4 343 * to short filenames if you are using the LocalFileSystem which only
WiredHome 44:71f09e4255f4 344 * supports short filenames.
WiredHome 44:71f09e4255f4 345 *
WiredHome 44:71f09e4255f4 346 * @code
WiredHome 44:71f09e4255f4 347 * char * ptr;
WiredHome 44:71f09e4255f4 348 * namevalue list[] = {
WiredHome 44:71f09e4255f4 349 * {"/local/longfilename.ext", "/local/short.ext"},
WiredHome 44:71f09e4255f4 350 * {"/local/verylongname2.ext", "/local/verylo~1.ext"},
WiredHome 44:71f09e4255f4 351 * {NULL, NULL}
WiredHome 44:71f09e4255f4 352 * };
WiredHome 44:71f09e4255f4 353 *
WiredHome 44:71f09e4255f4 354 * ptr = FindAlias(list, "/local/verylongname2.ext");
WiredHome 44:71f09e4255f4 355 * // ptr now references "/local/verylo~1.ext"
WiredHome 44:71f09e4255f4 356 * @endcode
WiredHome 44:71f09e4255f4 357 *
WiredHome 44:71f09e4255f4 358 * @param[in] haystack is the NULL terminated namevalue pair list.
WiredHome 44:71f09e4255f4 359 * @param[in] needle is a pointer to the name to find.
WiredHome 44:71f09e4255f4 360 * @returns the alias (value) if the needle is found, otherwise
WiredHome 44:71f09e4255f4 361 * returns the needle.
WiredHome 44:71f09e4255f4 362 */
WiredHome 44:71f09e4255f4 363 const char * FindAlias(const namevalue * haystack, const char * needle);
WiredHome 44:71f09e4255f4 364
WiredHome 44:71f09e4255f4 365
WiredHome 44:71f09e4255f4 366 /**
WiredHome 44:71f09e4255f4 367 * Register a list of filename aliases to webroot.
WiredHome 44:71f09e4255f4 368 *
WiredHome 44:71f09e4255f4 369 * Some uses of this could be on the LocalFileSystem, which only supports
WiredHome 44:71f09e4255f4 370 * an 8.3 naming convention. This API lets you register a list of
WiredHome 44:71f09e4255f4 371 * name:value pairs, where the name is the long filename and the
WiredHome 44:71f09e4255f4 372 * value is the corresponding short filename.
WiredHome 44:71f09e4255f4 373 *
WiredHome 44:71f09e4255f4 374 * @param[in] namevaluelist is a pointer to a NULL terminated long
WiredHome 44:71f09e4255f4 375 * to short filename list.
WiredHome 44:71f09e4255f4 376 */
WiredHome 44:71f09e4255f4 377 void RegisterFilenameAliasList(const namevalue * namevaluelist);
WiredHome 44:71f09e4255f4 378
WiredHome 24:062431453abb 379 /**
WiredHome 3:17928786bdb5 380 * The process to call whenever there is free time, as this basically does
WiredHome 0:729320f63c5c 381 * all the work to monitor for connections and handle replies.
WiredHome 2:a29c32190037 382 *
WiredHome 44:71f09e4255f4 383 * Activate this API as often as you can, typically from the loop in main.
WiredHome 44:71f09e4255f4 384 *
WiredHome 48:078adbe279ac 385 * @note This API will pause execution for the "blocking time" value configured
WiredHome 48:078adbe279ac 386 * in the constructor.
WiredHome 0:729320f63c5c 387 */
WiredHome 2:a29c32190037 388 void Poll();
WiredHome 12:109bf1558300 389
WiredHome 0:729320f63c5c 390 /**
WiredHome 12:109bf1558300 391 * Send typical header data, and some optional data back to the client.
WiredHome 3:17928786bdb5 392 *
WiredHome 3:17928786bdb5 393 * This forms and sends the typical header back to the client. It may also send
WiredHome 3:17928786bdb5 394 * optional data (which must end with "\r\n"). It then sends the second newline
WiredHome 3:17928786bdb5 395 * sequence that signals the end of the header.
WiredHome 0:729320f63c5c 396 *
WiredHome 44:71f09e4255f4 397 * @code
WiredHome 44:71f09e4255f4 398 * svr->header(200, "OK", "Content-Type: text/html\r\n");
WiredHome 44:71f09e4255f4 399 * ...
WiredHome 44:71f09e4255f4 400 * svr->header(200, "OK", "Content-Type: text/html\r\n", "SpecialParam: 13\r\n");
WiredHome 44:71f09e4255f4 401 * svr->header("NextParam: 14\r\n");
WiredHome 44:71f09e4255f4 402 * svr->header(""); // sends the final \r\n to end the header
WiredHome 44:71f09e4255f4 403 * @endcode
WiredHome 44:71f09e4255f4 404 *
WiredHome 44:71f09e4255f4 405 * @param[in] code is the optional return code; 200 = OK, if not provided then 404 = Not found is returned
WiredHome 44:71f09e4255f4 406 * @param[in] code_text is the text to align with the code (e.g. 404, "Not Found")
WiredHome 44:71f09e4255f4 407 * @param[in] content_type is a pointer to "Content-Type: text/html\r\n" (for example). The string
WiredHome 44:71f09e4255f4 408 * must have a \r\n termination. If this parameter is NULL, no alternate is substituted.
WiredHome 44:71f09e4255f4 409 * @param[in] optional_text is a pointer to any other text that is part of the header, which must
WiredHome 44:71f09e4255f4 410 * have \r\n termination. It is permissible to string several header items together,
WiredHome 44:71f09e4255f4 411 * each with the \r\n termination (which includes \r\n termination at the end).
WiredHome 44:71f09e4255f4 412 * If this parameter is NULL, a standard template response will be sent consisting
WiredHome 44:71f09e4255f4 413 * of "Max-age: 0\r\nServer: Smart_Server v0.2\r\nConnection: close\r\n\r\n"
WiredHome 44:71f09e4255f4 414 * If this parameter is not NULL, the user must call headerend(), or ensure that
WiredHome 44:71f09e4255f4 415 * the termination double (\r\n\r\n) ends the optional_text.
WiredHome 0:729320f63c5c 416 */
WiredHome 44:71f09e4255f4 417 void header(HeaderCodes code = Not_Found, const char * code_text = "Not Found", const char * content_type = NULL,
WiredHome 37:0cb2774e2410 418 const char * optional_text = NULL);
WiredHome 0:729320f63c5c 419
WiredHome 0:729320f63c5c 420 /**
WiredHome 44:71f09e4255f4 421 * Send a fragment of a header to the client.
WiredHome 44:71f09e4255f4 422 *
WiredHome 44:71f09e4255f4 423 * This API lets you send header information a fragment at a time. A fragment can be a single
WiredHome 44:71f09e4255f4 424 * line of text, or it can be several strung together with \r\n.
WiredHome 44:71f09e4255f4 425 *
WiredHome 44:71f09e4255f4 426 * @param[in] partialheader is a pointer to \r\n terminated text. If partial is a pointer to NULL,
WiredHome 44:71f09e4255f4 427 * then a terminating \r\n is sent, which ends the header record.
WiredHome 44:71f09e4255f4 428 */
WiredHome 44:71f09e4255f4 429 void header(const char * partialheader);
WiredHome 44:71f09e4255f4 430
WiredHome 44:71f09e4255f4 431 /**
WiredHome 0:729320f63c5c 432 * Send text to the client
WiredHome 0:729320f63c5c 433 *
WiredHome 3:17928786bdb5 434 * This sends the specified text to the client. If the number of bytes is not set,
WiredHome 3:17928786bdb5 435 * then it calculates the number of bytes as a string. For binary transfers, the
WiredHome 3:17928786bdb5 436 * number of bytes to send is required for proper operation.
WiredHome 3:17928786bdb5 437 *
WiredHome 44:71f09e4255f4 438 * @param[in] msg is the text string to send
WiredHome 44:71f09e4255f4 439 * @param[in] bytes is the number of bytes to send. If not set, then strlen is calculated.
WiredHome 0:729320f63c5c 440 */
WiredHome 0:729320f63c5c 441 void send(const char * msg, int bytes = -1);
WiredHome 12:109bf1558300 442
WiredHome 0:729320f63c5c 443 /**
WiredHome 44:71f09e4255f4 444 * Get the size of the file
WiredHome 44:71f09e4255f4 445 *
WiredHome 44:71f09e4255f4 446 * This returns the size of the file. If the specified file is not found, it returns zero.
WiredHome 44:71f09e4255f4 447 *
WiredHome 44:71f09e4255f4 448 * @param[in] filename is the file to read.
WiredHome 44:71f09e4255f4 449 * @returns the size of the file, or zero if the file was not found/opened.
WiredHome 44:71f09e4255f4 450 */
WiredHome 44:71f09e4255f4 451 uint32_t FileSize(const char * filename);
WiredHome 44:71f09e4255f4 452
WiredHome 44:71f09e4255f4 453 /**
WiredHome 3:17928786bdb5 454 * Send a referenced file to the client, including the header
WiredHome 3:17928786bdb5 455 *
WiredHome 3:17928786bdb5 456 * This sends a file from the filesystem to the client. It must be of a supported type
WiredHome 3:17928786bdb5 457 * in order to properly create the header.
WiredHome 0:729320f63c5c 458 *
WiredHome 44:71f09e4255f4 459 * @param[in] filename is the fully qualified path and filename
WiredHome 44:71f09e4255f4 460 * @param[in] filetype is the header information (e.g. "Content-Type: application/pdf")
WiredHome 0:729320f63c5c 461 * @return true if it thinks it sent ok, false otherwise.
WiredHome 0:729320f63c5c 462 */
WiredHome 0:729320f63c5c 463 bool SendFile(const char * filename, const char * filetype);
WiredHome 12:109bf1558300 464
WiredHome 12:109bf1558300 465 /**
WiredHome 0:729320f63c5c 466 * register a handler for a specific URL.
WiredHome 0:729320f63c5c 467 *
WiredHome 3:17928786bdb5 468 * This api lets you register a dynamic handler in the web server. This is
WiredHome 3:17928786bdb5 469 * most useful for interactive web pages, rather than simply serving static
WiredHome 3:17928786bdb5 470 * pages.
WiredHome 3:17928786bdb5 471 *
WiredHome 3:17928786bdb5 472 * @code
WiredHome 12:109bf1558300 473 *
WiredHome 3:17928786bdb5 474 * ...
WiredHome 44:71f09e4255f4 475 * svr.RegisterHandler("/dyn1", SimpleDynamicPage);
WiredHome 3:17928786bdb5 476 * ...
WiredHome 3:17928786bdb5 477 *
WiredHome 46:eaa86d48be6f 478 * HTTPServer::CallBackResults SimpleDynamicPage(HTTPServer *svr, HTTPServer::CallBackType type, const char * path,
WiredHome 37:0cb2774e2410 479 * const HTTPServer::namevalue *queryParams, int queryParamCount) {
WiredHome 3:17928786bdb5 480 * char buf[100];
WiredHome 46:eaa86d48be6f 481 * HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
WiredHome 12:109bf1558300 482 *
WiredHome 3:17928786bdb5 483 * switch (type) {
WiredHome 3:17928786bdb5 484 * case HTTPServer::SEND_PAGE:
WiredHome 46:eaa86d48be6f 485 * svr->header(HTTPServer::OK, "OK", "Content-Type: text/html\r\n");
WiredHome 3:17928786bdb5 486 * svr->send("<html><head><title>Dynamic Page</title></head>\r\n");
WiredHome 3:17928786bdb5 487 * svr->send("<body>\r\n");
WiredHome 3:17928786bdb5 488 * svr->send("This page was generated dynamically. Create your own name=value pairs on the URL "
WiredHome 3:17928786bdb5 489 * "which uses the GET method.<br/>\r\n");
WiredHome 13:8975d7928678 490 * sprintf(buf, "%d parameters passed to {%s}:<br/>\r\n", queryParamCount, path);
WiredHome 3:17928786bdb5 491 * svr->send(buf);
WiredHome 13:8975d7928678 492 * for (int i=0; i<queryParamCount; i++) {
WiredHome 13:8975d7928678 493 * sprintf(buf, "%d: %s = %s<br/>\r\n", i, queryParams[i].name, queryParams[i].value);
WiredHome 3:17928786bdb5 494 * svr->send(buf);
WiredHome 3:17928786bdb5 495 * }
WiredHome 3:17928786bdb5 496 * svr->send("Stats:<br/>\r\n");
WiredHome 3:17928786bdb5 497 * sprintf(buf,"Free memory space: %d<br/>\r\n", Free());
WiredHome 3:17928786bdb5 498 * svr->send(buf);
WiredHome 3:17928786bdb5 499 * sprintf(buf,"Max Header size: %d<br/>\r\n", svr->GetMaxHeaderSize());
WiredHome 3:17928786bdb5 500 * svr->send(buf);
WiredHome 3:17928786bdb5 501 * svr->send("<br/><a href='/'>back to main</a></body></html>\r\n");
WiredHome 46:eaa86d48be6f 502 * ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:17928786bdb5 503 * break;
WiredHome 3:17928786bdb5 504 * case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 46:eaa86d48be6f 505 * ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:17928786bdb5 506 * break;
WiredHome 3:17928786bdb5 507 * case HTTPServer::DATA_TRANSFER:
WiredHome 46:eaa86d48be6f 508 * ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:17928786bdb5 509 * break;
WiredHome 3:17928786bdb5 510 * default:
WiredHome 46:eaa86d48be6f 511 * ret = HTTPServer::ACCEPT_ERROR;
WiredHome 3:17928786bdb5 512 * break;
WiredHome 3:17928786bdb5 513 * }
WiredHome 46:eaa86d48be6f 514 * return ret;
WiredHome 3:17928786bdb5 515 * }
WiredHome 3:17928786bdb5 516 * @endcode
WiredHome 3:17928786bdb5 517 *
WiredHome 44:71f09e4255f4 518 * @param[in] path to register
WiredHome 44:71f09e4255f4 519 * @param[in] callback of type Handler
WiredHome 0:729320f63c5c 520 * @return true if successfully registered
WiredHome 0:729320f63c5c 521 */
WiredHome 0:729320f63c5c 522 bool RegisterHandler(const char * path, Handler callback);
WiredHome 12:109bf1558300 523
WiredHome 0:729320f63c5c 524 /**
WiredHome 16:6ebacf2946d8 525 * determine if the named file is a supported type (htm, html, jpg, etc)
WiredHome 0:729320f63c5c 526 *
WiredHome 3:17928786bdb5 527 * if you pass in a filename, it will attempt to extract the extension
WiredHome 3:17928786bdb5 528 * and compare that to the list of supported file types. If it finds a
WiredHome 3:17928786bdb5 529 * match, then it will return a pointer to the content-type string.
WiredHome 3:17928786bdb5 530 *
WiredHome 3:17928786bdb5 531 * @code
WiredHome 3:17928786bdb5 532 * fType = GetSupportedType("mypix.jpg");
WiredHome 3:17928786bdb5 533 * if (fType) {
WiredHome 3:17928786bdb5 534 * ...
WiredHome 3:17928786bdb5 535 * @endcode
WiredHome 12:109bf1558300 536 *
WiredHome 44:71f09e4255f4 537 * @param[in] filename is the filename to test, based on the extension
WiredHome 0:729320f63c5c 538 * @return pointer to a Content-Type string if supported, or NULL if not.
WiredHome 0:729320f63c5c 539 */
WiredHome 0:729320f63c5c 540 const char * GetSupportedType(const char * filename);
WiredHome 0:729320f63c5c 541
WiredHome 0:729320f63c5c 542 /**
WiredHome 39:0427544a5c08 543 * search the available query parameters for 'name' and if found, return the 'value'
WiredHome 0:729320f63c5c 544 *
WiredHome 12:109bf1558300 545 * After the querystring is parsed, the server maintains an array of
WiredHome 3:17928786bdb5 546 * name=value pairs. This Get function will search for the passed in name
WiredHome 3:17928786bdb5 547 * and provide access to the value.
WiredHome 3:17928786bdb5 548 *
WiredHome 3:17928786bdb5 549 * @code
WiredHome 3:17928786bdb5 550 * BusOut leds(LED1,LED2,LED3,LED4);
WiredHome 3:17928786bdb5 551 * ...
WiredHome 3:17928786bdb5 552 * leds = atoi(svr->GetParameter("leds"));
WiredHome 3:17928786bdb5 553 * @endcode
WiredHome 3:17928786bdb5 554 *
WiredHome 44:71f09e4255f4 555 * @param[in] name is the name to search for
WiredHome 0:729320f63c5c 556 * @return pointer to the value, or NULL
WiredHome 0:729320f63c5c 557 */
WiredHome 0:729320f63c5c 558 const char * GetParameter(const char * name);
WiredHome 0:729320f63c5c 559
WiredHome 0:729320f63c5c 560 /**
WiredHome 39:0427544a5c08 561 * get a pointer to a name-value pair based on the index.
WiredHome 39:0427544a5c08 562 *
WiredHome 44:71f09e4255f4 563 * @param[in] index is the item being referenced
WiredHome 39:0427544a5c08 564 * @return pointer to the namevalue, or NULL
WiredHome 39:0427544a5c08 565 */
WiredHome 44:71f09e4255f4 566 const namevalue * GetParameter(int index);
WiredHome 39:0427544a5c08 567
WiredHome 39:0427544a5c08 568 /**
WiredHome 39:0427544a5c08 569 * Get the count of query parameters from the active transaction.
WiredHome 39:0427544a5c08 570 *
WiredHome 39:0427544a5c08 571 * @returns count of parameters.
WiredHome 39:0427544a5c08 572 */
WiredHome 39:0427544a5c08 573 int GetParameterCount(void)
WiredHome 39:0427544a5c08 574 {
WiredHome 39:0427544a5c08 575 return queryParamCount;
WiredHome 39:0427544a5c08 576 };
WiredHome 39:0427544a5c08 577
WiredHome 39:0427544a5c08 578 /**
WiredHome 39:0427544a5c08 579 * search the available post parameters for 'name' and if found, return the 'value'
WiredHome 39:0427544a5c08 580 *
WiredHome 39:0427544a5c08 581 * After the post parameter string is parsed, the server maintains an array of
WiredHome 39:0427544a5c08 582 * name=value pairs. This Get function will search for the passed in name
WiredHome 39:0427544a5c08 583 * and provide access to the value.
WiredHome 39:0427544a5c08 584 *
WiredHome 39:0427544a5c08 585 * @code
WiredHome 39:0427544a5c08 586 * BusOut leds(LED1,LED2,LED3,LED4);
WiredHome 39:0427544a5c08 587 * ...
WiredHome 39:0427544a5c08 588 * leds = atoi(svr->GetPostParameter("leds"));
WiredHome 39:0427544a5c08 589 * @endcode
WiredHome 39:0427544a5c08 590 *
WiredHome 44:71f09e4255f4 591 * @param[in] name is the name to search for
WiredHome 39:0427544a5c08 592 * @return pointer to the value, or NULL
WiredHome 39:0427544a5c08 593 */
WiredHome 39:0427544a5c08 594 const char * GetPostParameter(const char * name);
WiredHome 39:0427544a5c08 595
WiredHome 39:0427544a5c08 596 /**
WiredHome 39:0427544a5c08 597 * get a pointer to a post parameter name-value pair based on the index.
WiredHome 39:0427544a5c08 598 *
WiredHome 44:71f09e4255f4 599 * @param[in] index is the item being referenced
WiredHome 39:0427544a5c08 600 * @return pointer to the namevalue, or NULL
WiredHome 39:0427544a5c08 601 */
WiredHome 39:0427544a5c08 602 namevalue * GetPostParameter(int index);
WiredHome 39:0427544a5c08 603
WiredHome 39:0427544a5c08 604 /**
WiredHome 39:0427544a5c08 605 * Get the count of post parameters from the active transaction.
WiredHome 39:0427544a5c08 606 *
WiredHome 39:0427544a5c08 607 * @returns count of parameters.
WiredHome 39:0427544a5c08 608 */
WiredHome 39:0427544a5c08 609 int GetPostParameterCount(void)
WiredHome 39:0427544a5c08 610 {
WiredHome 39:0427544a5c08 611 return postParamCount;
WiredHome 39:0427544a5c08 612 };
WiredHome 39:0427544a5c08 613
WiredHome 39:0427544a5c08 614 /**
WiredHome 12:109bf1558300 615 * Parse the text string into name=value parameters.
WiredHome 3:17928786bdb5 616 *
WiredHome 12:109bf1558300 617 * This will directly modify the referenced string. If there is a
WiredHome 3:17928786bdb5 618 * #fragment_id on the end of the string, it will be removed.
WiredHome 0:729320f63c5c 619 *
WiredHome 44:71f09e4255f4 620 * @param[in] qP is a pointer to a namevalue set
WiredHome 44:71f09e4255f4 621 * @param[in] qpCount is a pointer to a counter of what is in the set
WiredHome 44:71f09e4255f4 622 * @param[in] maxP is the maximum number of parameters for which space has been allocated.
WiredHome 44:71f09e4255f4 623 * @param[in,out] pName is a pointer to the string.
WiredHome 37:0cb2774e2410 624 * @returns The total number of items that have been parsed,
WiredHome 37:0cb2774e2410 625 * which can include a count from a url query string.
WiredHome 0:729320f63c5c 626 */
WiredHome 39:0427544a5c08 627 int ParseParameters(namevalue * qP, int * qpCount, int maxP, char * pName);
WiredHome 12:109bf1558300 628
WiredHome 0:729320f63c5c 629 /**
WiredHome 16:6ebacf2946d8 630 * Unescape string converts a coded string "in place" into a normal string.
WiredHome 3:17928786bdb5 631 *
WiredHome 3:17928786bdb5 632 * A query string will have a number of characters replaced for communication
WiredHome 3:17928786bdb5 633 * which includes spaces, quotes, question marks and more. Most of them
WiredHome 12:109bf1558300 634 * will be replaced with a %xx format, where xx is the hex code for the
WiredHome 3:17928786bdb5 635 * character. Since the string will only get shorter when this happens
WiredHome 3:17928786bdb5 636 * the operation is performed in place.
WiredHome 3:17928786bdb5 637 *
WiredHome 0:729320f63c5c 638 * this "This%20is%20a%20question%3F%20and%20an%20answer."
WiredHome 12:109bf1558300 639 *
WiredHome 0:729320f63c5c 640 * becomes "This is a question? and an answer."
WiredHome 3:17928786bdb5 641 *
WiredHome 0:729320f63c5c 642 * @note '+' is another form of space, so is converted to a space before the %xx
WiredHome 0:729320f63c5c 643 *
WiredHome 44:71f09e4255f4 644 * @param[in,out] encoded string to be converted
WiredHome 0:729320f63c5c 645 */
WiredHome 0:729320f63c5c 646 void UnescapeString(char * encoded);
WiredHome 12:109bf1558300 647
WiredHome 12:109bf1558300 648 /**
WiredHome 16:6ebacf2946d8 649 * This is used to force a connection to close.
WiredHome 3:17928786bdb5 650 *
WiredHome 44:71f09e4255f4 651 * @note When WiFly is the interface, this switches the module into
WiredHome 44:71f09e4255f4 652 * command mode, performs the close, and then switches it back to data mode.
WiredHome 44:71f09e4255f4 653 * So, this is a time-expensive command.
WiredHome 7:99ad7a67f05e 654 *
WiredHome 7:99ad7a67f05e 655 * @returns true if successful
WiredHome 0:729320f63c5c 656 */
WiredHome 7:99ad7a67f05e 657 bool close_connection();
WiredHome 12:109bf1558300 658
WiredHome 3:17928786bdb5 659 /**
WiredHome 16:6ebacf2946d8 660 * Diagnostic to get the size of the largest header.
WiredHome 3:17928786bdb5 661 *
WiredHome 12:109bf1558300 662 * This is a diagnostic function, so you can resize the allocated
WiredHome 12:109bf1558300 663 * buffer for your application. With proper sizing, more of the
WiredHome 3:17928786bdb5 664 * system memory is available for your application.
WiredHome 3:17928786bdb5 665 *
WiredHome 3:17928786bdb5 666 * @code
WiredHome 3:17928786bdb5 667 * sprintf(buf,"Max Header size: %d<br/>\r\n", svr->GetMaxHeaderSize());
WiredHome 3:17928786bdb5 668 * svr->send(buf);
WiredHome 3:17928786bdb5 669 * @endcode
WiredHome 12:109bf1558300 670 *
WiredHome 3:17928786bdb5 671 * @returns size in bytes of the larger header measured.
WiredHome 3:17928786bdb5 672 */
WiredHome 3:17928786bdb5 673 int GetMaxHeaderSize();
WiredHome 3:17928786bdb5 674
WiredHome 13:8975d7928678 675 /**
WiredHome 16:6ebacf2946d8 676 * Get a value from the http header, if it exists.
WiredHome 13:8975d7928678 677 *
WiredHome 48:078adbe279ac 678 * @param[in] hdr is the string to search for (e.g. "Content-Length")
WiredHome 48:078adbe279ac 679 * @returns pointer to the value associated with that header.
WiredHome 13:8975d7928678 680 * @returns NULL if the header is not found.
WiredHome 13:8975d7928678 681 */
WiredHome 13:8975d7928678 682 const char * GetHeaderValue(const char * hdr);
WiredHome 3:17928786bdb5 683
WiredHome 3:17928786bdb5 684 /**
WiredHome 3:17928786bdb5 685 * Performance parameter
WiredHome 3:17928786bdb5 686 */
WiredHome 3:17928786bdb5 687 typedef struct SW_PERFPARAM {
WiredHome 3:17928786bdb5 688 unsigned long long TotalTime_us;
WiredHome 3:17928786bdb5 689 unsigned long Samples;
WiredHome 3:17928786bdb5 690 unsigned long MaxTime_us;
WiredHome 3:17928786bdb5 691 } SW_PerformanceParam;
WiredHome 12:109bf1558300 692
WiredHome 3:17928786bdb5 693 /**
WiredHome 3:17928786bdb5 694 * Performance metrics
WiredHome 3:17928786bdb5 695 */
WiredHome 3:17928786bdb5 696 typedef struct SW_PERFDATA {
WiredHome 17:69ff00ce39f4 697 SW_PerformanceParam ConnectionAccepted;
WiredHome 17:69ff00ce39f4 698 SW_PerformanceParam HeaderParsed;
WiredHome 17:69ff00ce39f4 699 SW_PerformanceParam ResponseSent;
WiredHome 17:69ff00ce39f4 700 SW_PerformanceParam ConnectionClosed;
WiredHome 3:17928786bdb5 701 //SW_PerformanceParam SendFile;
WiredHome 3:17928786bdb5 702 } SW_PerformanceData;
WiredHome 12:109bf1558300 703
WiredHome 3:17928786bdb5 704 /**
WiredHome 3:17928786bdb5 705 * Get performance metrics from the web server.
WiredHome 3:17928786bdb5 706 *
WiredHome 3:17928786bdb5 707 * This is a diagnostic function, and gathers data on the internal
WiredHome 3:17928786bdb5 708 * performance of the server, as it works various actions.
WiredHome 3:17928786bdb5 709 *
WiredHome 44:71f09e4255f4 710 * @param[in] p is a pointer to a SW_PerformanceData structure to be populated
WiredHome 3:17928786bdb5 711 */
WiredHome 3:17928786bdb5 712 void GetPerformanceData(SW_PerformanceData * p);
WiredHome 12:109bf1558300 713
WiredHome 3:17928786bdb5 714 /**
WiredHome 3:17928786bdb5 715 * Reset performance metrics.
WiredHome 3:17928786bdb5 716 */
WiredHome 3:17928786bdb5 717 void ResetPerformanceData();
WiredHome 17:69ff00ce39f4 718
WiredHome 17:69ff00ce39f4 719 /**
WiredHome 17:69ff00ce39f4 720 * Get performance clock
WiredHome 17:69ff00ce39f4 721 */
WiredHome 17:69ff00ce39f4 722 unsigned int GetPerformanceClock();
WiredHome 12:109bf1558300 723
WiredHome 0:729320f63c5c 724 private:
WiredHome 0:729320f63c5c 725 char * webroot;
WiredHome 0:729320f63c5c 726 PC * pc;
WiredHome 0:729320f63c5c 727 TCPSocketServer * server;
WiredHome 0:729320f63c5c 728 TCPSocketConnection client;
WiredHome 0:729320f63c5c 729 char * rewriteWithDefaultFile(char * queryString);
WiredHome 0:729320f63c5c 730 char * rewritePrependWebroot(char * queryString);
WiredHome 13:8975d7928678 731
WiredHome 13:8975d7928678 732 namevalue *queryParams; // Query Parameters from the URL this=that&sky=blue&...
WiredHome 13:8975d7928678 733 int maxqueryParams;
WiredHome 13:8975d7928678 734 int queryParamCount;
WiredHome 13:8975d7928678 735
WiredHome 39:0427544a5c08 736 namevalue *postParams; // Same as Query params, but for post method
WiredHome 39:0427544a5c08 737 int maxPostParams;
WiredHome 39:0427544a5c08 738 int postParamCount;
WiredHome 39:0427544a5c08 739
WiredHome 13:8975d7928678 740 namevalue *headerParams; // Header params Host: 192.168...\r\nConnection: keep-alive\r\n...
WiredHome 13:8975d7928678 741 int maxheaderParams;
WiredHome 13:8975d7928678 742 int headerParamCount;
WiredHome 13:8975d7928678 743
WiredHome 3:17928786bdb5 744 int maxheaderbytes;
WiredHome 3:17928786bdb5 745 char * headerbuffer;
WiredHome 3:17928786bdb5 746 int headerbuffersize;
WiredHome 12:109bf1558300 747
WiredHome 10:9c8d2c6a3469 748 Timer PerformanceTimer;
WiredHome 3:17928786bdb5 749 /**
WiredHome 3:17928786bdb5 750 * Records performance data
WiredHome 12:109bf1558300 751 *
WiredHome 3:17928786bdb5 752 * This will take a pointer to a SW_PerformanceParam, and it will
WiredHome 3:17928786bdb5 753 * take the time when the performance measurement started. It locally
WiredHome 3:17928786bdb5 754 * accesses the current time to measure the elapsed.
WiredHome 3:17928786bdb5 755 *
WiredHome 48:078adbe279ac 756 * @param[in] param is the performance parameter to update
WiredHome 48:078adbe279ac 757 * @param[in] value is the reference time.
WiredHome 3:17928786bdb5 758 * @returns the current time which may be used as the reference time
WiredHome 3:17928786bdb5 759 * for further measurements.
WiredHome 3:17928786bdb5 760 */
WiredHome 16:6ebacf2946d8 761 unsigned int RecordPerformanceData(SW_PerformanceParam * param, unsigned int value);
WiredHome 3:17928786bdb5 762 SW_PerformanceData perfData;
WiredHome 12:109bf1558300 763
WiredHome 3:17928786bdb5 764 typedef struct HANDLER {
WiredHome 0:729320f63c5c 765 char * path;
WiredHome 0:729320f63c5c 766 Handler callback;
WiredHome 0:729320f63c5c 767 } handler;
WiredHome 0:729320f63c5c 768 int maxdynamicpages;
WiredHome 0:729320f63c5c 769 handler *handlers;
WiredHome 0:729320f63c5c 770 int handlercount;
WiredHome 3:17928786bdb5 771
WiredHome 3:17928786bdb5 772 char * queryType;
WiredHome 44:71f09e4255f4 773 char * queryString; // the query string [and 'GET' data] passed on the URL (e.g. ?name1=value1&name2=value2...)
WiredHome 44:71f09e4255f4 774 char * postQueryString; // the post data
WiredHome 44:71f09e4255f4 775 const namevalue * filenameAliasList; // pointer to a filename alias list
WiredHome 44:71f09e4255f4 776
WiredHome 0:729320f63c5c 777 /**
WiredHome 8:262583f054f6 778 * Extract the parameter from the record, by searching for the needle in the haystack.
WiredHome 8:262583f054f6 779 *
WiredHome 8:262583f054f6 780 * The parameter of interest follows the needle, and may be ' ' delimited
WiredHome 0:729320f63c5c 781 * Can damage haystack while processing it.
WiredHome 0:729320f63c5c 782 *
WiredHome 48:078adbe279ac 783 * @param[in] haystack is the record to search
WiredHome 48:078adbe279ac 784 * @param[in] needle is the text to search for, which precedes the text to return
WiredHome 48:078adbe279ac 785 * @param[out] string is the text following the needle
WiredHome 0:729320f63c5c 786 * @return true if it extracted something successfully
WiredHome 0:729320f63c5c 787 */
WiredHome 48:078adbe279ac 788 bool Extract(char * haystack, char * needle, char ** string);
WiredHome 0:729320f63c5c 789
WiredHome 3:17928786bdb5 790 void SendResponse();
WiredHome 29:00116fc9da74 791 HTTPServer::CallBackResults ParseHeader(char * bPtr);
WiredHome 3:17928786bdb5 792 bool CheckDynamicHandlers();
WiredHome 3:17928786bdb5 793
WiredHome 0:729320f63c5c 794 int HexCharToInt(char c);
WiredHome 0:729320f63c5c 795 char HexPairToChar(char * p);
WiredHome 29:00116fc9da74 796
WiredHome 29:00116fc9da74 797 #ifdef DEBUG
WiredHome 29:00116fc9da74 798 void * MyMalloc(int x, int y);
WiredHome 29:00116fc9da74 799 char toP(void * x);
WiredHome 29:00116fc9da74 800 #endif
WiredHome 0:729320f63c5c 801 };
WiredHome 0:729320f63c5c 802 #endif //SW_HTTPSERVER_H
WiredHome 4:f34642902056 803
WiredHome 7:99ad7a67f05e 804