Adam Green / Mbed 2 deprecated WeatherStation

Dependencies:   FatFileSystem mbed WeatherMeters SDFileSystem

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPServer.h Source File

HTTPServer.h

00001 /* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)
00002 
00003    Licensed under the Apache License, Version 2.0 (the "License");
00004    you may not use this file except in compliance with the License.
00005    You may obtain a copy of the License at
00006 
00007        http://www.apache.org/licenses/LICENSE-2.0
00008 
00009    Unless required by applicable law or agreed to in writing, software
00010    distributed under the License is distributed on an "AS IS" BASIS,
00011    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012    See the License for the specific language governing permissions and
00013    limitations under the License.
00014 */
00015 /* Header file for HTTP Server functionality. */
00016 #ifndef HTTPSERVER_H_
00017 #define HTTPSERVER_H_
00018 
00019 #include <mbed.h>
00020 #include "lwip/tcp.h"
00021 
00022 
00023 
00024 // UNDONE: Make protected member of CHTTPServer object?
00025 /** Structure used to buffer data being read in from content files and then
00026     written out the TCP/IP connections.
00027 */
00028 struct SBuffer
00029 {
00030     char*           pWrite;                 /**< Pointer into Data where the next tcp_write() should begin.  There are BytesToWrite valid bytes left in the Data array to be sent. */
00031     // UNDONE: These can be shorts since mbed only has a total of 64k anyway.
00032     unsigned int    BytesToWrite;           /**< Number of bytes in buffer left to be written to outbound connection. */
00033     unsigned int    UnacknowledgedBytes;    /**< Number of bytes outstanding on network waiting for acknowledgment. */
00034     char            Data[TCP_SND_BUF];      /**< The actual buffer holding data to be sent to remote client. */
00035 };
00036 
00037 
00038 
00039 
00040 
00041 // *****************
00042 // * C++ Interface *
00043 // *****************
00044 /** Interface to be returned from an application to provide callbacks for a
00045     specific HTTP request.
00046 */
00047 class IHTTPRequestHandlerContext
00048 {
00049 public:
00050     /** Called by the CHTTPServer object before any WriteRequestHeader() calls
00051         to let the application to know to expect subsequent 
00052         WriteRequestHeader() calls.
00053         
00054         @returns 0 if the application isn't interested in receiving subsequent
00055                  WriteRequestHeader() and EndRequestHeaders() callbacks.
00056                  Returns non-zero value to receive headers.
00057     */
00058     virtual int  BeginRequestHeaders() = 0;
00059 
00060     /** Called by CHTTPServer for each HTTP request header sent by the HTTP 
00061         client.  The server won't issue this callback if 0 was previously
00062         returned by the application from the BeginRequestHeaders() method.
00063         
00064         @param pHeaderName is the name of this header field.  If this string
00065                is empty then this header line is a continuation of the previous
00066                header line which did have a field name.  The string
00067                pointed to by this parameter has a short lifetime and is only
00068                valid during the duration of this call.
00069         @param pHeaderValue is the string value of this header field.  The
00070                string pointed to by this parameter has a short lifetime and is
00071                only valid during the duration of this call.
00072     */
00073     virtual void WriteRequestHeader(const char* pHeaderName, 
00074                                     const char* pHeaderValue) = 0;
00075     
00076     /** Called by the CHTTPServer object after it has completed all of the
00077         necessary WriteRequestHeader() calls to enumerate the headers of the
00078         HTTP client's request.
00079     */
00080     virtual void EndRequestHeaders() = 0;
00081     
00082 
00083     /** Called by CHTTPServer to let the application know that it should expect
00084         subsequent WriteRequestContentBlock() calls for processing of the
00085         request content as it arrives on the TCP/IP socket.
00086         
00087         Only POST requests from a client should include such content data.
00088         
00089         @param ContentSize is the size of the request content to be sent from
00090                the HTTP client.  This value indicates the total number of bytes
00091                that should result from all of the WriteRequestContentBlock()
00092                calls to follow.
00093                
00094         @returns 0 if the application isn't interested in receiving subsequent
00095                  WriteRequestContentBlock() and EndRequestContent() callbacks.
00096                  Returns non-zero value to receive request content data.
00097     */
00098     virtual int BeginRequestContent(size_t ContentSize) = 0;
00099     
00100     /** Called for each block of request data received from the HTTP client.
00101         The server won't issue this callback if the application returned 0 from
00102         the BeginRequestContent() method.
00103         
00104         @param pBlockBuffer is a pointer to the block of request content data
00105                most recently received from the HTTP client.
00106         @param BlockBufferSize is the number of bytes contained in 
00107                pBlockBuffer.
00108     */
00109     virtual void WriteRequestContentBlock(const void* pBlockBuffer, 
00110                                           size_t BlockBufferSize) = 0;
00111                                   
00112     /** Called by CHTTPServer after it has completed all of the 
00113         WriteRequestContentBlock() calls for processing of the request content
00114         data sent from the HTTP client.
00115     */
00116     virtual void EndRequestContent() = 0;
00117     
00118     
00119     /** Called by CHTTPServer object to get the status line from the
00120         application to be returned to the HTTP client for this request.
00121         Examples: "HTTP/1.0 200 OK\r\n" -or- "HTTP/1.0 404 File no found\r\n"
00122         
00123         @param pStatusLineLength points to the length to be filled in by the
00124                application indicating the length, in character, of the returned
00125                status line.  It should not include the NULL terminator.  It
00126                must have a non-zero value.
00127                
00128         @returns a pointer to the status line to be returned to the HTTP client
00129                  for this request.  It should start with the "HTTP/1.0" string
00130                  and end with a newline designator of "\r\n".  The return value
00131                  can't be NULL.
00132     */
00133     virtual const char* GetStatusLine(size_t* pStatusLineLength) = 0;
00134     
00135     /** Called by the CHTTPServer object to get all of the response headers
00136         that the application would like to be returned to the HTTP client.  The
00137         CHTTPServer will append this header string to the 
00138         "Server: ServerName\r\n" header that it always sends.
00139         
00140         Example: "Content-Length: 100\r\n"
00141         
00142         @param pResponseHeaderLength points to the length to be filled in by
00143                the application indicating the length, in character, of the
00144                returned header string.  It should not include the NULL
00145                terminator and can be 0 if the returned value is NULL.
00146                
00147         @returns a pointer to the extra headers to be returned to the HTTP
00148                  client for this request.  It can be NULL if the application
00149                  has no special headers to be returned.
00150     */
00151     virtual const char* GetResponseHeaders(size_t* pResponseHeaderLength) = 0;
00152     
00153     /** Called by CHTTPServer to let application know that there will be
00154         subsequent ReadResponseContentBlock() calls to obtain the content data
00155         from the application to be sent back to the HTTP client in the
00156         response.
00157         
00158         @returns 0 if the application has no content to be sent back in the
00159                  HTTP response.
00160     */
00161     virtual int BeginResponseContent() = 0;
00162     
00163     /** Called by CHTTPServer to get the next block of response data to be
00164         sent back to the HTTP client.
00165         
00166         @param pBuffer is a pointer to the buffer to be filled in by the
00167                application with data to be sent back to the HTTP client in the
00168                response.
00169         @param BytesToRead indicates the number of bytes that should be placed
00170                into pBuffer by the application.  The application should only
00171                place fewer than this requested amount on the last block of
00172                data to be sent back to the HTTP client.
00173         
00174         @returns The number of bytes that were actually placed in pBuffer for
00175                  this call.  It can only be smaller than BytesToRead on the
00176                  last block to be sent since the server uses such truncated
00177                 reads to know when it has sent the last block of response
00178                 data.
00179     */
00180     virtual size_t ReadResponseContentBlock(char*  pBuffer,
00181                                             size_t BytesToRead) = 0;
00182     
00183     
00184     /** Called by CHTTPServer to let the application know that it has finished
00185        sending all of the response data to the HTTP client.  The application
00186        can use such a call to close any files that it has open for satsifying
00187        this request.
00188     */
00189     virtual void EndResponseContent() = 0;
00190     
00191     /** Called by the CHTTPServer object when it is completely done processing
00192        this HTTP response request so that the application can free up any
00193        resources it has associated with this HTTP client request, including the
00194        IHTTPRequestHandlerContext derived object servicing these callbacks.
00195     */
00196     virtual void Release() = 0;
00197 };
00198 
00199 
00200 /** The application can provide an IRequestHandler interface implementation to
00201  *  the HTTP server object.  The methods on such attached interface objects will
00202  *  be called by the server before it attempts default handling of HTTP
00203  *  requests.  This gives the application an opportunity to provide overrides
00204  *  for handling POST requests or GET requests in a certain part of the URI
00205  *  namespace.
00206  */
00207 class IHTTPRequestHandler
00208 {
00209 public:
00210     /** Called by the server for each GET request.  If the application would
00211         like to handle the GET request rather than using the default server
00212         code then the application should return a valid 
00213         IHTTPRequestHandlerContext object pointer on which the server will call
00214         methods.  These method calls will inform the application of which
00215         headers were sent in the request and then obtain the response data to
00216         be sent back to the HTTP client.  Returning a NULL pointer indicates 
00217         that the server should search in its pRootPathname directory for the
00218         requested file.
00219         
00220         @param pURI is a pointer to the URI being requested by the HTTP
00221                client.  This is a short lived object that will only be
00222                valid during this call.
00223                
00224         @returns NULL if the CHTTPServer object should process the GET
00225                  request on its own.  Otherwise return an
00226                  IHTTPRequestHandlerContext object pointer so that the
00227                  application can be notified of additional request
00228                  information and provide the response data.
00229     */
00230     virtual IHTTPRequestHandlerContext* HandleGetRequest(const char* pURI) = 0;
00231     
00232     /** Called by the server for each HEAD request.  If the application would
00233         like to handle the HEAD request rather than using the default server
00234         code then the application should return a valid 
00235         IHTTPRequestHandlerContext object pointer on which the server will call
00236         methods.  These method calls will inform the application of which
00237         headers were sent in the request and then obtain the response data to
00238         be sent back to the HTTP client.  Returning a NULL pointer indicates 
00239         that the server should search in its pRootPathname directory for the
00240         requested file.
00241         
00242         @param pURI is a pointer to the URI being requested by the HTTP
00243                client.  This is a short lived object that will only be
00244                valid during this call.
00245                
00246         @returns NULL if the CHTTPServer object should process the HEAD
00247                  request on its own.  Otherwise return an
00248                  IHTTPRequestHandlerContext object pointer so that the
00249                  application can be notified of additional request
00250                  information.
00251     */
00252     virtual IHTTPRequestHandlerContext* HandleHeadRequest(const char* pURI) = 0;
00253     
00254     /** Called by the server for each POST request.  If the application would
00255         like to handle the POST request then it should return a valid 
00256         IHTTPRequestHandlerContext object pointer on which the server will call
00257         methods.  These method calls will inform the application of which
00258         headers were sent in the request and then obtain the response data to
00259         be sent back to the HTTP client.  Returning a NULL pointer indicates 
00260         that the server should fail this POST request with a not implemented
00261         error.
00262         
00263         @param pURI is a pointer to the URI being requested by the HTTP
00264                client.  This is a short lived object that will only be
00265                valid during this call.
00266                
00267         @returns NULL if the CHTTPServer object should fail the POST
00268                  request.  Otherwise return an IHTTPRequestHandlerContext 
00269                  object pointer so that the application can be notified of
00270                  additional request information and provide the response data.
00271     */
00272     virtual IHTTPRequestHandlerContext* HandlePostRequest(const char* pURI) = 0;
00273     
00274     /** Called by the server for each unrecognized request.  If the application
00275         would to handle such request then it should return a valid 
00276         IHTTPRequestHandlerContext object pointer on which the server will call
00277         methods.  These method calls will inform the application of which
00278         headers were sent in the request and then obtain the response data to
00279         be sent back to the HTTP client.  Returning a NULL pointer indicates 
00280         that the server should fail this bad request with an appropriate error.
00281         
00282         @param pRequest is a pointer to the request being made by the HTTP
00283                client.  This is a short lived object that will only be
00284                valid during this call.
00285                
00286         @returns NULL if the CHTTPServer object should fail this
00287                  request.  Otherwise return an IHTTPRequestHandlerContext 
00288                  object pointer so that the application can be notified of
00289                  additional request information and provide the response data.
00290     */
00291     virtual IHTTPRequestHandlerContext* HandleBadRequest(const char* pRequest) = 0;
00292 };
00293 
00294 
00295 // Forward declaration of class used to hold context for each HTTP client 
00296 // connection.
00297 class CHTTPContext;
00298 
00299 
00300 /** HTTP server class.
00301 */
00302 class CHTTPServer
00303 {
00304 public:
00305     /** Constructor */
00306     CHTTPServer();
00307     
00308     /** Attach IRequestHandler to the HTTP server to allow application to add
00309         custom GET/HEAD/POST handling.
00310     
00311         @param pHandler is a pointer to the application specific request handler object
00312                to be used by the HTTP server when it receives GET/POST requests.
00313         
00314         @returns 0 on successful attachment and a positive value otherwise.
00315     */
00316     int AttachRequestHandler(IHTTPRequestHandler* pHandler);
00317     
00318     /** Initializes the HTTP server object by binding it to to the specified
00319         port number.
00320 
00321         @param pRootPathame is the pathname of the default root directory from which the
00322                HTTP GET requests are satisfied.
00323         @param pServerName is the name of the server to be returned to the HTTP client
00324                in the Server header.
00325         @param BindPort is the TCP/IP port to which the HTTP server should listen for
00326                 incoming requests.  The default port for HTTP would be 80.
00327     
00328         @returns 0 on success and a positive value otherwise.
00329     */
00330     int Bind(const char*    pRootPathname,
00331              const char*    pServerName = "lwIP_HTTPServer/1.0",
00332              unsigned short BindPort = 80);
00333 
00334 protected:
00335     // Static Method Prototypes for lwIP Callbacks.
00336     static err_t        HTTPAccept(void* pvArg, tcp_pcb* pNewPCB, err_t err);
00337 
00338     // Methods called from CHTTPContext.
00339     friend class CHTTPContext;
00340     void                FreeBuffer(SBuffer* pBuffer);
00341     void                RemoveWaitingContext(CHTTPContext* pHTTPContext);
00342     SBuffer*            AllocateBuffer(CHTTPContext* pHTTPContext);
00343 
00344     // Listening port for HTTP Server.
00345     tcp_pcb*                m_pHTTPListenPCB;
00346     // Head and tail pointers for queue of client contexts that are waiting to
00347     // be allocated a SBuffer from the BufferPool.
00348     CHTTPContext*           m_pContextWaitingHead;
00349     CHTTPContext*           m_pContextWaitingTail;
00350     // The default root directory from which the HTTP GET requests are satisfied.
00351     const char*             m_pRootPathname;
00352     // Pointer to interface from application allowing it to handle HTTP requests.
00353     IHTTPRequestHandler*    m_pRequestHandler;
00354     // Server header returned to HTTP clients.
00355     size_t                  m_ServerHeaderLength;
00356     char                    m_ServerHeader[64];
00357     // Pool of buffers to use for transitioning data from the filesystem to
00358     // the network.
00359     SBuffer                 m_BufferPool[HTTP_BUFFER_POOL];
00360 };
00361 
00362 
00363 #endif /* HTTPSERVER_H_ */