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:
Wed Feb 27 18:06:23 2019 +0000
Revision:
60:d49a346c386f
Parent:
59:9a71ac02c782
Enable header code 302

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 60:d49a346c386f 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 53:e5d96abe5e9b 291 typedef CallBackResults (* Handler)(HTTPServer * svr, CallBackType type, 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 49:cd391662f254 305 * @param[in] blockingtime is the time that the Poll process will pause, waiting for input.
WiredHome 48:078adbe279ac 306 * @param[in] pc is the serial port for debug information (I should transform this to a log interface)
WiredHome 48:078adbe279ac 307 * @param[in] allocforheader is the memory allocation to support the largest expected header from a client
WiredHome 48:078adbe279ac 308 * @param[in] allocforfile is the memory allocation to support sending a file to the client. This is
WiredHome 37:0cb2774e2410 309 * typically sized to fit an ethernet frame.
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 49:cd391662f254 313 int blockingtime = 10,
WiredHome 49:cd391662f254 314 PC * pc = NULL, int _allocforheader = MAX_HEADER_SIZE, int _allocforfile = FILESEND_BUF_SIZE
WiredHome 49:cd391662f254 315 );
WiredHome 12:109bf1558300 316
WiredHome 0:729320f63c5c 317 /**
WiredHome 3:17928786bdb5 318 * Destructor, which can clean up memory.
WiredHome 0:729320f63c5c 319 */
WiredHome 0:729320f63c5c 320 ~HTTPServer();
WiredHome 12:109bf1558300 321
WiredHome 0:729320f63c5c 322 /**
WiredHome 27:90a1f5a5392f 323 * Get the path to the webroot, for applications that need to
WiredHome 27:90a1f5a5392f 324 * reference the file system relative to that point.
WiredHome 24:062431453abb 325 *
WiredHome 27:90a1f5a5392f 326 * @note The returned value may not be exactly as set at instantiation
WiredHome 27:90a1f5a5392f 327 * as trailing '/' were removed (unless the web root == "/").
WiredHome 27:90a1f5a5392f 328 * e.g. "/msc/web/" becomes "/msc/web"
WiredHome 27:90a1f5a5392f 329 *
WiredHome 27:90a1f5a5392f 330 * @returns pointer to the webroot string.
WiredHome 24:062431453abb 331 */
WiredHome 24:062431453abb 332 const char * GetWebRoot() {
WiredHome 27:90a1f5a5392f 333 return (const char *)webroot;
WiredHome 27:90a1f5a5392f 334 };
WiredHome 24:062431453abb 335
WiredHome 44:71f09e4255f4 336
WiredHome 44:71f09e4255f4 337 /**
WiredHome 44:71f09e4255f4 338 * Search a haystack of name:value pairs for the needle.
WiredHome 44:71f09e4255f4 339 *
WiredHome 44:71f09e4255f4 340 * This is a case-sensitive search. If it cannot find an alias,
WiredHome 44:71f09e4255f4 341 * it returns the needle.
WiredHome 44:71f09e4255f4 342 *
WiredHome 44:71f09e4255f4 343 * This is used in the web server for conveniently mapping long filenames
WiredHome 44:71f09e4255f4 344 * to short filenames if you are using the LocalFileSystem which only
WiredHome 44:71f09e4255f4 345 * supports short filenames.
WiredHome 44:71f09e4255f4 346 *
WiredHome 44:71f09e4255f4 347 * @code
WiredHome 44:71f09e4255f4 348 * char * ptr;
WiredHome 44:71f09e4255f4 349 * namevalue list[] = {
WiredHome 44:71f09e4255f4 350 * {"/local/longfilename.ext", "/local/short.ext"},
WiredHome 44:71f09e4255f4 351 * {"/local/verylongname2.ext", "/local/verylo~1.ext"},
WiredHome 44:71f09e4255f4 352 * {NULL, NULL}
WiredHome 44:71f09e4255f4 353 * };
WiredHome 44:71f09e4255f4 354 *
WiredHome 44:71f09e4255f4 355 * ptr = FindAlias(list, "/local/verylongname2.ext");
WiredHome 44:71f09e4255f4 356 * // ptr now references "/local/verylo~1.ext"
WiredHome 44:71f09e4255f4 357 * @endcode
WiredHome 44:71f09e4255f4 358 *
WiredHome 44:71f09e4255f4 359 * @param[in] haystack is the NULL terminated namevalue pair list.
WiredHome 44:71f09e4255f4 360 * @param[in] needle is a pointer to the name to find.
WiredHome 44:71f09e4255f4 361 * @returns the alias (value) if the needle is found, otherwise
WiredHome 44:71f09e4255f4 362 * returns the needle.
WiredHome 44:71f09e4255f4 363 */
WiredHome 44:71f09e4255f4 364 const char * FindAlias(const namevalue * haystack, const char * needle);
WiredHome 44:71f09e4255f4 365
WiredHome 44:71f09e4255f4 366
WiredHome 44:71f09e4255f4 367 /**
WiredHome 44:71f09e4255f4 368 * Register a list of filename aliases to webroot.
WiredHome 44:71f09e4255f4 369 *
WiredHome 44:71f09e4255f4 370 * Some uses of this could be on the LocalFileSystem, which only supports
WiredHome 44:71f09e4255f4 371 * an 8.3 naming convention. This API lets you register a list of
WiredHome 44:71f09e4255f4 372 * name:value pairs, where the name is the long filename and the
WiredHome 44:71f09e4255f4 373 * value is the corresponding short filename.
WiredHome 44:71f09e4255f4 374 *
WiredHome 44:71f09e4255f4 375 * @param[in] namevaluelist is a pointer to a NULL terminated long
WiredHome 44:71f09e4255f4 376 * to short filename list.
WiredHome 44:71f09e4255f4 377 */
WiredHome 44:71f09e4255f4 378 void RegisterFilenameAliasList(const namevalue * namevaluelist);
WiredHome 44:71f09e4255f4 379
WiredHome 24:062431453abb 380 /**
WiredHome 3:17928786bdb5 381 * The process to call whenever there is free time, as this basically does
WiredHome 0:729320f63c5c 382 * all the work to monitor for connections and handle replies.
WiredHome 2:a29c32190037 383 *
WiredHome 44:71f09e4255f4 384 * Activate this API as often as you can, typically from the loop in main.
WiredHome 44:71f09e4255f4 385 *
WiredHome 48:078adbe279ac 386 * @note This API will pause execution for the "blocking time" value configured
WiredHome 48:078adbe279ac 387 * in the constructor.
WiredHome 0:729320f63c5c 388 */
WiredHome 2:a29c32190037 389 void Poll();
WiredHome 12:109bf1558300 390
WiredHome 0:729320f63c5c 391 /**
WiredHome 12:109bf1558300 392 * Send typical header data, and some optional data back to the client.
WiredHome 3:17928786bdb5 393 *
WiredHome 3:17928786bdb5 394 * This forms and sends the typical header back to the client. It may also send
WiredHome 3:17928786bdb5 395 * optional data (which must end with "\r\n"). It then sends the second newline
WiredHome 3:17928786bdb5 396 * sequence that signals the end of the header.
WiredHome 0:729320f63c5c 397 *
WiredHome 44:71f09e4255f4 398 * @code
WiredHome 44:71f09e4255f4 399 * svr->header(200, "OK", "Content-Type: text/html\r\n");
WiredHome 44:71f09e4255f4 400 * ...
WiredHome 44:71f09e4255f4 401 * svr->header(200, "OK", "Content-Type: text/html\r\n", "SpecialParam: 13\r\n");
WiredHome 44:71f09e4255f4 402 * svr->header("NextParam: 14\r\n");
WiredHome 44:71f09e4255f4 403 * svr->header(""); // sends the final \r\n to end the header
WiredHome 44:71f09e4255f4 404 * @endcode
WiredHome 44:71f09e4255f4 405 *
WiredHome 44:71f09e4255f4 406 * @param[in] code is the optional return code; 200 = OK, if not provided then 404 = Not found is returned
WiredHome 44:71f09e4255f4 407 * @param[in] code_text is the text to align with the code (e.g. 404, "Not Found")
WiredHome 44:71f09e4255f4 408 * @param[in] content_type is a pointer to "Content-Type: text/html\r\n" (for example). The string
WiredHome 44:71f09e4255f4 409 * must have a \r\n termination. If this parameter is NULL, no alternate is substituted.
WiredHome 44:71f09e4255f4 410 * @param[in] optional_text is a pointer to any other text that is part of the header, which must
WiredHome 44:71f09e4255f4 411 * have \r\n termination. It is permissible to string several header items together,
WiredHome 44:71f09e4255f4 412 * each with the \r\n termination (which includes \r\n termination at the end).
WiredHome 44:71f09e4255f4 413 * If this parameter is NULL, a standard template response will be sent consisting
WiredHome 44:71f09e4255f4 414 * of "Max-age: 0\r\nServer: Smart_Server v0.2\r\nConnection: close\r\n\r\n"
WiredHome 49:cd391662f254 415 * If this parameter is not NULL, the user must call header(""), or ensure that
WiredHome 44:71f09e4255f4 416 * the termination double (\r\n\r\n) ends the optional_text.
WiredHome 0:729320f63c5c 417 */
WiredHome 44:71f09e4255f4 418 void header(HeaderCodes code = Not_Found, const char * code_text = "Not Found", const char * content_type = NULL,
WiredHome 37:0cb2774e2410 419 const char * optional_text = NULL);
WiredHome 0:729320f63c5c 420
WiredHome 0:729320f63c5c 421 /**
WiredHome 44:71f09e4255f4 422 * Send a fragment of a header to the client.
WiredHome 44:71f09e4255f4 423 *
WiredHome 49:cd391662f254 424 * @code
WiredHome 49:cd391662f254 425 * ...
WiredHome 49:cd391662f254 426 * svr->header("NextParam: 14\r\n");
WiredHome 49:cd391662f254 427 * svr->header(""); // sends the final \r\n to end the header
WiredHome 49:cd391662f254 428 * @endcode
WiredHome 49:cd391662f254 429 *
WiredHome 44:71f09e4255f4 430 * This API lets you send header information a fragment at a time. A fragment can be a single
WiredHome 44:71f09e4255f4 431 * line of text, or it can be several strung together with \r\n.
WiredHome 44:71f09e4255f4 432 *
WiredHome 44:71f09e4255f4 433 * @param[in] partialheader is a pointer to \r\n terminated text. If partial is a pointer to NULL,
WiredHome 44:71f09e4255f4 434 * then a terminating \r\n is sent, which ends the header record.
WiredHome 44:71f09e4255f4 435 */
WiredHome 44:71f09e4255f4 436 void header(const char * partialheader);
WiredHome 44:71f09e4255f4 437
WiredHome 44:71f09e4255f4 438 /**
WiredHome 0:729320f63c5c 439 * Send text to the client
WiredHome 0:729320f63c5c 440 *
WiredHome 3:17928786bdb5 441 * This sends the specified text to the client. If the number of bytes is not set,
WiredHome 3:17928786bdb5 442 * then it calculates the number of bytes as a string. For binary transfers, the
WiredHome 3:17928786bdb5 443 * number of bytes to send is required for proper operation.
WiredHome 3:17928786bdb5 444 *
WiredHome 44:71f09e4255f4 445 * @param[in] msg is the text string to send
WiredHome 44:71f09e4255f4 446 * @param[in] bytes is the number of bytes to send. If not set, then strlen is calculated.
WiredHome 53:e5d96abe5e9b 447 * @returns # of bytes sent, and < 0 for various error codes.
WiredHome 0:729320f63c5c 448 */
WiredHome 53:e5d96abe5e9b 449 int send(const char * msg, int bytes = -1);
WiredHome 12:109bf1558300 450
WiredHome 0:729320f63c5c 451 /**
WiredHome 44:71f09e4255f4 452 * Get the size of the file
WiredHome 44:71f09e4255f4 453 *
WiredHome 44:71f09e4255f4 454 * This returns the size of the file. If the specified file is not found, it returns zero.
WiredHome 44:71f09e4255f4 455 *
WiredHome 44:71f09e4255f4 456 * @param[in] filename is the file to read.
WiredHome 44:71f09e4255f4 457 * @returns the size of the file, or zero if the file was not found/opened.
WiredHome 44:71f09e4255f4 458 */
WiredHome 44:71f09e4255f4 459 uint32_t FileSize(const char * filename);
WiredHome 44:71f09e4255f4 460
WiredHome 44:71f09e4255f4 461 /**
WiredHome 3:17928786bdb5 462 * Send a referenced file to the client, including the header
WiredHome 3:17928786bdb5 463 *
WiredHome 3:17928786bdb5 464 * This sends a file from the filesystem to the client. It must be of a supported type
WiredHome 3:17928786bdb5 465 * in order to properly create the header.
WiredHome 0:729320f63c5c 466 *
WiredHome 44:71f09e4255f4 467 * @param[in] filename is the fully qualified path and filename
WiredHome 44:71f09e4255f4 468 * @param[in] filetype is the header information (e.g. "Content-Type: application/pdf")
WiredHome 0:729320f63c5c 469 * @return true if it thinks it sent ok, false otherwise.
WiredHome 0:729320f63c5c 470 */
WiredHome 0:729320f63c5c 471 bool SendFile(const char * filename, const char * filetype);
WiredHome 12:109bf1558300 472
WiredHome 12:109bf1558300 473 /**
WiredHome 0:729320f63c5c 474 * register a handler for a specific URL.
WiredHome 0:729320f63c5c 475 *
WiredHome 3:17928786bdb5 476 * This api lets you register a dynamic handler in the web server. This is
WiredHome 3:17928786bdb5 477 * most useful for interactive web pages, rather than simply serving static
WiredHome 3:17928786bdb5 478 * pages.
WiredHome 3:17928786bdb5 479 *
WiredHome 3:17928786bdb5 480 * @code
WiredHome 12:109bf1558300 481 *
WiredHome 3:17928786bdb5 482 * ...
WiredHome 44:71f09e4255f4 483 * svr.RegisterHandler("/dyn1", SimpleDynamicPage);
WiredHome 3:17928786bdb5 484 * ...
WiredHome 3:17928786bdb5 485 *
WiredHome 53:e5d96abe5e9b 486 * HTTPServer::CallBackResults SimpleDynamicPage(HTTPServer *svr, HTTPServer::CallBackType type, char * path,
WiredHome 37:0cb2774e2410 487 * const HTTPServer::namevalue *queryParams, int queryParamCount) {
WiredHome 3:17928786bdb5 488 * char buf[100];
WiredHome 46:eaa86d48be6f 489 * HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
WiredHome 12:109bf1558300 490 *
WiredHome 3:17928786bdb5 491 * switch (type) {
WiredHome 3:17928786bdb5 492 * case HTTPServer::SEND_PAGE:
WiredHome 46:eaa86d48be6f 493 * svr->header(HTTPServer::OK, "OK", "Content-Type: text/html\r\n");
WiredHome 3:17928786bdb5 494 * svr->send("<html><head><title>Dynamic Page</title></head>\r\n");
WiredHome 3:17928786bdb5 495 * svr->send("<body>\r\n");
WiredHome 3:17928786bdb5 496 * svr->send("This page was generated dynamically. Create your own name=value pairs on the URL "
WiredHome 3:17928786bdb5 497 * "which uses the GET method.<br/>\r\n");
WiredHome 13:8975d7928678 498 * sprintf(buf, "%d parameters passed to {%s}:<br/>\r\n", queryParamCount, path);
WiredHome 3:17928786bdb5 499 * svr->send(buf);
WiredHome 13:8975d7928678 500 * for (int i=0; i<queryParamCount; i++) {
WiredHome 13:8975d7928678 501 * sprintf(buf, "%d: %s = %s<br/>\r\n", i, queryParams[i].name, queryParams[i].value);
WiredHome 3:17928786bdb5 502 * svr->send(buf);
WiredHome 3:17928786bdb5 503 * }
WiredHome 3:17928786bdb5 504 * svr->send("Stats:<br/>\r\n");
WiredHome 3:17928786bdb5 505 * sprintf(buf,"Free memory space: %d<br/>\r\n", Free());
WiredHome 3:17928786bdb5 506 * svr->send(buf);
WiredHome 3:17928786bdb5 507 * sprintf(buf,"Max Header size: %d<br/>\r\n", svr->GetMaxHeaderSize());
WiredHome 3:17928786bdb5 508 * svr->send(buf);
WiredHome 3:17928786bdb5 509 * svr->send("<br/><a href='/'>back to main</a></body></html>\r\n");
WiredHome 46:eaa86d48be6f 510 * ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:17928786bdb5 511 * break;
WiredHome 3:17928786bdb5 512 * case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 46:eaa86d48be6f 513 * ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:17928786bdb5 514 * break;
WiredHome 3:17928786bdb5 515 * case HTTPServer::DATA_TRANSFER:
WiredHome 46:eaa86d48be6f 516 * ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:17928786bdb5 517 * break;
WiredHome 3:17928786bdb5 518 * default:
WiredHome 46:eaa86d48be6f 519 * ret = HTTPServer::ACCEPT_ERROR;
WiredHome 3:17928786bdb5 520 * break;
WiredHome 3:17928786bdb5 521 * }
WiredHome 46:eaa86d48be6f 522 * return ret;
WiredHome 3:17928786bdb5 523 * }
WiredHome 3:17928786bdb5 524 * @endcode
WiredHome 3:17928786bdb5 525 *
WiredHome 44:71f09e4255f4 526 * @param[in] path to register
WiredHome 44:71f09e4255f4 527 * @param[in] callback of type Handler
WiredHome 0:729320f63c5c 528 * @return true if successfully registered
WiredHome 0:729320f63c5c 529 */
WiredHome 0:729320f63c5c 530 bool RegisterHandler(const char * path, Handler callback);
WiredHome 12:109bf1558300 531
WiredHome 59:9a71ac02c782 532
WiredHome 59:9a71ac02c782 533 /**
WiredHome 59:9a71ac02c782 534 * Get the path for the active handler.
WiredHome 59:9a71ac02c782 535 *
WiredHome 59:9a71ac02c782 536 * Useful from a callback to find out the registered path being serviced.
WiredHome 59:9a71ac02c782 537 *
WiredHome 59:9a71ac02c782 538 * @returns pointer to the string containing the registered path.
WiredHome 59:9a71ac02c782 539 * @returns NULL if it is invalid, e.g. called from a non-callback.
WiredHome 59:9a71ac02c782 540 */
WiredHome 59:9a71ac02c782 541 const char * GetActiveHandlerPath(void);
WiredHome 59:9a71ac02c782 542
WiredHome 0:729320f63c5c 543 /**
WiredHome 16:6ebacf2946d8 544 * determine if the named file is a supported type (htm, html, jpg, etc)
WiredHome 0:729320f63c5c 545 *
WiredHome 3:17928786bdb5 546 * if you pass in a filename, it will attempt to extract the extension
WiredHome 3:17928786bdb5 547 * and compare that to the list of supported file types. If it finds a
WiredHome 3:17928786bdb5 548 * match, then it will return a pointer to the content-type string.
WiredHome 3:17928786bdb5 549 *
WiredHome 3:17928786bdb5 550 * @code
WiredHome 3:17928786bdb5 551 * fType = GetSupportedType("mypix.jpg");
WiredHome 3:17928786bdb5 552 * if (fType) {
WiredHome 3:17928786bdb5 553 * ...
WiredHome 3:17928786bdb5 554 * @endcode
WiredHome 12:109bf1558300 555 *
WiredHome 44:71f09e4255f4 556 * @param[in] filename is the filename to test, based on the extension
WiredHome 0:729320f63c5c 557 * @return pointer to a Content-Type string if supported, or NULL if not.
WiredHome 0:729320f63c5c 558 */
WiredHome 0:729320f63c5c 559 const char * GetSupportedType(const char * filename);
WiredHome 0:729320f63c5c 560
WiredHome 0:729320f63c5c 561 /**
WiredHome 39:0427544a5c08 562 * search the available query parameters for 'name' and if found, return the 'value'
WiredHome 0:729320f63c5c 563 *
WiredHome 12:109bf1558300 564 * After the querystring is parsed, the server maintains an array of
WiredHome 3:17928786bdb5 565 * name=value pairs. This Get function will search for the passed in name
WiredHome 3:17928786bdb5 566 * and provide access to the value.
WiredHome 3:17928786bdb5 567 *
WiredHome 3:17928786bdb5 568 * @code
WiredHome 3:17928786bdb5 569 * BusOut leds(LED1,LED2,LED3,LED4);
WiredHome 3:17928786bdb5 570 * ...
WiredHome 3:17928786bdb5 571 * leds = atoi(svr->GetParameter("leds"));
WiredHome 3:17928786bdb5 572 * @endcode
WiredHome 3:17928786bdb5 573 *
WiredHome 44:71f09e4255f4 574 * @param[in] name is the name to search for
WiredHome 0:729320f63c5c 575 * @return pointer to the value, or NULL
WiredHome 0:729320f63c5c 576 */
WiredHome 0:729320f63c5c 577 const char * GetParameter(const char * name);
WiredHome 0:729320f63c5c 578
WiredHome 0:729320f63c5c 579 /**
WiredHome 39:0427544a5c08 580 * get a pointer to a name-value pair based on the index.
WiredHome 39:0427544a5c08 581 *
WiredHome 44:71f09e4255f4 582 * @param[in] index is the item being referenced
WiredHome 39:0427544a5c08 583 * @return pointer to the namevalue, or NULL
WiredHome 39:0427544a5c08 584 */
WiredHome 44:71f09e4255f4 585 const namevalue * GetParameter(int index);
WiredHome 39:0427544a5c08 586
WiredHome 39:0427544a5c08 587 /**
WiredHome 39:0427544a5c08 588 * Get the count of query parameters from the active transaction.
WiredHome 39:0427544a5c08 589 *
WiredHome 39:0427544a5c08 590 * @returns count of parameters.
WiredHome 39:0427544a5c08 591 */
WiredHome 39:0427544a5c08 592 int GetParameterCount(void)
WiredHome 39:0427544a5c08 593 {
WiredHome 39:0427544a5c08 594 return queryParamCount;
WiredHome 39:0427544a5c08 595 };
WiredHome 39:0427544a5c08 596
WiredHome 39:0427544a5c08 597 /**
WiredHome 39:0427544a5c08 598 * search the available post parameters for 'name' and if found, return the 'value'
WiredHome 39:0427544a5c08 599 *
WiredHome 39:0427544a5c08 600 * After the post parameter string is parsed, the server maintains an array of
WiredHome 39:0427544a5c08 601 * name=value pairs. This Get function will search for the passed in name
WiredHome 39:0427544a5c08 602 * and provide access to the value.
WiredHome 39:0427544a5c08 603 *
WiredHome 39:0427544a5c08 604 * @code
WiredHome 39:0427544a5c08 605 * BusOut leds(LED1,LED2,LED3,LED4);
WiredHome 39:0427544a5c08 606 * ...
WiredHome 39:0427544a5c08 607 * leds = atoi(svr->GetPostParameter("leds"));
WiredHome 39:0427544a5c08 608 * @endcode
WiredHome 39:0427544a5c08 609 *
WiredHome 44:71f09e4255f4 610 * @param[in] name is the name to search for
WiredHome 39:0427544a5c08 611 * @return pointer to the value, or NULL
WiredHome 39:0427544a5c08 612 */
WiredHome 39:0427544a5c08 613 const char * GetPostParameter(const char * name);
WiredHome 39:0427544a5c08 614
WiredHome 39:0427544a5c08 615 /**
WiredHome 39:0427544a5c08 616 * get a pointer to a post parameter name-value pair based on the index.
WiredHome 39:0427544a5c08 617 *
WiredHome 44:71f09e4255f4 618 * @param[in] index is the item being referenced
WiredHome 39:0427544a5c08 619 * @return pointer to the namevalue, or NULL
WiredHome 39:0427544a5c08 620 */
WiredHome 39:0427544a5c08 621 namevalue * GetPostParameter(int index);
WiredHome 39:0427544a5c08 622
WiredHome 39:0427544a5c08 623 /**
WiredHome 39:0427544a5c08 624 * Get the count of post parameters from the active transaction.
WiredHome 39:0427544a5c08 625 *
WiredHome 39:0427544a5c08 626 * @returns count of parameters.
WiredHome 39:0427544a5c08 627 */
WiredHome 39:0427544a5c08 628 int GetPostParameterCount(void)
WiredHome 39:0427544a5c08 629 {
WiredHome 39:0427544a5c08 630 return postParamCount;
WiredHome 39:0427544a5c08 631 };
WiredHome 39:0427544a5c08 632
WiredHome 59:9a71ac02c782 633
WiredHome 59:9a71ac02c782 634 /**
WiredHome 59:9a71ac02c782 635 * Parse the provided buffer as a method='Post' process.
WiredHome 59:9a71ac02c782 636 *
WiredHome 59:9a71ac02c782 637 * This is called from the user code if they want the parameters to
WiredHome 59:9a71ac02c782 638 * be parsed. If it is a bulk transfer, the user will not call this.
WiredHome 59:9a71ac02c782 639 * But if it is a form submitted with method='post', and if the total
WiredHome 59:9a71ac02c782 640 * number of parameters is small, then we can let the common code
WiredHome 59:9a71ac02c782 641 * process it.
WiredHome 59:9a71ac02c782 642 *
WiredHome 59:9a71ac02c782 643 * @param[in] pPostString is a pointer to the string to be processed.
WiredHome 59:9a71ac02c782 644 * @returns count of parameters parsed.
WiredHome 59:9a71ac02c782 645 */
WiredHome 59:9a71ac02c782 646 int ParsePostParameters(char * pPostString);
WiredHome 59:9a71ac02c782 647
WiredHome 39:0427544a5c08 648 /**
WiredHome 12:109bf1558300 649 * Parse the text string into name=value parameters.
WiredHome 3:17928786bdb5 650 *
WiredHome 12:109bf1558300 651 * This will directly modify the referenced string. If there is a
WiredHome 3:17928786bdb5 652 * #fragment_id on the end of the string, it will be removed.
WiredHome 0:729320f63c5c 653 *
WiredHome 44:71f09e4255f4 654 * @param[in] qP is a pointer to a namevalue set
WiredHome 44:71f09e4255f4 655 * @param[in] qpCount is a pointer to a counter of what is in the set
WiredHome 44:71f09e4255f4 656 * @param[in] maxP is the maximum number of parameters for which space has been allocated.
WiredHome 44:71f09e4255f4 657 * @param[in,out] pName is a pointer to the string.
WiredHome 37:0cb2774e2410 658 * @returns The total number of items that have been parsed,
WiredHome 37:0cb2774e2410 659 * which can include a count from a url query string.
WiredHome 0:729320f63c5c 660 */
WiredHome 39:0427544a5c08 661 int ParseParameters(namevalue * qP, int * qpCount, int maxP, char * pName);
WiredHome 12:109bf1558300 662
WiredHome 0:729320f63c5c 663 /**
WiredHome 16:6ebacf2946d8 664 * Unescape string converts a coded string "in place" into a normal string.
WiredHome 3:17928786bdb5 665 *
WiredHome 3:17928786bdb5 666 * A query string will have a number of characters replaced for communication
WiredHome 3:17928786bdb5 667 * which includes spaces, quotes, question marks and more. Most of them
WiredHome 12:109bf1558300 668 * will be replaced with a %xx format, where xx is the hex code for the
WiredHome 3:17928786bdb5 669 * character. Since the string will only get shorter when this happens
WiredHome 3:17928786bdb5 670 * the operation is performed in place.
WiredHome 3:17928786bdb5 671 *
WiredHome 0:729320f63c5c 672 * this "This%20is%20a%20question%3F%20and%20an%20answer."
WiredHome 12:109bf1558300 673 *
WiredHome 0:729320f63c5c 674 * becomes "This is a question? and an answer."
WiredHome 3:17928786bdb5 675 *
WiredHome 0:729320f63c5c 676 * @note '+' is another form of space, so is converted to a space before the %xx
WiredHome 0:729320f63c5c 677 *
WiredHome 44:71f09e4255f4 678 * @param[in,out] encoded string to be converted
WiredHome 0:729320f63c5c 679 */
WiredHome 0:729320f63c5c 680 void UnescapeString(char * encoded);
WiredHome 12:109bf1558300 681
WiredHome 12:109bf1558300 682 /**
WiredHome 16:6ebacf2946d8 683 * This is used to force a connection to close.
WiredHome 3:17928786bdb5 684 *
WiredHome 44:71f09e4255f4 685 * @note When WiFly is the interface, this switches the module into
WiredHome 44:71f09e4255f4 686 * command mode, performs the close, and then switches it back to data mode.
WiredHome 44:71f09e4255f4 687 * So, this is a time-expensive command.
WiredHome 7:99ad7a67f05e 688 *
WiredHome 7:99ad7a67f05e 689 * @returns true if successful
WiredHome 0:729320f63c5c 690 */
WiredHome 7:99ad7a67f05e 691 bool close_connection();
WiredHome 12:109bf1558300 692
WiredHome 3:17928786bdb5 693 /**
WiredHome 16:6ebacf2946d8 694 * Diagnostic to get the size of the largest header.
WiredHome 3:17928786bdb5 695 *
WiredHome 12:109bf1558300 696 * This is a diagnostic function, so you can resize the allocated
WiredHome 12:109bf1558300 697 * buffer for your application. With proper sizing, more of the
WiredHome 3:17928786bdb5 698 * system memory is available for your application.
WiredHome 3:17928786bdb5 699 *
WiredHome 3:17928786bdb5 700 * @code
WiredHome 3:17928786bdb5 701 * sprintf(buf,"Max Header size: %d<br/>\r\n", svr->GetMaxHeaderSize());
WiredHome 3:17928786bdb5 702 * svr->send(buf);
WiredHome 3:17928786bdb5 703 * @endcode
WiredHome 12:109bf1558300 704 *
WiredHome 3:17928786bdb5 705 * @returns size in bytes of the larger header measured.
WiredHome 3:17928786bdb5 706 */
WiredHome 3:17928786bdb5 707 int GetMaxHeaderSize();
WiredHome 3:17928786bdb5 708
WiredHome 13:8975d7928678 709 /**
WiredHome 16:6ebacf2946d8 710 * Get a value from the http header, if it exists.
WiredHome 13:8975d7928678 711 *
WiredHome 48:078adbe279ac 712 * @param[in] hdr is the string to search for (e.g. "Content-Length")
WiredHome 48:078adbe279ac 713 * @returns pointer to the value associated with that header.
WiredHome 13:8975d7928678 714 * @returns NULL if the header is not found.
WiredHome 13:8975d7928678 715 */
WiredHome 13:8975d7928678 716 const char * GetHeaderValue(const char * hdr);
WiredHome 3:17928786bdb5 717
WiredHome 3:17928786bdb5 718 /**
WiredHome 3:17928786bdb5 719 * Performance parameter
WiredHome 3:17928786bdb5 720 */
WiredHome 3:17928786bdb5 721 typedef struct SW_PERFPARAM {
WiredHome 3:17928786bdb5 722 unsigned long long TotalTime_us;
WiredHome 3:17928786bdb5 723 unsigned long Samples;
WiredHome 3:17928786bdb5 724 unsigned long MaxTime_us;
WiredHome 3:17928786bdb5 725 } SW_PerformanceParam;
WiredHome 12:109bf1558300 726
WiredHome 3:17928786bdb5 727 /**
WiredHome 3:17928786bdb5 728 * Performance metrics
WiredHome 3:17928786bdb5 729 */
WiredHome 3:17928786bdb5 730 typedef struct SW_PERFDATA {
WiredHome 17:69ff00ce39f4 731 SW_PerformanceParam ConnectionAccepted;
WiredHome 17:69ff00ce39f4 732 SW_PerformanceParam HeaderParsed;
WiredHome 17:69ff00ce39f4 733 SW_PerformanceParam ResponseSent;
WiredHome 17:69ff00ce39f4 734 SW_PerformanceParam ConnectionClosed;
WiredHome 3:17928786bdb5 735 //SW_PerformanceParam SendFile;
WiredHome 3:17928786bdb5 736 } SW_PerformanceData;
WiredHome 12:109bf1558300 737
WiredHome 3:17928786bdb5 738 /**
WiredHome 3:17928786bdb5 739 * Get performance metrics from the web server.
WiredHome 3:17928786bdb5 740 *
WiredHome 3:17928786bdb5 741 * This is a diagnostic function, and gathers data on the internal
WiredHome 3:17928786bdb5 742 * performance of the server, as it works various actions.
WiredHome 3:17928786bdb5 743 *
WiredHome 44:71f09e4255f4 744 * @param[in] p is a pointer to a SW_PerformanceData structure to be populated
WiredHome 3:17928786bdb5 745 */
WiredHome 3:17928786bdb5 746 void GetPerformanceData(SW_PerformanceData * p);
WiredHome 12:109bf1558300 747
WiredHome 3:17928786bdb5 748 /**
WiredHome 3:17928786bdb5 749 * Reset performance metrics.
WiredHome 3:17928786bdb5 750 */
WiredHome 3:17928786bdb5 751 void ResetPerformanceData();
WiredHome 17:69ff00ce39f4 752
WiredHome 17:69ff00ce39f4 753 /**
WiredHome 17:69ff00ce39f4 754 * Get performance clock
WiredHome 17:69ff00ce39f4 755 */
WiredHome 17:69ff00ce39f4 756 unsigned int GetPerformanceClock();
WiredHome 12:109bf1558300 757
WiredHome 0:729320f63c5c 758 private:
WiredHome 0:729320f63c5c 759 char * webroot;
WiredHome 0:729320f63c5c 760 PC * pc;
WiredHome 0:729320f63c5c 761 TCPSocketServer * server;
WiredHome 0:729320f63c5c 762 TCPSocketConnection client;
WiredHome 0:729320f63c5c 763 char * rewriteWithDefaultFile(char * queryString);
WiredHome 0:729320f63c5c 764 char * rewritePrependWebroot(char * queryString);
WiredHome 13:8975d7928678 765
WiredHome 13:8975d7928678 766 namevalue *queryParams; // Query Parameters from the URL this=that&sky=blue&...
WiredHome 13:8975d7928678 767 int maxqueryParams;
WiredHome 13:8975d7928678 768 int queryParamCount;
WiredHome 13:8975d7928678 769
WiredHome 39:0427544a5c08 770 namevalue *postParams; // Same as Query params, but for post method
WiredHome 39:0427544a5c08 771 int maxPostParams;
WiredHome 39:0427544a5c08 772 int postParamCount;
WiredHome 39:0427544a5c08 773
WiredHome 13:8975d7928678 774 namevalue *headerParams; // Header params Host: 192.168...\r\nConnection: keep-alive\r\n...
WiredHome 13:8975d7928678 775 int maxheaderParams;
WiredHome 13:8975d7928678 776 int headerParamCount;
WiredHome 13:8975d7928678 777
WiredHome 3:17928786bdb5 778 int maxheaderbytes;
WiredHome 3:17928786bdb5 779 char * headerbuffer;
WiredHome 3:17928786bdb5 780 int headerbuffersize;
WiredHome 12:109bf1558300 781
WiredHome 10:9c8d2c6a3469 782 Timer PerformanceTimer;
WiredHome 3:17928786bdb5 783 /**
WiredHome 3:17928786bdb5 784 * Records performance data
WiredHome 12:109bf1558300 785 *
WiredHome 3:17928786bdb5 786 * This will take a pointer to a SW_PerformanceParam, and it will
WiredHome 3:17928786bdb5 787 * take the time when the performance measurement started. It locally
WiredHome 3:17928786bdb5 788 * accesses the current time to measure the elapsed.
WiredHome 3:17928786bdb5 789 *
WiredHome 48:078adbe279ac 790 * @param[in] param is the performance parameter to update
WiredHome 48:078adbe279ac 791 * @param[in] value is the reference time.
WiredHome 3:17928786bdb5 792 * @returns the current time which may be used as the reference time
WiredHome 3:17928786bdb5 793 * for further measurements.
WiredHome 3:17928786bdb5 794 */
WiredHome 16:6ebacf2946d8 795 unsigned int RecordPerformanceData(SW_PerformanceParam * param, unsigned int value);
WiredHome 3:17928786bdb5 796 SW_PerformanceData perfData;
WiredHome 12:109bf1558300 797
WiredHome 3:17928786bdb5 798 typedef struct HANDLER {
WiredHome 0:729320f63c5c 799 char * path;
WiredHome 0:729320f63c5c 800 Handler callback;
WiredHome 0:729320f63c5c 801 } handler;
WiredHome 0:729320f63c5c 802 int maxdynamicpages;
WiredHome 0:729320f63c5c 803 handler *handlers;
WiredHome 0:729320f63c5c 804 int handlercount;
WiredHome 59:9a71ac02c782 805 int ndxActiveHandler; // Contains the index into the list of handlers for the currently active callback
WiredHome 3:17928786bdb5 806
WiredHome 3:17928786bdb5 807 char * queryType;
WiredHome 44:71f09e4255f4 808 char * queryString; // the query string [and 'GET' data] passed on the URL (e.g. ?name1=value1&name2=value2...)
WiredHome 44:71f09e4255f4 809 char * postQueryString; // the post data
WiredHome 44:71f09e4255f4 810 const namevalue * filenameAliasList; // pointer to a filename alias list
WiredHome 44:71f09e4255f4 811
WiredHome 0:729320f63c5c 812 /**
WiredHome 8:262583f054f6 813 * Extract the parameter from the record, by searching for the needle in the haystack.
WiredHome 8:262583f054f6 814 *
WiredHome 8:262583f054f6 815 * The parameter of interest follows the needle, and may be ' ' delimited
WiredHome 0:729320f63c5c 816 * Can damage haystack while processing it.
WiredHome 0:729320f63c5c 817 *
WiredHome 48:078adbe279ac 818 * @param[in] haystack is the record to search
WiredHome 48:078adbe279ac 819 * @param[in] needle is the text to search for, which precedes the text to return
WiredHome 48:078adbe279ac 820 * @param[out] string is the text following the needle
WiredHome 0:729320f63c5c 821 * @return true if it extracted something successfully
WiredHome 0:729320f63c5c 822 */
WiredHome 48:078adbe279ac 823 bool Extract(char * haystack, char * needle, char ** string);
WiredHome 0:729320f63c5c 824
WiredHome 3:17928786bdb5 825 void SendResponse();
WiredHome 29:00116fc9da74 826 HTTPServer::CallBackResults ParseHeader(char * bPtr);
WiredHome 3:17928786bdb5 827 bool CheckDynamicHandlers();
WiredHome 3:17928786bdb5 828
WiredHome 0:729320f63c5c 829 int HexCharToInt(char c);
WiredHome 0:729320f63c5c 830 char HexPairToChar(char * p);
WiredHome 29:00116fc9da74 831
WiredHome 29:00116fc9da74 832 #ifdef DEBUG
WiredHome 29:00116fc9da74 833 void * MyMalloc(int x, int y);
WiredHome 29:00116fc9da74 834 char toP(void * x);
WiredHome 29:00116fc9da74 835 #endif
WiredHome 0:729320f63c5c 836 };
WiredHome 0:729320f63c5c 837 #endif //SW_HTTPSERVER_H
WiredHome 4:f34642902056 838
WiredHome 7:99ad7a67f05e 839