ported HTTP-Server with W5500 Ethernet Shield
Dependencies: W5500Interface mbed-rpc mbed
Fork of HTTP-Server by
Revision 4:624527ebc0fa, committed 2013-07-17
- Comitter:
- feb11
- Date:
- Wed Jul 17 15:00:24 2013 +0000
- Parent:
- 3:fb0a778f2480
- Child:
- 5:8ab27ca793cd
- Commit message:
- Fixed bug in InteractiveHTMLFormatter
Changed in this revision
--- a/Formatter.cpp Wed Jul 17 11:07:06 2013 +0000 +++ b/Formatter.cpp Wed Jul 17 15:00:24 2013 +0000 @@ -6,74 +6,74 @@ const char *SIMPLE_HTML_CODE = "\ <!DOCTYPE html>\ <html>\ - <head>\ - <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\ - <title>TCP Server</title>\ - </head>\ - <body>"; +<head>\ +<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\ +<title>TCP Server</title>\ +</head>\ + <body>"; const char* INTERACTIVE_HTML_CODE_1 = "\ -<!DOCTYPE html>\ +<!DOCTYPE html> \ <html>\ - <head>\ - <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\ - <title>TCP Server</title>\ - <script type=\"text/javascript\">\ - var ip = \"%s\";\ - function submitCreateForm()\ - {\ - var list = document.getElementById(\"type\");\ - var type = list.options[list.selectedIndex].value;\ - var name = document.getElementById(\"name\").value;\ - var arg = document.getElementById(\"arg\").value;\ - var url;\ - if(arg === \"\")\ - url = \"http://\" + ip + type + \"new?name=\" + name;\ - else\ - url = \"http://\" + ip + type + \"new?arg=\" + arg + \"&name=\" + name;\ - location.href= url;\ - }\ - function submitCallFuncForm()\ - {\ - var command = document.getElementById(\"command\").value;\ - var tmp = command.split(\' \');\ - var url = tmp[0];\ - if(tmp.length > 1)\ - url += \"?\";\ - for(var i = 1; i < tmp.length; ++i)\ - {\ - url += \"arg\" + i + \"=\" + tmp[i];\ - if(i+1 < tmp.length)\ - url += \"&\";\ - }\ - location.href = url;\ - }\ - </script>\ - </head> \ +<head>\ +<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\ +<title>TCP Server</title>\ +<script type=\"text/javascript\">\ +var ip = \"%s\";\ +function submitCreateForm()\ +{\ +var list = document.getElementById(\"type\");\ +var type = list.options[list.selectedIndex].value;\ +var name = document.getElementById(\"name\").value;\ +var arg = document.getElementById(\"arg\").value;\ +var url;\ +if(arg === \"\")\ +url = \"http://\" + ip + type + \"new?name=\" + name;\ +else\ +url = \"http://\" + ip + type + \"new?arg=\" + arg + \"&name=\" + name;\ +location.href= url;\ +}\ +function submitCallFuncForm()\ +{\ +var command = document.getElementById(\"command\").value;\ +var tmp = command.split(\' \');\ +var url = tmp[0];\ +if(tmp.length > 1)\ +url += \"?\";\ +for(var i = 1; i < tmp.length; ++i)\ +{\ +url += \"arg\" + i + \"=\" + tmp[i];\ +if(i+1 < tmp.length)\ +url += \"&\";\ +}\ +location.href = url;\ +}\ +</script>\ +</head> \ <body>"; const char* INTERACTIVE_HTML_CODE_2 = "<h3>Create Object :</h3>\ - <form id=\"create\" method=\"get\">\ - Type: <select id=\"type\">\ - <option value=\"/DigitalOut/\">DigitalOut</option>\ - <option value=\"/DigitalIn/\">DigitalIn</option>\ - <option value=\"/DigitalInOut/\">DigitalInOut</option>\ - <option value=\"/PwmOut/\">PwmOut</option>\ - <option value=\"/Timer/\">Timer</option>\ - </select><br>\ - name: <input type=\"text\" id=\"name\"><br>\ - arg(optional): <input type=\"text\" id=\"arg\">\ - <p><input type=\"button\" value=\"Create\" onclick=\"javascript:submitCreateForm();\"></p>\ - </form> \ - \ - <h3>Call a function :</h3>\ - <p>Enter an RPC command.</p>\ - <form method=\"get\">\ - Command: <input type= \"text\" id=\"command\"><br>\ - <input type=\"button\" value=\"Send\" onclick=\"javascript:submitCallFuncForm();\"><br>\ - </form>\ - </body> \ +<form id=\"create\" method=\"get\">\ +Type: <select id=\"type\">\ +<option value=\"/DigitalOut/\">DigitalOut</option>\ +<option value=\"/DigitalIn/\">DigitalIn</option>\ +<option value=\"/DigitalInOut/\">DigitalInOut</option>\ +<option value=\"/PwmOut/\">PwmOut</option>\ +<option value=\"/Timer/\">Timer</option>\ +</select><br>\ +name: <input type=\"text\" id=\"name\"><br>\ +arg(optional): <input type=\"text\" id=\"arg\">\ +<p><input type=\"button\" value=\"Create\" onclick=\"javascript:submitCreateForm();\"></p>\ +</form> \ + \ +<h3>Call a function :</h3>\ +<p>Enter an RPC command.</p>\ +<form method=\"get\">\ +Command: <input type= \"text\" id=\"command\"><br>\ +<input type=\"button\" value=\"Send\" onclick=\"javascript:submitCallFuncForm();\"><br>\ +</form>\ +</body> \ </html>"; static char chunk[1024]; @@ -145,6 +145,7 @@ { if(c == 0) sprintf(chunk, INTERACTIVE_HTML_CODE_1, EthernetInterface::getIPAddress()); + else if(c == 1) { if(reply != NULL && strlen(reply) != 0)
--- a/Formatter.h Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -#ifndef FORMATTER -#define FORMATTER - - -class Formatter -{ - public : - - Formatter(int nbChunk = 1); - - char* get_page(char *reply); - - protected : - - virtual void get_chunk(const int c, char *reply); - - private : - - int currentChunk; - int nbChunk; -}; - -class SimpleHTMLFormatter : public Formatter -{ - public : - - SimpleHTMLFormatter(); - - protected : - - virtual void get_chunk(const int c, char *reply); - -}; - -class InteractiveHTMLFormatter : public Formatter -{ - public : - - InteractiveHTMLFormatter(); - - protected : - - virtual void get_chunk(const int c, char *reply); -}; - - -#endif -
--- a/HTTPServer.cpp Wed Jul 17 11:07:06 2013 +0000 +++ b/HTTPServer.cpp Wed Jul 17 15:00:24 2013 +0000 @@ -6,14 +6,7 @@ { return strcmp(a,b) < 0; } -const char *TEST = "\ -<!DOCTYPE html>\ -<html>\ - <head>\ - <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\ - <title>TCP Server</title>\ - </head>\ - <body>Hello World !</body></html>"; + HTTPServer::HTTPServer(Formatter *f): socket(), handlers(&cmp),
--- a/HTTPServer.h Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -#ifndef HTTP_SERVER -#define HTTP_SERVER - -#include <map> - -#include "mbed.h" -#include "mbed_rpc.h" -#include "RequestHandler.h" -#include "Formatter.h" -#include "EthernetInterface.h" -#include "RPCCommand.h" - - -class HTTPServer -{ - public : - - HTTPServer(Formatter *f = new Formatter()); - virtual ~HTTPServer(); - - bool init(int port); - - void run(); - - void add_request_handler(char *name, RequestHandler* handler); - - private : - - void handle_request(char *buffer); - - TCPSocketServer socket; - std::map<char*, RequestHandler*, bool(*)(char*, char*)> handlers; - Formatter *formatter; - char reply[RPC_MAX_STRING]; - RPCCommand command; -}; - -#endif -
--- a/RPCCommand.cpp Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -#include "RPCCommand.h" -#include "mbed.h" -#include "RPCType.h" - - -RPCCommand::RPCCommand(): -cmd(), -obj_name(NULL), -func_name(NULL) -{ - -} - -bool RPCCommand::decode(char *buffer) -{ - if(buffer == NULL) - return false; - if(buffer[0] != '/') - return false; - - ++buffer; - char *tmp = strchr(buffer ,'/'); - - if(tmp == NULL) - return false; - if(tmp == buffer) - return false; - - tmp[0] = '\0'; - obj_name = buffer; - - buffer = tmp+1; - - if(buffer[0] == '\0' || buffer[0] == '?') - return false; - - func_name = buffer; - - tmp = strchr(buffer, '?'); - if(tmp != NULL) - { - if(tmp[1] == '\0') - return false; - tmp[0] = '\0'; - } - - cmd[0] = '\0'; - strcat(cmd, "/"); - strcat(cmd, obj_name); - strcat(cmd, "/"); - strcat(cmd, func_name); - - if(tmp == NULL) - return true; - - buffer = tmp+1; - do - { - tmp = strchr(buffer, '&'); - - if(tmp != NULL) - { - if(tmp[1] == '\0' || buffer == tmp) - return false; - tmp[0] = '\0'; - } - - char *sep = strchr(buffer, '='); - if(sep == NULL) - return false; - if(sep == buffer) - return false; - if(sep[1] == '\0' || sep[1] == '&') - return false; - - strcat(cmd, " "); - strcat(cmd, sep+1); - - if(tmp != NULL) - buffer = tmp+1; - else - buffer = NULL; - }while(buffer); - - return true; -} - - - -char* RPCCommand::get_cmd() const -{ - return (char*)cmd; -} - -RPC_COMMAND_TYPE RPCCommand::get_type() const -{ - if(!strcmp(func_name, "new") && RPCType::instance().is_supported_type(obj_name)) - return CREATE; - - RPC* r = RPC::lookup(obj_name); - if(r == NULL) - return INVALID; - - if(!strcmp(func_name, "delete")) - return DELETE; - - const struct rpc_method *methods = r->get_rpc_methods(); - int i = 0; - while(methods[i].name != NULL) - { - if(!strcmp(func_name, methods[i].name)) - { - return FUNCTION_CALL; - } - ++i; - } - - return INVALID; -} - -char* RPCCommand::get_obj_name() const -{ - return obj_name; -} - -char* RPCCommand::get_func_name() const -{ - return func_name; -} -
--- a/RPCCommand.h Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -#ifndef RPCCOMMAND -#define RPCCOMMAND - -#include <list> -#include "mbed_rpc.h" - -enum RPC_COMMAND_TYPE { INVALID, CREATE, DELETE, FUNCTION_CALL }; - -struct rpc_arg -{ - char *name; - char *val; -}; - -class RPCCommand -{ - public : - - RPCCommand(); - - bool decode(char *buffer); - - char* get_cmd() const; - RPC_COMMAND_TYPE get_type() const; - char* get_obj_name() const; - char* get_func_name() const; - - private : - - char cmd[RPC_MAX_STRING]; - char* obj_name; - char* func_name; -}; - -#endif -
--- a/RPCObjectManager.cpp Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -#include "RPCObjectManager.h" -#include "mbed.h" - -RPCObjectManager& RPCObjectManager::instance() -{ - static RPCObjectManager om; - return om; -} - -RPCObjectManager::RPCObjectManager(): -objects() -{ -} - -RPCObjectManager::~RPCObjectManager() -{ - for(std::list<char*>::iterator itor = objects.begin(); - itor != objects.end(); - ++itor) - delete *itor; -} - -void RPCObjectManager::store_object(char *obj_name) -{ - char *obj = new char[strlen(obj_name)+1]; - strcpy(obj, obj_name); - obj[strlen(obj_name)] = '\0'; - objects.push_back(obj); -} - -void RPCObjectManager::remove_object(char *obj_name) -{ - for(std::list<char*>::iterator itor = objects.begin(); - itor != objects.end(); - ++itor) - if(!strcmp(obj_name, *itor)) - { - delete *itor; - objects.erase(itor); - break; - } -} - -bool RPCObjectManager::lookup_object(char *obj_name) -{ - for(std::list<char*>::iterator itor = objects.begin(); - itor != objects.end(); - ++itor) - if(!strcmp(obj_name, *itor)) - return true; - return false; -} - -bool RPCObjectManager::is_empty() -{ - return objects.empty(); -} - -std::list<char*>::iterator RPCObjectManager::begin() -{ - return objects.begin(); -} - -std::list<char*>::iterator RPCObjectManager::end() -{ - return objects.end(); -} -
--- a/RPCObjectManager.h Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -#ifndef RPCOBJECTMANAGER -#define RPCOBJECTMANAGER - -#include <list> - -class RPCObjectManager -{ - public : - - static RPCObjectManager& instance(); - - void store_object(char *obj_name); - void remove_object(char *obj_name); - bool lookup_object(char *obj_name); - - std::list<char*>::iterator begin(); - std::list<char*>::iterator end(); - - bool is_empty(); - - private : - - RPCObjectManager(); - ~RPCObjectManager(); - - std::list<char*> objects; -}; -#endif -
--- a/RPCType.cpp Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -#include "mbed.h" -#include "mbed_rpc.h" -#include "RPCType.h" - - -RPCType::RPCType(): -supported_types() -{ -} - -RPCType& RPCType::instance() -{ - static RPCType t; - return t; -} - -void RPCType::register_types() -{ - RPCType &t = instance(); - - RPC::add_rpc_class<RpcDigitalOut>(); - t.supported_types.push_back("DigitalOut"); - RPC::add_rpc_class<RpcDigitalIn>(); - t.supported_types.push_back("DigitalIn"); - RPC::add_rpc_class<RpcDigitalInOut>(); - t.supported_types.push_back("DigitalInOut"); - - #if DEVICE_PWMOUT - RPC::add_rpc_class<RpcPwmOut>(); - t.supported_types.push_back("PwmOut"); - #endif - #if DEVICE_SPI - t.supported_types.push_back("SPI"); - RPC::add_rpc_class<RpcSPI>(); - #endif - #if DEVICE_SERIAL - t.supported_types.push_back("Serial"); - RPC::add_rpc_class<RpcSerial>(); - #endif - RPC::add_rpc_class<RpcTimer>(); - t.supported_types.push_back("Timer"); -} - -bool RPCType::is_supported_type(char *type) -{ - for(std::list<char*>::iterator itor = instance().supported_types.begin(); - itor != instance().supported_types.end(); - ++itor) - if(!strcmp(*itor,type)) - return true; - - return false; -} - -
--- a/RPCType.h Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -#ifndef RPCTYPE_H -#define RPCTYPE_H - -#include <list> - -class RPCType -{ - public : - - static RPCType& instance(); - - void register_types(); - - bool is_supported_type(char *type); - - private : - - RPCType(); - std::list<char*> supported_types; -}; - -#endif -
--- a/RequestHandler.cpp Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -#include "RequestHandler.h" -#include "mbed_rpc.h" -#include "RPCObjectManager.h" -#include "RPCCommand.h" - -void GetRequestHandler::handle(const RPCCommand& cmd, char *reply) -{ - switch(cmd.get_type()) - { - case DELETE: - strcat(reply, "You must send a DELETE request to remove an object "); - break; - case FUNCTION_CALL: - RPC::call(cmd.get_cmd(), reply); - break; - case CREATE: - strcat(reply, "You must send a PUT request to call a function"); - break; - default: - strcat(reply, "Invalid RPC command"); - break; - } -} - -void PutRequestHandler::handle(const RPCCommand& cmd, char *reply) -{ - switch(cmd.get_type()) - { - case DELETE: - strcat(reply, "You must send a DELETE request to remove an object "); - break; - case FUNCTION_CALL: - strcat(reply, "You must send a GET request to call a function"); - break; - case CREATE: - RPC::call(cmd.get_cmd(), reply); - if(strlen(reply) > 0) - { - RPCObjectManager::instance().store_object(reply); - strcat(reply, " has been created"); - } - else - strcat(reply, "Error while creating object."); - break; - default: - strcat(reply, "Invalid RPC command"); - break; - } -} - -void DeleteRequestHandler::handle(const RPCCommand& cmd, char *reply) -{ - switch(cmd.get_type()) - { - case CREATE: - strcat(reply, "You must send a PUT request to remove an object "); - break; - case FUNCTION_CALL: - strcat(reply, "You must send a GET request to call a function"); - break; - case DELETE: - RPC::call(cmd.get_cmd(), reply); - RPCObjectManager::instance().remove_object(cmd.get_obj_name()); - strcat(reply, "Deleted object "); - strcat(reply, cmd.get_obj_name()); - break; - default: - strcat(reply, "Invalid RPC command"); - break; - } -} - -void ComplexRequestHandler::handle(const RPCCommand& cmd, char *reply) -{ - switch(cmd.get_type()) - { - case CREATE : - putHandler.handle(cmd, reply); - break; - case DELETE : - deleteHandler.handle(cmd, reply); - break; - case FUNCTION_CALL : - getHandler.handle(cmd, reply); - break; - default : - strcat(reply, "Invalid RPC command"); - break; - } -} -
--- a/RequestHandler.h Wed Jul 17 11:07:06 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -#ifndef REQUEST_HANDLER -#define REQUEST_HANDLER - -#include "RPCCommand.h" - -class RequestHandler -{ - public : - - virtual void handle(const RPCCommand& cmd, char* reply) = 0; -}; - -class GetRequestHandler : public RequestHandler -{ - public : - - virtual void handle(const RPCCommand& cmd, char* reply); -}; - -class PutRequestHandler : public RequestHandler -{ - public : - - virtual void handle(const RPCCommand& cmd, char* reply); - -}; - - -class DeleteRequestHandler : public RequestHandler -{ - public : - - virtual void handle(const RPCCommand& cmd, char* reply); - -}; - -class ComplexRequestHandler : public RequestHandler -{ - public : - - virtual void handle(const RPCCommand& cmd, char* reply); - - private : - - GetRequestHandler getHandler; - PutRequestHandler putHandler; - DeleteRequestHandler deleteHandler; -}; - -#endif -