Single instance HTTP Server using WiFly Interface.

Dependents:   WiFlyHTTPServerSample MultiThreadingHTTPServer

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HttpServer.h Source File

HttpServer.h

00001 #ifndef __HTTPSERVER_H__
00002 #define __HTTPSERVER_H__
00003 
00004 #include "Wifly.h"
00005 #include "rtos.h"
00006 #include "HTTPConnection.h"
00007 #include "HTTPRequestHandler.h"
00008 
00009 #include <string>
00010 #include <map>
00011 
00012 typedef enum {
00013     msg_get,
00014     msg_post,
00015     msg_head,
00016     msg_put,
00017     msg_delete,
00018     msg_trace,
00019     msg_options,
00020     msg_connect
00021 } msg_t;
00022 
00023 
00024 typedef struct {
00025     msg_t                       requestType;
00026     char                        requestUri[256];
00027 //    map<string, string>         messageHeaders;
00028 } request_msg_t;
00029 
00030 /** Typedefinition for a handler function
00031 */
00032 typedef void (*HTTPRequestHandlerFunction)(HTTPConnection::HTTPMessage&);
00033 
00034 
00035 /** This is the non-blocking HTTP Server class. The idea behind this class is as follows:
00036   * the user may instantiate the class and initialize it. Once the server is setup and 
00037   * listening, the server will stay in an endless loop and keep on listening for new 
00038   * connections and for new HTTP requests. Once a request is received it will be placed 
00039   * in a queue. The queue itself will be handled in a separate task.
00040   */
00041 class HttpServer : public Wifly
00042 {
00043         Thread      *m_listener;
00044         Thread      *m_worker;
00045 
00046         request_msg_t*  checkMessageReceived(char *);
00047         void            processMessageHeader(char* headerLine, char **fieldname, char **fieldvalue);        
00048         
00049     public:
00050         HttpServer(PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec, Wifly::WiflyBaudrate_t baud = Wifly::Wifly_115200);
00051         ~HttpServer();
00052         
00053         bool start(int port);
00054         
00055         virtual void handler_rx(void);
00056         virtual void attach_rx(bool);
00057         
00058         virtual bool join();
00059         virtual int send(const char * str, int len, const char * ACK = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
00060         
00061     public:
00062         
00063         
00064         /**
00065         * Structure which will allow to order the stored handlers according to their associated path.
00066         */
00067         struct handlersComp //Used to order handlers in the right way
00068         {
00069             bool operator() (const string& handler1, const string& handler2) const
00070             {
00071                 //The first handler is longer than the second one
00072                 if (handler1.length() > handler2.length())
00073                     return true; //Returns true if handler1 is to appear before handler2
00074                 else if (handler1.length() < handler2.length())
00075                     return false;
00076                 else //To avoid the == case, sort now by address
00077                     return ((&handler1)>(&handler2));
00078             }
00079         };
00080         /** The standard error handler function.
00081         * @param msg : Request message data.
00082         * @param tcp : Socket to be used for responding.
00083         */
00084         static void StdErrorHandler(HTTPConnection::HTTPMessage& msg);
00085 
00086 
00087         /** Internal function which processes a request and which will try to find the matching handler function
00088         * for the given request. Please note that the function will search through the list of handlers, iterating
00089         * from longest to shortest \c paths. If the registered \c path is a subset of the request the associated
00090         * handler is considered as being a match.
00091         * @param msg : Request message data. Contains the requested logical \c uri. 
00092         * @param tcp : Socket to be used for communication with the client.
00093         */
00094         void HandleRequest(HTTPConnection::HTTPMessage* msg);
00095     
00096         /** Map of handler objects. Can be any object derived from \ref HTTPRequestHeader. Use the \ref addHandler function
00097         * to register new handler objects.
00098         */
00099         static map<string, HTTPRequestHandler* (*)(const char*, const char*, HTTPConnection::HTTPMessage&), handlersComp>   m_lpHandlers;
00100 
00101         /**
00102         * Adds a request handler to the handlers list. You will have to use one of the existing implementations.
00103         * With each handler a \c uri or \c path is associated. Whenever a request is received the server will
00104         * walk through all registered handlers and check which \c path is matching.
00105         * @param T : class which will be instanciated to serve these requests for the associated \b path.
00106         * @param path : request uri starting with this \c path will be served using this handler.
00107         */
00108         template<typename T>
00109         void addHandler(const char* path)
00110         { m_lpHandlers[path] = &T::create; }
00111     
00112         /**
00113         * Replaces the standard error Handler. The error Handler will be called everytime a request is not
00114         * matching any of the registered \c paths or \c uris.
00115         * @param hdlFunc: User specified handler function which will be used in error conditions.
00116         */
00117         void addErrorHandler(HTTPRequestHandlerFunction hdlFunc)
00118         { m_pErrorHandler = hdlFunc!=NULL ?hdlFunc : StdErrorHandler; }    
00119         HTTPRequestHandlerFunction m_pErrorHandler;
00120 
00121     protected:
00122         bool bind(int port);
00123         void listenForRequests();
00124         void serveRequests();
00125         
00126         bool parseRequest(char *request);
00127         
00128         static void listen_thread(const void * parms);
00129         static void worker_thread(const void * parms);
00130 };
00131 
00132 #endif //   __HTTPSERVER_H__