A simple web server that can be bound to either the EthernetInterface or the WiflyInterface.
Dependents: Smart-WiFly-WebServer WattEye X10Svr SSDP_Server
SW_HTTPServer.h
- Committer:
- WiredHome
- Date:
- 2013-05-31
- Revision:
- 1:54353af0d20a
- Parent:
- 0:729320f63c5c
- Child:
- 2:a29c32190037
File content as of revision 1:54353af0d20a:
#ifndef SW_HTTPSERVER_H #define SW_HTTPSERVER_H #include "mbed.h" //#include "MODSERIAL.h" // would like to hook in mod serial for higher performance, less blocking #include "Wifly.h" #include "TCPSocketServer.h" #include "TCPSocketConnection.h" #ifdef MODSERIAL_H #define PC MODSERIAL #else #define PC Serial #endif /// HTTPServer is a simple web server using the WiFly module. /// /// Partially derived from nweb /// http://www.ibm.com/developerworks/systems/library/es-nweb/sidefile1.html /// /// Uses a modified WiflyInterface - a number of performance issues /// were identified and resolved in the local version. /// /// Also, if nothing visits its web page for a long time, it seems /// to disable. Might be a sleep timer I'm not spotting. /// /// Given: scheme://domain:port/path?query_string#fragment_id /// @li scheme is "http" /// @li domain is whatever IP the server has /// @li port is the registered port /// @li /path is the reference to the file (actual or logical) on the server /// @li query_string is any combination of name=value pairs /// @li fragment_id is a reference to an anchor on the page /// /// @todo make it non-blocking. /// @todo hunt down lengthy operations - there seems to be a long timeout somewhere. /// @todo move part of the POST method handler to the registered handler, so /// it can decide if it should allocate the needed memory. /// @todo transform the pc serial interface to a log interface, which might /// be more useful. /// @todo parse the header similar to the query string, and then make /// those parameters accessible - perhaps like environment vars. /// /// @note Copyright © 2013 by Smartware Computing, all rights reserved. /// Individuals may use this application for evaluation or non-commercial /// purposes. Within this restriction, changes may be made to this application /// as long as this copyright notice is retained. The user shall make /// clear that their work is a derived work, and not the original. /// Users of this application and sources accept this application "as is" and /// shall hold harmless Smartware Computing, for any undesired results while /// using this application - whether real or imagined. /// /// @author David Smart, Smartware Computing /// class HTTPServer { public: /** * namevalue pairs for parameters */ typedef struct { char * name; char * value; } namevalue; /** * callback prototype for custom handler * * @param svr is a handle to this class, so the callback has access to member functions * @param params is a pointer to an array of name value pairs * @paramcount is the number of parameters. */ typedef void (* Handler)(HTTPServer * svr, const char * path, const namevalue *params, int paramcount); /** * Create the HTTPServer object. * * @param wifly is the serial port with the wifly interface. * @param port is the optional parameter for the port number to use, default is 80. * @param webroot is a file system path to the root folder for the web space. * @param maxparams defines the maximum number of parameters to a dynamic function (and the memory to support them). * @param maxdynamicpages defines the maximum number of dynamic pages that can be registered. * @param pc is the serial port for debug information (I should transform this to a log interface) */ HTTPServer(Wifly * wifly, int port = 80, const char * webroot = "/", int maxparams = 30, int maxdynamicpages = 10, PC * pc = NULL); /** * destructor, which can clean up a few things */ ~HTTPServer(); /** * the process to call whenever there is free time, as this basically does * all the work to monitor for connections and handle replies. */ void ip_process(); /** * Send a header back to the client and automatically appends a "\r\n". Each parameter must * send a "\r\n" as part of that string. * * @param code is the optional return code; 200 = OK, if not provided then 404 = Not found is returned * @param code_text is the text to align with the code (e.g. 404, "Not Found") * @param content_type is a pointer to "Content-Type: text/html\r\n" (for example) * @param optional_text is a pointer to any other text that is part of the header */ void header(int code = 404, const char * code_text = "Not Found", const char * content_type = NULL, const char * optional_text = NULL); /** * Send text to the client * * @param msg is the text string to send * @param bytes is the number of bytes to send. If not set, then strlen is calculated. */ void send(const char * msg, int bytes = -1); /** * Send a file to the client, including the header * * @param filename is the fully qualified path and filename * @param filetype is the header information (e.g. "Content-Type: text/html") * @return true if it thinks it sent ok, false otherwise. */ bool SendFile(const char * filename, const char * filetype); /** * register a handler for a specific URL. * * @param path to register * @param callback of type Handler * @return true if successfully registered */ bool RegisterHandler(const char * path, Handler callback); /** * determine if the named file is a supported type (e.g. .htm, .jpg, ...) * * @param filename is the filename to test, based on the extension * @return pointer to a Content-Type string if supported, or NULL if not. */ const char * GetSupportedType(const char * filename); /** * search the available parameters for 'name' and if found, return the 'value' * * @param name is the name to search for * @return pointer to the value, or NULL */ const char * GetParameter(const char * name); /** * parse the text string into name=value parameters. This will directly * modify the referenced string. If there is a #fragment_id on the end * of the string, that will be removed. * * @param pString is a pointer to the string. */ void ParseParameters(char * pString); /** * Unescape string converts a coded string "in place" into a normal string * this "This%20is%20a%20question%3F%20and%20an%20answer." * becomes "This is a question? and an answer." * @note '+' is another form of space, so is converted to a space before the %xx * * @param encoded string to be converted */ void UnescapeString(char * encoded); /** * Get the IP address of the remote node to which we are connected. * @caution this switches the module into, and out of, command mode * which has quite a time penalty. */ void GetRemoteAddr(char * str, int size); /** * used to force a connection to close */ void close_connection(); private: Wifly * wifly; char * webroot; PC * pc; Timer * timer; TCPSocketServer * server; TCPSocketConnection client; char * rewriteWithDefaultFile(char * queryString); char * rewritePrependWebroot(char * queryString); int maxparams; namevalue *params; int paramcount; typedef struct { char * path; Handler callback; } handler; int maxdynamicpages; handler *handlers; int handlercount; /** * Extract the message from the record, by searching for the needle * the string of interest follows the needle, and may be ' ' delimited * Can damage haystack while processing it. * * @param haystack is the record to search * @param needle is the text to search for, which precedes the text to return * @param string is the text following the needle * @return true if it extracted something successfully */ bool Extract(char * rec, char * needle, char ** string); int HexCharToInt(char c); char HexPairToChar(char * p); }; #endif //SW_HTTPSERVER_H