Web server based weather station using Sparkfun Weather Meters.
Dependencies: FatFileSystem mbed WeatherMeters SDFileSystem
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_ */
Generated on Tue Jul 12 2022 20:48:15 by 1.7.2