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: RPC_HTTP RPC_HTTP_WIZnetInterface RPC_HTTP rpc_over_http_TL_interrupter_gatePJ
Fork of HTTPServer by
Revision 3:d6224049b3bf, committed 2013-05-28
- Comitter:
- leihen
- Date:
- Tue May 28 01:56:14 2013 +0000
- Parent:
- 2:8653bbcf7e58
- Child:
- 4:d065642c32cc
- Commit message:
- First beta version
Changed in this revision
--- a/HTTPConnection.cpp Sun May 26 23:22:36 2013 +0000
+++ b/HTTPConnection.cpp Tue May 28 01:56:14 2013 +0000
@@ -178,24 +178,22 @@
}
-int HTTPConnection::parseHeader(const char *buffer)
+int HTTPConnection::parseHeader(char *buffer)
{
if ((strlen(buffer) <3) || (buffer == NULL))
return -1;
// decompose string into a touple of <field name> : <field value>
- static char fieldname[256] = {};
- static char fieldvalue[256] = {};
- for (int i = 0 ; i < strlen(buffer)+1 ; i++) {
+ int value_start = 0;
+ int buflen = strlen(buffer)+1;
+ for (int i = 0 ; i < buflen ; i++) {
if (buffer[i] == ':') {
// touple found
- strncpy(fieldname, buffer, i);
- fieldname[i] = 0;
- strcpy(fieldvalue, &buffer[i+1]);
-
-// m_Msg.headers[fieldname] = fieldvalue;
+ buffer[i] = 0;
+ value_start = i+1;
+ m_Msg.headers[buffer] = &buffer[value_start];
- INFO("Header name=\"%s\" : value=\"%s\".", fieldname, fieldvalue);
+ INFO("Header name=\"%s\" : value=\"%s\".", buffer, &buffer[value_start]);
return 0;
}
}
--- a/HTTPConnection.h Sun May 26 23:22:36 2013 +0000
+++ b/HTTPConnection.h Tue May 28 01:56:14 2013 +0000
@@ -1,4 +1,25 @@
/* 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__
@@ -10,60 +31,76 @@
class HTTPServer;
-enum HTTPRequestType
+/** Type HTTPRequestType enumerates request types
+*/
+typedef enum
{
- HTTP_RT_GET,
- HTTP_RT_POST,
- HTTP_RT_PUT,
- HTTP_RT_OPTIONS,
- HTTP_RT_HEAD,
- HTTP_RT_DELETE,
- HTTP_RT_TRACE,
- HTTP_RT_CONNECT
-};
+ 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;
-struct HTTPMessage
-{
- HTTPRequestType request;
- std::string uri;
- std::string version;
- std::map<string, string> headers;
-};
/** class HTTPConnection, encapsulates one connection being made throught the HTTPServer
*
*/
class HTTPConnection {
public:
- /** public constructor
- *
- */
- HTTPConnection ();
- ~HTTPConnection();
-
- /** function to close this connection. To be called from internally.
- */
- void close();
-
- /** query if this connection is closed and can be deleted.
- @returns true if connection is closed.
- */
- bool is_closed();
-
- /**
- Polling function
- @returns -1 if connection is not required anymore. Can happen if a fault occured or if the connection is not needed anymore.
- */
- int poll();
+
+ /** 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;
+ } HTTPMessage;
+ /** Public constructor for HTTPConnection objects.
+ *
+ */
+ HTTPConnection ();
+
+ /** 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;
-
int parse(char *buffer);
- int parseHeader(const char *buffer);
+ int parseHeader(char *buffer);
int receiveHeaders(const char* buffer, int nBuffSize);
int receiveLine(char* szLine, int nMaxLen, int nTimeout = -1, char szLineTerm = '\n');
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPFsRequestHandler.cpp Tue May 28 01:56:14 2013 +0000
@@ -0,0 +1,86 @@
+/* HTTPFsRequestHandler.cpp */
+#include "mbed.h"
+#include "HTTPFsRequestHandler.h"
+
+
+
+#if (1 && !defined(TARGET_LPC11U24))
+#define INFO(x, ...) std::printf("[HTTPFsRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[HTTPFsRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
+#define ERR(x, ...) std::printf("[HTTPFsRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
+#else
+#define INFO(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+#endif
+
+
+#define MAX_BUFFERSIZE 128
+static char buffer[MAX_BUFFERSIZE];
+
+
+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;
+
+ // Now replace the virtual root path with a mounted device path
+ std::map<const char*, const char*>::iterator it;
+ for (it = m_fsMap.begin() ; it != m_fsMap.end() ; it++) {
+ // find best match (if the given logical path is containted in the root
+ if (m_rootPath.find( it->second ) == 0) {
+ m_rootPath = it->first;
+ break;
+ }
+ }
+
+ handleRequest();
+}
+
+HTTPFsRequestHandler::~HTTPFsRequestHandler()
+{
+}
+
+int HTTPFsRequestHandler::handleGetRequest()
+{
+ INFO("Handling Get Request.");
+ int retval = 200; //success
+ 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) {
+ // 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(buffer, 1, MAX_BUFFERSIZE , fp);
+ processResponse(cnt, buffer);
+ }
+ endResponse();
+ fclose(fp);
+ }
+ else {
+ retval = 404;
+ ERR("Requested file was not found !");
+ }
+
+ return retval;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPFsRequestHandler.h Tue May 28 01:56:14 2013 +0000
@@ -0,0 +1,50 @@
+/* HTTPFsRequestHandler.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 __HTTPFSREQUESTHANDLER_H__
+#define __HTTPFSREQUESTHANDLER_H__
+
+#include "mbed.h"
+#include "HTTPRequestHandler.h"
+
+#include <map>
+#include <string>
+
+class HTTPFsRequestHandler : public HTTPRequestHandler
+{
+ std::string m_rootPath;
+ std::string m_localPath;
+
+ public:
+ HTTPFsRequestHandler(const char* roottPath, const char* localPath, HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp);
+ virtual ~HTTPFsRequestHandler();
+
+ 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();
+
+ static std::map<const char*, const char*> m_fsMap;
+ static void mount(const char* requestPath, const char* localPath) { m_fsMap[requestPath] = localPath; }
+};
+#endif // __HTTPFSREQUESTHANDLER_H__
\ No newline at end of file
--- a/HTTPRequestHandler.cpp Sun May 26 23:22:36 2013 +0000
+++ b/HTTPRequestHandler.cpp Tue May 28 01:56:14 2013 +0000
@@ -2,11 +2,119 @@
#include "mbed.h"
#include "HTTPRequestHandler.h"
+#if (1 && !defined(TARGET_LPC11U24))
+#define INFO(x, ...) std::printf("[HTTPRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[HTTPRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
+#define ERR(x, ...) std::printf("[HTTPRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
+#else
+#define INFO(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+#endif
-HTTPRequestHandler::HTTPRequestHandler()
+static char buffer[128];
+
+HTTPRequestHandler::HTTPRequestHandler(HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp)
+ : msg(Msg), tcp(Tcp)
{
+ msg = Msg;
+ tcp = Tcp;
}
HTTPRequestHandler::~HTTPRequestHandler()
{
-}
\ No newline at end of file
+}
+
+void HTTPRequestHandler::handleRequest()
+{
+ int err = 0;
+
+ switch (msg.request) {
+ case HTTP_RT_GET:
+ INFO("Dispatching GET Request.");
+ err = handleGetRequest();
+ break;
+
+// case HTTP_RT_POST:
+// err = handlePostRequest();
+// break;
+
+// case HTTP_RT_PUT:
+// err = handlePutRequest();
+// break;
+
+ default:
+ INFO("Error in handleRequest, unhandled request type.");
+ err = 404;
+ 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 %d</h1><P>HTTPServer Error<P></BODY></HTML>\r\n\r\n";
+
+void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header)
+{
+ INFO("Handling error !");
+ tcp.set_blocking(true, 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, int nLen, HTTPHeaders* header)
+{
+ INFO("Starting response !");
+ tcp.set_blocking(true, 1500);
+ sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode);
+ tcp.send(buffer, strlen(buffer));
+ sprintf(buffer, "Content-Length: %d\r\n", nLen + 2); // Add 2 chars for the terminating CR+LF
+ tcp.send(buffer, strlen(buffer));
+ if (header == NULL) {
+ sprintf(buffer, "Content-Type: text/html\r\nServer: mbed embedded\r\n\r\n");
+ 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\r\n",2);
+ }
+ tcp.send("\r\n", 2);
+ }
+ // other content must be sent using the 'processResponse' function
+}
+
+void HTTPRequestHandler::processResponse(int nLen, char* body)
+{
+ INFO("Processing Response !");
+ tcp.send(body, nLen);
+}
+
+void HTTPRequestHandler::endResponse()
+{
+ INFO("Ending Response !");
+ tcp.send("\r\n", 2);
+}
+
--- a/HTTPRequestHandler.h Sun May 26 23:22:36 2013 +0000
+++ b/HTTPRequestHandler.h Tue May 28 01:56:14 2013 +0000
@@ -1,26 +1,91 @@
/* 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;
+
+/** class HTTPRequestHandler is the base class for HTTP Handler request implementations.
+*
+*/
class HTTPRequestHandler
{
+ protected:
+ HTTPConnection::HTTPMessage& msg;
+ TCPSocketConnection& tcp;
+
public:
- /**
- public constructor
+ /** Constructor for HTTPRequestHandler objects.
*/
- HTTPRequestHandler();
+ HTTPRequestHandler(HTTPConnection::HTTPMessage&, TCPSocketConnection&);
+
+ /** Destructor for HTTPRequestHandler objects.
+ */
+ virtual ~HTTPRequestHandler();
+
+ /** Handler function which will be used by the HTTPServer to serve requests.
+ * @param msg : Request Message information.
+ * @param tcp : The socket which represents the active connection to the client.
+ */
+ virtual void handleRequest();
- /**
- destructor
- */
- ~HTTPRequestHandler();
+ /** 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, int nLen, HTTPHeaders* header = NULL);
+ void processResponse(int nLen, char* body );
+ void endResponse();
+
+ protected:
+ /** Handler function to serve GET requests
+ */
+ virtual int handleGetRequest() = 0;
+ /** Handler function to serve PUT requests
+ */
+// virtual int handlePutRequest() = 0;
- void HandleRequest(HTTPMessage& );
-
+ /** Handler function to serve POST requests
+ */
+// virtual int handlePostRequest() = 0;
+
};
#endif // __HTTPREQUESTHANDLER_H__
\ No newline at end of file
--- a/HTTPServer.cpp Sun May 26 23:22:36 2013 +0000
+++ b/HTTPServer.cpp Tue May 28 01:56:14 2013 +0000
@@ -6,7 +6,7 @@
DigitalOut led3(LED3);
DigitalOut led4(LED4);
-#if (0 && !defined(TARGET_LPC11U24))
+#if (1 && !defined(TARGET_LPC11U24))
#define INFO(x, ...) if (m_pDbg) m_pDbg->printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__); else printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__);
#define WARN(x, ...) if (m_pDbg) m_pDbg->printf("[HttpServer : WARN]"x"\r\n", ##__VA_ARGS__); else printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__);
#define ERR(x, ...) if (m_pDbg) m_pDbg->printf("[HttpServer : ERR]"x"\r\n", ##__VA_ARGS__); else printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__);
@@ -16,9 +16,9 @@
#define ERR(x, ...)
#endif
-HTTPServer::HTTPServer(Serial* pDbg)
+HTTPServer::HTTPServer(Serial *dbg)
{
- m_pDbg = pDbg;
+ m_pDbg = dbg;
m_pSvr = NULL;
m_bServerListening = false;
m_pErrorHandler = StdErrorHandler;
@@ -36,7 +36,7 @@
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(HTTPMessage& msg, TCPSocketConnection& tcp)
+void HTTPServer::StdErrorHandler(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp)
{
char echoHeader[512];
@@ -132,7 +132,39 @@
return 0;
}
-void HTTPServer::HandleRequest(HTTPMessage& msg, TCPSocketConnection& tcp)
+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;
+
+ 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) {
+ // handler found
+ 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 {
+ INFO("Routing webrequest !");
+
+ HTTPRequestHandler *phdl = (*it->second)(it->first.c_str(), localPath.c_str(), msg, tcp);
+ if (phdl != NULL)
+ delete phdl;
+ }
+
+}
+/*
+void HTTPServer::HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp)
{
map<string, HTTPRequestHandlerFunction>::iterator it;
@@ -149,4 +181,5 @@
INFO("Routing webrequest !");
(it->second)(msg, tcp);
}
-}
\ No newline at end of file
+}
+*/
\ No newline at end of file
--- a/HTTPServer.h Sun May 26 23:22:36 2013 +0000
+++ b/HTTPServer.h Tue May 28 01:56:14 2013 +0000
@@ -1,4 +1,25 @@
/* 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"
@@ -13,30 +34,66 @@
#include <TCPSocketConnection.h>
#include <TCPSocketServer.h>
-typedef void (*HTTPRequestHandlerFunction)(HTTPMessage&, TCPSocketConnection&);
+/** Typedefinition for a handler function
+*/
+typedef void (*HTTPRequestHandlerFunction)(HTTPConnection::HTTPMessage&, TCPSocketConnection&);
+
-/** Class HTTPServer for WiFly Interface Library
- *
- */
- class HTTPServer
- {
-
+/** 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");
+* WiflyInterface wifly(p9, p10, p25, p26, "<your access point>", "<your password>", WPA);
+*
+* void main(void)
+* {
+* HTTPServer svr;
+ svr.mount("/local/", "/");
+* svr.addHandler<HTTPFsRequestHandler>( "/" );
+* svr.start();
+* while(1)
+* {
+* if (svr.poll() < 0)
+* exit(0);
+* }
+* }
+* @endcode
+*/
+class HTTPServer
+{
public:
- HTTPServer(Serial* pDbg = NULL);
+ /** Constructor for HTTPServer objects.
+ */
+ HTTPServer(Serial* dbg = NULL);
+
+ /** Destructor for HTTPServer objects.
+ */
~HTTPServer();
-
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));
+ //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));
}
};
@@ -46,43 +103,42 @@
@param T : class which will be instanciated to serve these requests
@param path : requests starting with this path will be served using this handler
*/
-// template<typename T>
-// void addHandler(const char* path) //Template decl in header
-// { m_pHandlers[path] = &T::inst; }
-
- void addHandler(const char* path, HTTPRequestHandlerFunction hdlFunc)
- { m_pHandlers[path] = hdlFunc; }
+ 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
+ handled by a handler from the handler list.
+ @param hdlFunc: Handler which serves an error condition.
+ */
void addErrorHandler(HTTPRequestHandlerFunction hdlFunc)
{ m_pErrorHandler = hdlFunc!=NULL ?hdlFunc : StdErrorHandler; }
- ///Starts listening
- /**
- 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
- @returns : -1 if an unrecoverable error occured, or 0 if everything was ok.
+
+ /** 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
+ * @returns : -1 if an unrecoverable error occured, or 0 if everything was ok.
*/
int start(int port = 80);
- /**
- 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.
+ /** 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.
*/
int poll();
-private:
-
- static void StdErrorHandler(HTTPMessage&, TCPSocketConnection&);
-
- TCPSocketServer* m_pSvr;
- bool m_bServerListening;
+ private:
+ static void StdErrorHandler(HTTPConnection::HTTPMessage&, TCPSocketConnection&);
- Serial* m_pDbg;
- void HandleRequest(HTTPMessage& con, TCPSocketConnection&);
-
- map<string, HTTPRequestHandlerFunction> m_pHandlers;
- HTTPRequestHandlerFunction m_pErrorHandler;
+ TCPSocketServer* m_pSvr;
+ bool m_bServerListening;
+
+ Serial* m_pDbg;
+ void HandleRequest(HTTPConnection::HTTPMessage& con, TCPSocketConnection&);
+ 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
