Changes made for RPC
Revision 5:dc88012caef1, committed 2013-06-01
- Comitter:
- leihen
- Date:
- Sat Jun 01 06:24:43 2013 +0000
- Parent:
- 4:d065642c32cc
- Child:
- 6:fe661fa9d18a
- Commit message:
- Now also supporting RPC get requests
Changed in this revision
--- a/HTTPRequestHandler.h Tue May 28 21:20:58 2013 +0000 +++ b/HTTPRequestHandler.h Sat Jun 01 06:24:43 2013 +0000 @@ -30,10 +30,52 @@ 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:
--- a/HTTPServer.cpp Tue May 28 21:20:58 2013 +0000 +++ b/HTTPServer.cpp Sat Jun 01 06:24:43 2013 +0000 @@ -91,6 +91,7 @@ int HTTPServer::poll() { + int retval = -1; INFO("Listening for new connection requests."); // This thread basically checks if there is a new incoming connection. @@ -99,8 +100,19 @@ #ifdef _DEBUG led4 = 1; // Indicate we are waiting for a new connection -#endif - if (m_pSvr->accept(Clnt) < 0) { +#endif + m_pSvr->set_blocking(true); + retval = m_pSvr->accept(Clnt); + if (retval > 0) { + // no connection availale yet, so just return +#ifdef _DEBUG +led4 = 0; +led3 = 0; +led2 = 0; +#endif + return retval; + } + if ( retval < 0) { // an error occured ERR("There was an error, Accept returned with an error. Probably the connection to the router was lost. Shutting down server"); #ifdef _DEBUG
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/FsHandler.cpp Sat Jun 01 06:24:43 2013 +0000 @@ -0,0 +1,97 @@ +/* FsHandler.cpp */ +#include "mbed.h" +#include "FsHandler.h" + + +#define _DEBUG 1 + +#if (_DEBUG && !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 = 0; //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; +} + +int HTTPFsRequestHandler::handlePostRequest() +{ + return 404; +} + +int HTTPFsRequestHandler::handlePutRequest() +{ + return 404; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/FsHandler.h Sat Jun 01 06:24:43 2013 +0000 @@ -0,0 +1,81 @@ +/* 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); +}; +#endif // __FSHANDLER_H__ \ No newline at end of file
--- a/Handler/HTTPFsRequestHandler.cpp Tue May 28 21:20:58 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* HTTPFsRequestHandler.cpp */ -#include "mbed.h" -#include "HTTPFsRequestHandler.h" - - -#define _DEBUG 1 - -#if (_DEBUG && !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; -} - -int HTTPFsRequestHandler::handlePostRequest() -{ - return 404; -} - -int HTTPFsRequestHandler::handlePutRequest() -{ - return 404; -} \ No newline at end of file
--- a/Handler/HTTPFsRequestHandler.h Tue May 28 21:20:58 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* 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 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); -}; -#endif // __HTTPFSREQUESTHANDLER_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/RpcHandler.cpp Sat Jun 01 06:24:43 2013 +0000 @@ -0,0 +1,85 @@ +/* FsHandler.cpp */ +#include "mbed.h" +#include "RpcHandler.h" +#include "mbed_rpc.h" + + +#define _DEBUG 1 + +#if (_DEBUG && !defined(TARGET_LPC11U24)) +#define INFO(x, ...) std::printf("[HTTPRpcHandler : DBG]"x"\r\n", ##__VA_ARGS__); +#define WARN(x, ...) std::printf("[HTTPRpcHandler : DBG]"x"\r\n", ##__VA_ARGS__); +#define ERR(x, ...) std::printf("[HTTPRpcHandler : DBG]"x"\r\n", ##__VA_ARGS__); +#else +#define INFO(x, ...) +#define WARN(x, ...) +#define ERR(x, ...) +#endif + +RPC rpc("rpc"); + + +HTTPRpcRequestHandler::HTTPRpcRequestHandler(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp) + : HTTPRequestHandler(Msg, Tcp) +{ + m_rootPath = rootPath; + m_localPath = localPath; + + handleRequest(); +} + + +HTTPRpcRequestHandler::~HTTPRpcRequestHandler() +{ +} + + +int HTTPRpcRequestHandler::handleGetRequest() +{ + char outBuf[256] = {}; + bool retval = false; + int err = 404; + string rpc_args(""); + + INFO("Handling RPC Get Requesst."); + // This version of the RPC handler does only accept native RPC commands in the format + // /<class>/<method> <argument1> [<argument2> [<argument3> ...]] + // So we can simply pass our local pathg to our rpc + + // Append missing slash if needed + if (m_localPath.c_str()[0] != '/') { + rpc_args = "/"; + } + // replace the HTTP strings with ascii strings + for (int i = 0 ; i < m_localPath.length() ; i++) { + if (m_localPath.substr(i,3) == "%20") { + rpc_args += " "; + i+=2; + } + else { + rpc_args += m_localPath.substr(i,1); + } + } + INFO("RPC to %s", rpc_args.c_str()); + retval = rpc.call(rpc_args.c_str(),outBuf); + INFO("RPC Request returned %d with args : %s", retval==true ? 1 : 0, outBuf); + if (retval) { + // No error + startResponse(retval, strlen(outBuf)); + processResponse(strlen(outBuf), outBuf); + endResponse(); + err = 0; + } + + return err; +} + +int HTTPRpcRequestHandler::handlePutRequest() +{ + return 404; +} + +int HTTPRpcRequestHandler::handlePostRequest() +{ + return 404; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Handler/RpcHandler.h Sat Jun 01 06:24:43 2013 +0000 @@ -0,0 +1,68 @@ +/* RpcHandler.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 __RPCHANDLER_H__ +#define __RPCHANDLER_H__ + +#include "mbed.h" +#include "HTTPRequestHandler.h" + +class HTTPRpcRequestHandler : public HTTPRequestHandler +{ + std::string m_rootPath; + std::string m_localPath; + + public: + /** constructor for HTTPRpcRequestHandler 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. + */ + HTTPRpcRequestHandler(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp); + + /** Destructor + */ + virtual ~HTTPRpcRequestHandler(); + + /** static creation function for this object. + */ + static inline HTTPRequestHandler* create(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp) { return new HTTPRpcRequestHandler(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(); + + /** Parse a uri string for uri file name and argument:value pairs + */ +// int parseUriArgs(string uri, string map<string, string>& args); +}; +#endif // __RPCHANDLER_H__ \ No newline at end of file