Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: PetfeederWebServer
Fork of httpServer_with_Ethernt by
Revision 0:e59cc54df17c, committed 2015-06-29
- Comitter:
- hjjeon
- Date:
- Mon Jun 29 09:03:40 2015 +0000
- Child:
- 1:772534e3b627
- Commit message:
- httpServer
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPConnection.cpp Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,287 @@
+/* HTTPConnection.cpp */
+
+#include "mbed.h"
+#include "HTTPConnection.h"
+//#define DEBUG
+#include "hl_debug.h"
+
+#include <vector>
+using std::vector;
+
+using std::string;
+
+
+
+const struct HTTPRequestConfig {
+ const char* request_string;
+ HTTPRequestType request_type;
+} g_requestConfig[] = {
+ { "GET", HTTP_RT_GET },
+ { "POST", HTTP_RT_POST},
+ { "PUT", HTTP_RT_PUT},
+ { "OPTIONS",HTTP_RT_OPTIONS},
+ { "HEAD", HTTP_RT_HEAD},
+ { "DELETE", HTTP_RT_DELETE},
+ { "TRACE", HTTP_RT_TRACE},
+ { "CONNECT",HTTP_RT_CONNECT}
+};
+
+
+HTTPConnection::HTTPConnection(TCPSocketConnection& clnt) : m_Tcp(clnt)
+{
+}
+
+
+HTTPConnection::~HTTPConnection()
+{
+ close();
+}
+
+void HTTPConnection::close()
+{
+ m_Msg.headers.clear();
+}
+
+int HTTPConnection::poll()
+{
+ static char buffer[256] = {};
+ int rcvd= 0;
+ int ret = 0;
+ int attri_len = 0;
+
+ INFO("Waiting for new data in connection");
+ // Try receiving request line
+ rcvd = receiveLine(buffer, 255, 3000);
+ if (rcvd == -1) {
+ // there was an error, probably the connection was closed, so close this connection as well
+ INFO("No more data available. Will close this connection now.");
+ close();
+ return -1;
+ }
+
+ // The Request has not yet been received so try it
+ rcvd = parse(buffer);
+ if (rcvd == -1) {
+ // Invalid content received, so close the connection
+ INFO("Invalid message received, so sending negative response and closing connection !");
+ //sprintf(buffer,"HTTP/1.1 400 BadRequest\n\rContent-Length: %d\n\rContent-Type: text\n\r\n\r\n\r",0);
+ m_Tcp.set_blocking(true, 1500);
+ //m_Tcp.send(buffer,strlen(buffer));
+ close();
+ rcvd = -1;
+ return -1;
+ }
+ // The request has been received, try receive the body
+ while(rcvd > 0) {
+ rcvd = receiveLine((char*)buffer, 255, 3000);
+ // First check if we received an empty line. This would indicate the end of the message or message body.
+ if (rcvd < 0) {
+ // there was an empty line, so we can start with performing the request
+ INFO("Request Header was received completely. Performing request.");
+ rcvd = 0;
+ break;
+ }
+ else {
+ // add message body
+ ret = parseHeader(buffer);
+ if (ret == 0) {
+
+ }
+ else {
+ attri_len = ret;
+ }
+ }
+ }
+
+ //Receive attribute data
+ if( attri_len != 0 )
+ {
+ m_Tcp.receive( m_Msg.attri, attri_len );
+ }
+
+ INFO("Leaving poll function!");
+ return rcvd;
+}
+
+int HTTPConnection::receiveLine(char* szLine, int nMaxLen, int nTimeout, char cLineTerm)
+{
+ if ((szLine == NULL) || (nMaxLen == 0))
+ return -1;
+
+ szLine[0] = 0;
+ m_Tcp.set_blocking(false);
+
+ if (!m_Tcp.is_connected()) {
+ error("NOT COnnected anymore");
+ return -1;
+ }
+ Timer tm;
+ int i;
+
+ // Try to receive up to the max number of characters
+ for (i = 0 ; i < nMaxLen-1 ; i++) {
+ int c;
+ c = m_Tcp.receive( szLine + i, 1 );
+ // Check that - if no character was currently received - the timeout period is reached.
+ if ((c == 0) || (c==-1)) {
+ // no character was read, so check if operation timed out
+ if (tm.read_ms() > nTimeout) {
+ // Operation timed out
+ INFO("Timeout occured in function 'receiveLine'.");
+ return -1;
+ }
+ }
+
+ // Check if line terminating character was received
+ if (szLine[i] == cLineTerm)
+ {
+ break;
+ }
+ }
+
+ // Terminate with \0
+ szLine[i] = 0;
+
+ // Trim for '\r' linefeed at the end
+ if( (i >0) && (szLine[i-1] == '\r')) {
+ i--;
+ szLine[i] = 0;
+ }
+
+ // return number of characters received in the line or return -2 if an empty line was received
+ if ((i == 0) || ((i==1) &&(szLine[0] == '\r')))
+ {
+ // empty line received, so return -2
+ return -2;
+ }
+ return i;
+}
+
+int HTTPConnection::parse(char* buffer)
+{
+ // Check if buffer is invalid or its content not long enough.
+ if ((buffer == NULL) || (strlen(buffer) < 4)) {
+ ERR("Buffer content is invalid or too short.");
+ return -1;
+ }
+
+ std::vector<std::string> args;
+ args.clear();
+
+ int argno = 0;
+ // decompose string into a list of arguments
+ char s = 0; // current starting char
+ int nLen = strlen(buffer)+1;
+
+
+ //for(int i = 0; i < nLen; i++)
+ //printf("%d : %c\r\n", i, buffer[i]);
+
+
+ for (int i = 0 ; i < nLen ; i++) {
+ if ((buffer[i] == ' ') || (buffer[i] == '\n') || (buffer[i] == 0)) {
+ // new arg found
+ buffer[i] = 0;
+ if (argno++ == 1) {
+ // its the uri
+ // parse the uri args
+ parseUriArgs(&buffer[s], m_Msg.args);
+ }
+ INFO("Found argument \"%s\"", &buffer[s]);
+ args.push_back(&buffer[s]);
+ s = i+1;
+ }
+ }
+
+ // store the uri and the HTTP version
+ m_Msg.uri = args[1];
+ m_Msg.version = args[2];
+
+ // Find matching request type
+ for (int i = 0 ; i < sizeof(g_requestConfig)/sizeof(struct HTTPRequestConfig) ; i++) {
+ if (args.at(0) == g_requestConfig[i].request_string) {
+ m_Msg.request = g_requestConfig[i].request_type;
+ }
+ }
+ args.clear();
+
+ return 1;
+}
+
+
+int HTTPConnection::parseHeader(char *buffer)
+{
+ // Check if the buffer is invalid or if the content is too short to be meaningful
+ if ((strlen(buffer) <3) || (buffer == NULL))
+ return -1;
+
+ //Find Content length
+ if(strncmp(buffer, "Content-Length", 14) == 0)
+ {
+ m_Msg.attri_len = atoi(&buffer[16]);
+ return m_Msg.attri_len;
+ }
+ /*
+ for (int i = 0 ; i < buflen ; i++) {
+ if (buffer[i] == ':') {
+ // touple found
+ buffer[i] = 0;
+ value_start = i+1;
+ m_Msg.headers[buffer] = &buffer[value_start];
+
+ INFO("Header name=\"%s\" : value=\"%s\".", buffer, &buffer[value_start]);
+ return 0;
+ }
+ }
+ */
+ return 0;
+ //ERR("Did not recieve a valid header : \"%s\".", buffer);
+ //return -1;
+}
+
+int HTTPConnection::parseUriArgs(char *buffer, map<string,string>&args)
+{
+ // Check if the buffer is invalid or if the content is too short to be meaningful
+ if ((strlen(buffer) <3) || (buffer == NULL))
+ return -1;
+
+ int args_start = -1;
+ int value_start = -1;
+ int buflen = strlen(buffer) +1;
+ const char* argname = NULL;
+ const char* valuename = NULL;
+ for (int i = 0; i < buflen ; i++) {
+ if (args_start == -1) { // args section not yet found
+ if (buffer[i] == '?') { // starts with a question mark, so got it
+ buffer[i] = 0;
+ args_start = i; // set the start of the args section
+ INFO("Argument section found !");
+ }
+ }
+ else { // search arg-value touples
+ if (argname == NULL) { // arg-name found ?
+ if (buffer[i] == '=') {
+ // yes, separate the arg-name
+ buffer[i] = 0;
+ argname = &buffer[args_start];
+ value_start = i+1;
+ INFO("Argument name %s", argname);
+ }
+ }
+ else { // search for end of value
+ if ((buffer[i] == '&') || (buffer[i] == 0) || (buffer[i] == '\r') || (buffer[i] == '\n')) {
+ buffer[i] = 0;
+ valuename = &buffer[value_start];
+ INFO("Argument value %s", valuename);
+ args[argname] = valuename;
+ // reset all indicators
+ argname = NULL;
+ valuename = NULL;
+ }
+ }
+ }
+ }
+
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPConnection.h Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,143 @@
+/* HTTPConnection.h */
+/*
+Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef __HTTPConnection_H__
+#define __HTTPConnection_H__
+
+#include "mbed.h"
+#include "TCPSocketConnection.h"
+
+#include <string>
+#include <map>
+
+class HTTPServer;
+
+/** Type HTTPRequestType enumerates request types
+*/
+typedef enum
+{
+ HTTP_RT_GET, /*!< GET request */
+ HTTP_RT_POST, /*!< POST request */
+ HTTP_RT_PUT, /*!< PUT request */
+ HTTP_RT_OPTIONS, /*!< OPTIONS request */
+ HTTP_RT_HEAD, /*!< HEAD request */
+ HTTP_RT_DELETE, /*!< DELETE request */
+ HTTP_RT_TRACE, /*!< TRACE request */
+ HTTP_RT_CONNECT /*!< CONNECT request */
+} HTTPRequestType;
+
+/** class HTTPConnection, encapsulates one connection being made throught the HTTPServer
+ *
+ */
+class HTTPConnection {
+ public:
+
+ /** HTTPMessage contains all the details of the request received by external HTTP client.
+ */
+ typedef struct
+ {
+ /** Specifies the request type received
+ */
+ HTTPRequestType request;
+ /** The uri associated with the request.
+ */
+ std::string uri;
+ /** Contains the HTTP/1.1 or HTTP/1.0 version requested by client.
+ */
+ std::string version;
+ /** Map of headers provided by the client in the form <HeaderName>:<HeaderValue>
+ */
+ std::map<std::string, std::string> headers;
+ /** Map of arguments that came with the uri string
+ */
+ std::map<std::string, std::string> args;
+
+ //attribute data
+ char attri[50];
+ //attribute length
+ uint32_t attri_len;
+ } HTTPMessage;
+
+ /** Public constructor for HTTPConnection objects.
+ *
+ */
+ HTTPConnection (TCPSocketConnection& clnt);
+
+ /** Destructor for HTTPConnection objects.
+ *
+ */
+ ~HTTPConnection();
+
+ /** Query if this connection is already closed and can be deleted.
+ @returns true, if connection is closed.
+ */
+ bool is_closed();
+
+ /** Polling function for the connection.
+ * @returns -1 if connection is not required anymore. In the current version of this library this should be the normal case. This may change in future versions.
+ */
+ int poll();
+
+ protected:
+
+ /** Function to close this connection. To be called from internally.
+ */
+ void close();
+
+ friend class HTTPServer;
+
+ TCPSocketConnection m_Tcp;
+ HTTPMessage m_Msg;
+
+ /** parse a HTTP request line from the content of the buffer.
+ * @param buffer : the request received from the client in the form <RequestType> <uri> <Http Version>
+ * @returns -1 if the request is invalid or 0 if the request is valid
+ */
+ int parse(char *buffer);
+
+ /** parses the received string in \c buffer for HTTP request headers.
+ * @param buffer : buffer which contains the string to parse for headers.
+ * @returns -1 in case of an error, otherwise returns 0
+ */
+ int parseHeader(char *buffer);
+ int receiveHeaders(const char* buffer, int nBuffSize);
+
+ /** Function which receives a line from the current Socket
+ * @param szline : will contain one line received from the socket
+ * @param nMaxLen : the size of the buffer. If the line is longer than the buffer the line is cropped at the end.
+ * @param nTimeout : if the timeout elapses, only the portion that has been received within this time will be returned.
+ * @param szLineTerm : the \c end-of-line character to be used to detect the end of the line.
+ * @returns -1 in case of an error or timeout, -2 in case of an empty line or the number of received characters.
+ */
+ int receiveLine(char* szLine, int nMaxLen, int nTimeout = -1, char szLineTerm = '\n');
+
+
+ /** parse the receoved \c uri_string for arguments which will be stored in the \c args map.
+ * @parse uri_string : the uri string which was received from the client.
+ * @parse args : the args map which will receive the argument:value touples from the \c uri_string.
+ * @returns -1 if an error occured, otherwise returns 0.
+ */
+ int parseUriArgs(char *uri_string, map<string,string>& args);
+
+};
+
+#endif // __HTTPConnection_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPRequestHandler.cpp Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,176 @@
+/* HTTPRequestHandler.cpp */
+#include "mbed.h"
+#include "HTTPRequestHandler.h"
+//#define DEBUG
+#include "hl_debug.h"
+#include <ctype.h>
+
+
+static char buffer[128];
+
+
+const char hdrStandard[] = "DNT: 1\r\n"
+ "MaxAge: 0\r\n"
+ "Connection: Keep-Alive\r\n"
+ "Content-Type: text/html\r\n"
+ "Server: mbed embedded\r\n"
+ "Accessible: 1\r\n"
+ "\r\n";
+
+
+static int _stricmp(const char* a, const char* b)
+{
+ int la = strlen(a);
+ int lb = strlen(b);
+ for (int i = 0 ; i < min(la, lb) ; i++) {
+ if (tolower((int)a[i]) != tolower((int)b[i]))
+ return i;
+ }
+ return 0;
+}
+
+
+static const struct mapping_t {
+ const char* key;
+ const char* value;
+} fileTypeMapping[] = {
+ {".gif", "Content-Type: image/gif\r\n" },
+ {".jpg", "Content-Type: image/jpeg\r\n" },
+ {".jpeg","Content-Type: image/jpeg\r\n" },
+ {".ico", "Content-Type: image/x-icon\r\n"},
+ {".png", "Content-Type: image/png\r\n" },
+ {".zip", "Content-Type: image/zip\r\n" },
+ {".gz", "Content-Type: image/gz\r\n" },
+ {".tar", "Content-Type: image/tar\r\n" },
+ {".txt", "Content-Type: plain/text\r\n" },
+ {".pdf", "Content-Type: application/pdf\r\n" },
+ {".htm", "Content-Type: text/html\r\n" },
+ {".html","Content-Type: text/html\r\n" },
+ {".css", "Content-Type: text/css\r\n" },
+ {".js", "Content-Type: text/javascript\r\n"}};
+
+HTTPRequestHandler::HTTPRequestHandler(HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp)
+ : msg(Msg), tcp(Tcp)
+{
+ msg = Msg;
+ tcp = Tcp;
+
+}
+
+HTTPRequestHandler::~HTTPRequestHandler()
+{
+}
+
+void HTTPRequestHandler::getStandardHeaders(HTTPHeaders& header, const char* fext)
+{
+ header.clear();
+ header["DNT"] = "1";
+ header["MaxAge"] = "0";
+ header["Connection"] = "Keep-Alive";
+ header["Server"] = "mbed Embedded";
+ if (fext == NULL)
+ header["Content-Type"] = "text/html";
+ else {
+ for (int i = 0 ; i < sizeof(fileTypeMapping)/sizeof(struct mapping_t) ;i++) {
+ if (_stricmp(fileTypeMapping[i].key, fext) == 0) {
+ header["Content-Type"] = fileTypeMapping[i].value;
+ break;
+ }
+ }
+ }
+}
+
+void HTTPRequestHandler::handleRequest()
+{
+ int err = 0;
+
+ switch (msg.request) {
+ case HTTP_RT_GET:
+ INFO("Dispatching GET Request.");
+ err = handleGetRequest();
+ break;
+
+ case HTTP_RT_POST:
+ INFO("Dispatching POST request.");
+ err = handlePostRequest();
+ break;
+
+ case HTTP_RT_PUT:
+ INFO("Dispatching PUT request.");
+ err = handlePutRequest();
+ break;
+
+ default:
+ INFO("Error in handleRequest, unhandled request type.");
+ err = HTTP_NotImplemented;
+ break;
+ }
+
+ // if any of these functions returns a negative number, call the error handler
+ if (err > 0) {
+ handleError(err);
+ }
+}
+
+static const char* szErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error</h1><P>HTTPServer Error<P></BODY></HTML>\r\n\r\n";
+
+void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header)
+{
+ INFO("Handling error !");
+ tcp.set_blocking(false, 1500);
+ sprintf(buffer,"HTTP/1.1 %d Error\r\n", errorCode);
+ tcp.send(buffer, strlen(buffer));
+ sprintf(buffer, "Content-Length: %d\r\n", strlen(szErrorPage));
+ tcp.send(buffer, strlen(buffer));
+ if (header == NULL) {
+ sprintf(buffer, "Content-Type: text/html\r\nServer: mbed embedded\r\n\n\r");
+ tcp.send(buffer, strlen(buffer));
+ }
+ else {
+ for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
+ tcp.send((char*)cIter->first, strlen(cIter->first));
+ tcp.send(": ", 2);
+ tcp.send((char*)cIter->second, strlen(cIter->second));
+ tcp.send("\r\n",2);
+ }
+ tcp.send("\r\n",2);
+ }
+ tcp.send((char*)szErrorPage, strlen(szErrorPage));
+}
+
+
+void HTTPRequestHandler::startResponse(int returnCode, long nLen, HTTPHeaders* header)
+{
+ INFO("Starting response (%ld bytes in total)!", nLen);
+ tcp.set_blocking(false, 1500);
+ sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode);
+ tcp.send(buffer, strlen(buffer));
+ sprintf(buffer, "Content-Length: %ld\r\n", nLen); // Add 2 chars for the terminating CR+LF
+ tcp.send(buffer, strlen(buffer));
+ INFO("Sending standard headers !");
+ if (header == NULL) {
+ tcp.send_all((char*)hdrStandard, strlen(hdrStandard));
+ }
+ else {
+ for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
+ tcp.send_all((char*)cIter->first, strlen(cIter->first));
+ tcp.send_all(": ", 2);
+ tcp.send_all((char*)cIter->second, strlen(cIter->second));
+ tcp.send_all("\r\n\r\n",2);
+ }
+ tcp.send_all("\r\n", 2);
+ }
+ INFO("Proceeding !");
+ // other content must be sent using the 'processResponse' function
+}
+
+void HTTPRequestHandler::processResponse(int nLen, char* body)
+{
+ INFO("Processing Response (%d bytes)!\n",nLen);
+ tcp.send_all(body, nLen);
+}
+
+void HTTPRequestHandler::endResponse()
+{
+ INFO("Ending Response !");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPRequestHandler.h Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,139 @@
+/* HTTPRequestHandler.h */
+/*
+Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef __HTTPREQUESTHANDLER_H__
+#define __HTTPREQUESTHANDLER_H__
+
+#include "mbed.h"
+#include "HTTPConnection.h"
+
+#include <map>
+
+typedef std::map<const char*,const char*> HTTPHeaders;
+
+typedef enum {
+ HTTP_Continue = 100, // 100
+ HTTP_SwitchingProtocols = 101, // 101
+ HTTP_Ok = 200, // 200
+ HTTP_Created = 201, // 201
+ HTTP_Accepted = 202, // 202
+ HTTP_NonAuthoritativeInformation = 203, // 203
+ HTTP_NoContent = 204, // 204
+ HTTP_ResetContent = 205, // 205
+ HTTP_PartialContent = 206, // 206
+ HTTP_MultipleChoices = 300, // 300
+ HTTP_MovedPermanently = 301, // 301
+ HTTP_Found = 302, // 302
+ HTTP_SeeOther = 303, // 303
+ HTTP_NotModified = 304, // 304
+ HTTP_UseProxy = 305, // 305
+ HTTP_TemporaryRedirect = 307, // 307
+ HTTP_BadRequest = 400, // 400
+ HTTP_Unauthorized = 401, // 401
+ HTTP_PaymentRequired = 402, // 402
+ HTTP_Forbidden = 403, // 403
+ HTTP_NotFound = 404, // 404
+ HTTP_MethodNotAllowed = 405, // 405
+ HTTP_NotAcceptable = 406, // 406
+ HTTP_ProxyAuthRequired = 407, // 407
+ HTTP_RequestTimeOut = 408, // 408
+ HTTP_Conflict = 409, // 409
+ HTTP_Gone = 410, // 410
+ HTTP_LengthRequired = 411, // 411
+ HTTP_PreconditionFailed = 412, // 412
+ HTTP_RequestEntityTooLarge = 413, // 413
+ HTTP_RequestURITooLarge = 414, // 414
+ HTTP_UnsupportedMediaType = 415, // 415
+ HTTP_RequestedRangeNotSatisfiable = 416, // 416
+ HTTP_ExpectationFailed = 417, // 417
+ HTTP_InternalServerError = 500, // 500
+ HTTP_NotImplemented = 501, // 501
+ HTTP_BadGateway = 502, // 502
+ HTTP_ServiceUnavailable = 503, // 503
+ HTTP_GatewayTimeout = 504, // 504
+ HTTP_HTTPVersionNotSupported = 505, // 505
+} HTTPResponseCode;
+
+/** class HTTPRequestHandler is the base class for HTTP Handler request implementations.
+*
+*/
+class HTTPRequestHandler
+{
+ protected:
+ HTTPConnection::HTTPMessage& msg;
+ TCPSocketConnection& tcp;
+
+ public:
+ /** Constructor for HTTPRequestHandler objects.
+ */
+ HTTPRequestHandler(HTTPConnection::HTTPMessage&, TCPSocketConnection&);
+
+ /** Destructor for HTTPRequestHandler objects.
+ */
+ virtual ~HTTPRequestHandler();
+
+ /** Handler function which will be used by the HTTPServer to serve requests.
+ * The default version of this function will dispatch respective handler member
+ * functions according to the request type given in the HTTPMessage object.
+ * The list of possible functions dispatched is :
+ * * handleGetRequest
+ * * handlePostRequest
+ * * handlePutRequest
+ */
+ virtual void handleRequest();
+
+ /** Handler function which will handle errors and return errors correctly
+ * @param errorCode : The error code returned by the HTTP Server to represent the error condition.
+ * @param msg : Request Message information.
+ * @param tcp : The socket which represents the active connection to the client.
+ */
+ virtual void handleError(int errorCode, HTTPHeaders* header = NULL);
+
+ /** Function sends the response header which consists of the return code and the headers section
+ * the response header also contains the length (in bytes) of the body. You need to send the body
+ * right after calling this function. Please note that you do not need to consider the terminating
+ * CR+LF after your last CR+LF. This will be sent automatically once \c endResponse is called. Also
+ * the Length given in \c nLen does not need to consider this additional chars. It will also be
+ * automatically added in \c startResponse. if you need to change the headers, please do NOT
+ * specify the \c Content-Length Header. This is done automatically be the function.
+ */
+ void startResponse(int returnCode, long nLen, HTTPHeaders* header = NULL);
+ void processResponse(int nLen, char* body );
+ void endResponse();
+
+ protected:
+ /** Handler function to serve GET requests. Download ressource from server from \c uri location.
+ */
+ virtual int handleGetRequest() = 0;
+
+ /** Handler function to serve PUT requests. Upload ressource to server to \c uri location.
+ */
+ virtual int handlePutRequest() = 0;
+
+ /** Handler function to serve POST requests. Send data to webserver. Can also be appended to uri.
+ */
+ virtual int handlePostRequest() = 0;
+
+ void getStandardHeaders(HTTPHeaders& header, const char* fext = NULL);
+};
+
+#endif // __HTTPREQUESTHANDLER_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPServer.cpp Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,127 @@
+#include "mbed.h"
+#include "HTTPServer.h"
+//#define DEBUG
+#include "hl_debug.h"
+
+
+
+/* Constructor */
+/* initialize all members and set the standard error handler. */
+HTTPServer::HTTPServer()
+ : m_pEthernet(NULL)
+{
+ m_pErrorHandler = StdErrorHandler;
+}
+
+HTTPServer::~HTTPServer()
+{
+ if (m_pEthernet == NULL) {
+ INFO("Deleting EthernetInterface Object.\n");
+ delete m_pEthernet;
+ }
+}
+
+static const char* szStdErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error 404</h1><P>This resource is not available<P></BODY></HTML>\r\n\r\n";
+
+void HTTPServer::StdErrorHandler(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp)
+{
+ char echoHeader[256];
+ tcp.set_blocking(true, 1500);
+ sprintf(echoHeader,"HTTP/1.0 404 Fail\r\nConnection: close\r\nContent-Length: %d\r\nContent-Type: text/html\r\nServer: mbed embedded\r\n\n\r",strlen(szStdErrorPage));
+ tcp.send(echoHeader, strlen(echoHeader));
+ tcp.send((char*)szStdErrorPage, strlen(szStdErrorPage));
+}
+
+
+bool HTTPServer::start(int port, EthernetInterface* pEthernet)
+{
+ // If no ethernet interface is provided, instantiate own on the heap. This has to be deleted later in the destructor.
+ // If a valid pointer to an thernet interface is proveded, we can simply use it.
+ if (pEthernet == NULL) {
+ ERR("Socket is not opened!!\r\n");
+
+ } else {
+ // In the case that the ethernet interface is provided, it is assumed that a connection has already been created.
+ INFO("Using connection IP %s", pEthernet->getIPAddress());
+ }
+
+ INFO("Binding to port %d...", port);
+ if (m_Svr.bind(port) < 0) {
+ ERR("Failed to bind to port !\n");
+ error("Binding");
+ return false;
+ }
+
+ INFO("Listening ...");
+ if (m_Svr.listen(1) < 0) {
+ ERR("Failed to listen !\n");
+ error("Listening");
+ return false;
+ }
+
+ INFO("Connected !");
+ // set into non blocking operation
+ m_Svr.set_blocking(false, 100);
+
+ return true;
+}
+
+
+int HTTPServer::poll(bool blocking)
+{
+ // This thread basically checks if there is a new incoming connection.
+ // If so , a new HTTPConnection is created and the connection thread is started.
+ TCPSocketConnection Clnt;
+ if (m_Svr.accept(Clnt) < 0) {
+ return -1;
+ }
+
+ // a new connection was received
+ INFO("Client (IP=%s) is connected !\n", Clnt.get_address());
+ HTTPConnection con(Clnt);
+ int c = con.poll();
+ if (c == 0) {
+ // Handle the request
+ INFO("Handling request !");
+ HandleRequest(con.m_Msg, Clnt);
+ }
+ if (c == -1) {
+// break;
+ }
+
+ INFO("Leaving polling thread");
+ return 0;
+}
+
+void HTTPServer::HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp)
+{
+ std::string localPath;
+ std::map<std::string, HTTPRequestHandler*(*)(const char*, const char*, HTTPConnection::HTTPMessage&, TCPSocketConnection&), handlersComp>::const_iterator it;
+
+ // Iterate through registered handlers and check if the handler's path is a subset of the requested uri.
+ for (it = m_lpHandlers.begin() ; it != m_lpHandlers.end() ; it++) {
+ // check if this entries' path is fully contained at the beginning of the requested path
+ std::string curpth = it->first;
+
+ if (msg.uri.find(curpth) == 0) {
+ // firts matching handler found, we just take it and we'll be happy
+ localPath = msg.uri.substr(curpth.length());
+ break;
+ }
+ }
+
+ if (it == m_lpHandlers.end()) {
+ // There is no such handler, so return invalid
+
+ m_pErrorHandler(msg, tcp);
+ INFO("Webrequest left unhandled.");
+ } else {
+ // Valid handler was found
+ INFO("Routing webrequest !");
+ // Instantiate the handler object (handling will be done from withing the object's constructor
+ HTTPRequestHandler *phdl = (*it->second)(it->first.c_str(), localPath.c_str(), msg, tcp);
+ // now we can delete the object, because handling is completed.
+ if (phdl != NULL)
+ delete phdl;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPServer.h Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,210 @@
+/* HTTPServer.cpp */
+/*
+Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef __HTTPSERVER_H__
+#define __HTTPSERVER_H__
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "HTTPConnection.h"
+#include "HTTPRequestHandler.h"
+
+#include <map>
+using std::map;
+#include <string>
+using std::string;
+
+#include <TCPSocketConnection.h>
+#include <TCPSocketServer.h>
+
+/** Typedefinition for a handler function
+*/
+typedef void (*HTTPRequestHandlerFunction)(HTTPConnection::HTTPMessage&, TCPSocketConnection&);
+
+
+/** Class HTTPServer for use with <a href="http://mbed.org/users/samux/code/WiflyInterface/">WiflyInterface</a>.
+* This class is a simple implementation of an HTTP Server for use with the WiFly interface.
+* The class will listen for incoming connections on the (configurable) HTTP port. For each
+* incoming connection, one request will be processed.
+* After instantiating this class, add all required handlers using the \c addHandler function,
+* replace the default error handler using \c addErrorHandler if needed and call the \c start
+* method to initialize the class.
+* You need to continuously poll for any new incoming connections after one request has been
+* served using the \c poll member function.
+*
+* \b Example:
+* @code
+* #include "mbed.h"
+* #include "HTTPServer.h"
+* #include "LocalFileSystem.h"
+*
+* LocalFileSystem local("local");
+*
+* void main(void)
+* {
+* HTTPServer svr;
+* svr.mount("/local/", "/");
+* svr.addHandler<HTTPFsRequestHandler>( "/" );
+* svr.start();
+* while(1)
+* {
+* if (svr.poll() < 0)
+* exit(0);
+* }
+* }
+* @endcode
+*
+* An alternate approach e.g. if you need to perform additional tasks using the EthernetInterface
+* there is the possibility to provide the EthernetInterface object in an initialized and connected
+* state. __NOTE: You should choose this scenario for compatibility reasons.___
+*
+* \b Example2:
+* @code
+* #include "mbed.h"
+* #include "HTTPServer.h"
+* #include "EthernetInterface.h"
+* #include "LocalFileSystem.h"
+*
+* LocalFileSystem local("local");
+* EthernetInterface eth;
+*
+* void main(void)
+* {
+* HTTPServer svr;
+* // Initialize the ethernet interface
+* if (eth.init() != 0) {
+* printf("Initialization of EthernetInterface failed !");
+* exit(0);
+* }
+* // Connect using DHCP
+* if (eth.connect() !=0) {
+* printf("Failed to connect using DHCP !");
+* exit(0);
+* }
+*
+* // Moint the local file system and provide a handler for 'root'.
+* svr.mount("/local/", "/");
+* svr.addHandler<HTTPFsRequestHandler>( "/" );
+* // Start the server on port 80, providing our own ethernet interface object.
+* svr.start(80, ð);
+* while(1)
+* {
+* if (svr.poll() < 0)
+* exit(0);
+* }
+* }
+* @endcode
+*
+*/
+class HTTPServer
+{
+ TCPSocketServer m_Svr;
+ bool m_bServerListening;
+ EthernetInterface* m_pEthernet;
+
+ public:
+ /** Constructor for HTTPServer objects.
+ */
+ HTTPServer();
+
+ /** Destructor for HTTPServer objects.
+ */
+ ~HTTPServer();
+
+ /**
+ * Structure which will allow to order the stored handlers according to their associated path.
+ */
+ struct handlersComp //Used to order handlers in the right way
+ {
+ bool operator() (const string& handler1, const string& handler2) const
+ {
+ //The first handler is longer than the second one
+ if (handler1.length() > handler2.length())
+ return true; //Returns true if handler1 is to appear before handler2
+ else if (handler1.length() < handler2.length())
+ return false;
+ else //To avoid the == case, sort now by address
+ return ((&handler1)>(&handler2));
+ }
+ };
+
+ /**
+ * Adds a request handler to the handlers list. You will have to use one of the existing implementations.
+ * With each handler a \c uri or \c path is associated. Whenever a request is received the server will
+ * walk through all registered handlers and check which \c path is matching.
+ * @param T : class which will be instanciated to serve these requests for the associated \b path.
+ * @param path : request uri starting with this \c path will be served using this handler.
+ */
+ template<typename T>
+ void addHandler(const char* path)
+ { m_lpHandlers[path] = &T::create; }
+
+ /**
+ * Replaces the standard error Handler. The error Handler will be called everytime a request is not
+ * matching any of the registered \c paths or \c uris.
+ * @param hdlFunc: User specified handler function which will be used in error conditions.
+ */
+ void addErrorHandler(HTTPRequestHandlerFunction hdlFunc)
+ { m_pErrorHandler = hdlFunc!=NULL ?hdlFunc : StdErrorHandler; }
+
+ /** Binds server to a specific port and starts listening. This member prepares the internal variables and the server socket
+ * and terminates after successfull initialization
+ * @param port : port on which to listen for incoming connections
+ * @param pEthernet : a pointer to an existing EthernetInterface object or NULL if the HTTPServer shall allocate the object. _Please note that for compatibility reasons
+ * your should consider to create the EthernetInterface as a static variable. Otherwise the the object will be created on the heap._
+ * @returns : false if an unrecoverable error occured or if the ethernet interface was not set or not initialized correctly, or true if everything was ok.
+ */
+ bool start(int port = 80, EthernetInterface* pEthernet = NULL);
+
+ /** Performs the regular polling of the server component. Needs to be called cyclically.
+ * The function will internally check whether new connections are requested by a client and will also poll all existing client connections.
+ * @param blocking : if true,
+ * @returns -1 if there was a problem. If 0 is returned, the latest request was served successfully and the server is
+ * ready for processing the next request. Simply call \c poll as long as you want to serve new incoming requests.
+ */
+ int poll(bool blocking = true);
+
+ private:
+
+ /** The standard error handler function.
+ * @param msg : Request message data.
+ * @param tcp : Socket to be used for responding.
+ */
+ static void StdErrorHandler(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp);
+
+ /** Internal function which processes a request and which will try to find the matching handler function
+ * for the given request. Please note that the function will search through the list of handlers, iterating
+ * from longest to shortest \c paths. If the registered \c path is a subset of the request the associated
+ * handler is considered as being a match.
+ * @param msg : Request message data. Contains the requested logical \c uri.
+ * @param tcp : Socket to be used for communication with the client.
+ */
+ void HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp);
+
+ /** Map of handler objects. Can be any object derived from \ref HTTPRequestHeader. Use the \ref addHandler function
+ * to register new handler objects.
+ */
+ map<string, HTTPRequestHandler* (*)(const char*, const char*, HTTPConnection::HTTPMessage&, TCPSocketConnection&), handlersComp> m_lpHandlers;
+ HTTPRequestHandlerFunction m_pErrorHandler;
+
+ };
+
+ #endif //__HTTPSERVER_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/FsHandler.cpp Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,211 @@
+/* FsHandler.cpp */
+#include "mbed.h"
+#include "FsHandler.h"
+//#define DEBUG
+#include "hl_debug.h"
+
+DigitalOut led_red(LED1);
+DigitalOut led_green(LED2);
+DigitalOut led_blue(LED3);
+
+DigitalIn din(PC_14);
+
+
+static int matchstrings(const char* one, const char* two)
+{
+ int m = 0;
+
+ for (m = 0; m < min(strlen(one), strlen(two)) ; m++) {
+ if (one[m] != two[m])
+ return m;
+ }
+ return m;
+}
+
+std::map<const char*, const char*> HTTPFsRequestHandler::m_fsMap;
+
+HTTPFsRequestHandler::HTTPFsRequestHandler(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp)
+ : HTTPRequestHandler(Msg, Tcp)
+{
+ m_rootPath = rootPath;
+ m_localPath = localPath;
+
+ string myPath = m_rootPath + m_localPath;
+
+ // Now replace the virtual root path with a mounted device path
+ std::map<const char*, const char*>::iterator it;
+ const char *bestMatch = NULL;
+ const char *bestMatchExchange = NULL;
+ int match_ind = -1;
+ for (it = m_fsMap.begin() ; it != m_fsMap.end() ; it++) {
+ // find best match (if the given logical path is containted in the root
+ int s = matchstrings(myPath.c_str(), it->second);
+ INFO("Matching Root %s with handler %s results in %d identical characters\n", myPath.c_str(), it->second, s);
+ if ((s == strlen(it->second)) && (s > match_ind)) {
+ match_ind = s;
+ bestMatch = it->first;
+ bestMatchExchange = it->second;
+ }
+ }
+
+ if (bestMatch != NULL) {
+ m_rootPath = bestMatch;
+ m_localPath = string(myPath).substr(strlen(bestMatchExchange));
+ }
+
+ handleRequest();
+}
+
+HTTPFsRequestHandler::~HTTPFsRequestHandler()
+{
+}
+
+int HTTPFsRequestHandler::handleGetRequest()
+{
+ HTTPHeaders headers;
+ int retval = 0; //success
+ uint8_t pin_state;
+
+ if( std::string::npos != msg.uri.find("get_dio14.cgi") )
+ {
+ if(din)
+ pin_state = 1;
+ else
+ pin_state = 0;
+
+ /*
+ *len = sprintf((char *)buf, "DioCallback({\"dio_p\":\"14\",\
+ \"dio_s\":\"%d\"\
+ });",
+ pin_state // Digital io status
+ );
+
+
+ Tcp.
+ */
+ }
+ else //read html pages
+ {
+ if (m_localPath.length() > 4)
+ getStandardHeaders(headers, m_localPath.substr(m_localPath.length()-4).c_str());
+ else
+ getStandardHeaders(headers);
+
+ INFO("Handling Get Request (root = %s, local = %s).", m_rootPath.c_str(), m_localPath.c_str());
+
+ std::string reqPath;
+
+ // Check if we received a directory with the local bath
+ if ((m_localPath.length() == 0) || (m_localPath.substr( m_localPath.length()-1, 1) == "/")) {
+ // yes, we shall append the default page name
+ m_localPath += "index.html";
+ }
+
+ reqPath = m_rootPath + m_localPath;
+
+ INFO("Mapping \"%s\" to \"%s\"", msg.uri.c_str(), reqPath.c_str());
+
+ FILE *fp = fopen(reqPath.c_str(), "r");
+ if (fp != NULL) {
+ char * pBuffer = NULL;
+ int sz = 8192;
+ while( pBuffer == NULL) {
+ sz /= 2;
+ pBuffer = (char*)malloc(sz);
+ if (sz < 128)
+ error ("OutOfMemory");
+ }
+
+ // File was found and can be returned
+
+ // first determine the size
+ fseek(fp, 0, SEEK_END);
+ long size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ startResponse(200, size);
+ while(!feof(fp) && !ferror(fp)) {
+ int cnt = fread(pBuffer, 1, sz , fp);
+ if (cnt < 0)
+ cnt = 0;
+ processResponse(cnt, pBuffer);
+ }
+ delete pBuffer;
+ endResponse();
+ fclose(fp);
+ }
+ else {
+ retval = 404;
+ ERR("Requested file was not found !");
+ }
+ }
+
+ return retval;
+}
+
+int HTTPFsRequestHandler::handlePostRequest()
+{
+
+ int pin = 0;
+
+ if( std::string::npos != msg.uri.find("set_dio.cgi") )
+ {
+ pin = get_http_param_value("pin");
+ if(pin == 8)
+ {
+ led_red = get_http_param_value("val");
+ }
+ else if(pin == 9)
+ {
+ led_green = get_http_param_value("val");
+ }
+ else if(pin == 5)
+ {
+ led_blue = get_http_param_value("val");
+ }
+ else
+ {
+ WARN("Wrong pin number");
+ }
+
+ return 0;
+ }
+ else
+ {
+ return 404;
+ }
+}
+
+int HTTPFsRequestHandler::handlePutRequest()
+{
+ return 404;
+}
+
+uint32_t HTTPFsRequestHandler::get_http_param_value(char* param_name)
+{
+ uint8_t * name = 0;
+ uint8_t * pos2;
+ uint16_t len = 0;
+ char value[10];
+ uint32_t ret = 0;
+
+ //msg.attri
+ if((name = (uint8_t *)strstr(msg.attri, param_name)))
+ {
+ name += strlen(param_name) + 1;
+ pos2 = (uint8_t*)strstr((char*)name, "&");
+ if(!pos2)
+ {
+ pos2 = name + strlen((char*)name);
+ }
+ len = pos2 - name;
+
+ if(len)
+ {
+ strncpy(value, (char*)name, len);
+ ret = atoi(value);
+ }
+ }
+ return ret;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Handler/FsHandler.h Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,83 @@
+/* FsHandler.h */
+/*
+Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef __FSHANDLER_H__
+#define __FSHANDLER_H__
+
+#include "mbed.h"
+#include "HTTPRequestHandler.h"
+
+#include <map>
+#include <string>
+
+/** class HTTPFsRequestHandler serves requests with file-system objects
+*/
+class HTTPFsRequestHandler : public HTTPRequestHandler
+{
+ std::string m_rootPath;
+ std::string m_localPath;
+
+ public:
+ /** constructor for HTTPFsRequestHandler object and stores the request related data locally.
+ * the request handling will be initiated from within the constructor.
+ * @param rootPath : The path under which the handler was registered.
+ * @param localPath : The path which is relative to the registered file system root.
+ * @param Msg : Message request information that comes with the request.
+ * @param Tcp : The socket connection for communicating with the client.
+ */
+ HTTPFsRequestHandler(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp);
+
+ /** Destructor
+ */
+ virtual ~HTTPFsRequestHandler();
+
+ /** static creation function for this object.
+ */
+ static inline HTTPRequestHandler* create(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp) { return new HTTPFsRequestHandler(rootPath, localPath, msg, tcp); }
+
+ /** Handler function to serve GET requests
+ */
+ virtual int handleGetRequest();
+
+ /** Handler function to serve PUT requests
+ */
+ virtual int handlePutRequest();
+
+ /** Handler function to serve POST requests
+ */
+ virtual int handlePostRequest();
+
+ /** Map to register different file system types and associate them with different root paths
+ */
+ static std::map<const char*, const char*> m_fsMap;
+
+ /** static function to register a new file system type with a logical root path
+ */
+ static void mount(const char* requestPath, const char* localPath) { m_fsMap[requestPath] = localPath; }
+
+ /** Parse a uri string for uri file name and argument:value pairs
+ */
+ int parseUriArgs(string uri, map<string, string>& args);
+
+ uint32_t get_http_param_value(char* param_name);
+};
+#endif // __FSHANDLER_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hl_debug.h Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,16 @@
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+
+#ifdef DEBUG
+#define INFO(x, ...) std::printf("[INFO: %s:%d]"x"\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[WARN: %s:%d]"x"\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define ERR(x, ...) std::printf("[ERR: %s:%d]"x"\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define INFO(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+#endif
+
+
+#endif // __DEBUG_H__#ifndef __DEBUG_H__
