Nicolas Borla / Mbed OS ROME2_Robot_Firmware
Committer:
boro
Date:
Mon Mar 16 13:12:31 2020 +0000
Revision:
0:4beb2ea291ec
a

Who changed what in which revision?

UserRevisionLine numberNew contents of line
boro 0:4beb2ea291ec 1 /*
boro 0:4beb2ea291ec 2 * HTTPServer.h
boro 0:4beb2ea291ec 3 * Copyright (c) 2017, ZHAW
boro 0:4beb2ea291ec 4 * All rights reserved.
boro 0:4beb2ea291ec 5 *
boro 0:4beb2ea291ec 6 * Created on: 02.02.2017
boro 0:4beb2ea291ec 7 * Author: Marcel Honegger
boro 0:4beb2ea291ec 8 */
boro 0:4beb2ea291ec 9
boro 0:4beb2ea291ec 10 #ifndef HTTP_SERVER_H_
boro 0:4beb2ea291ec 11 #define HTTP_SERVER_H_
boro 0:4beb2ea291ec 12
boro 0:4beb2ea291ec 13 #include <string>
boro 0:4beb2ea291ec 14 #include <vector>
boro 0:4beb2ea291ec 15 #include <mbed.h>
boro 0:4beb2ea291ec 16 #include <EthernetInterface.h>
boro 0:4beb2ea291ec 17
boro 0:4beb2ea291ec 18 using namespace std;
boro 0:4beb2ea291ec 19
boro 0:4beb2ea291ec 20 class HTTPScript;
boro 0:4beb2ea291ec 21
boro 0:4beb2ea291ec 22 /**
boro 0:4beb2ea291ec 23 * The <code>HTTPServer</code> class implements a simple webserver that is able to
boro 0:4beb2ea291ec 24 * transmit files over an ethernet connection and allows to call scripts that are
boro 0:4beb2ea291ec 25 * registered with the server.
boro 0:4beb2ea291ec 26 * <br/>
boro 0:4beb2ea291ec 27 * An http server can be created and started as follows:
boro 0:4beb2ea291ec 28 * <pre><code>
boro 0:4beb2ea291ec 29 * EthernetInterface* ethernet = new EthernetInterface(); <span style="color:#008000">// init the TCP/IP stack</span>
boro 0:4beb2ea291ec 30 * ethernet->set_network("192.168.1.2", "255.255.255.0", "192.168.1.1");
boro 0:4beb2ea291ec 31 * ethernet->connect();
boro 0:4beb2ea291ec 32 *
boro 0:4beb2ea291ec 33 * HTTPServer* httpServer = new HTTPServer(ethernet); <span style="color:#008000">// creates an http server</span>
boro 0:4beb2ea291ec 34 * ...
boro 0:4beb2ea291ec 35 * </code></pre>
boro 0:4beb2ea291ec 36 * This http server allows to execute application specific code implemented as http
boro 0:4beb2ea291ec 37 * scripts. These scripts are objects derived from the <code>HTTPScript</code> superclass.
boro 0:4beb2ea291ec 38 * <br/>
boro 0:4beb2ea291ec 39 * An example of an application specific script is given below:
boro 0:4beb2ea291ec 40 * <pre><code>
boro 0:4beb2ea291ec 41 * class MyHTTPScript : public HTTPScript {
boro 0:4beb2ea291ec 42 * public:
boro 0:4beb2ea291ec 43 * MyHTTPScript();
boro 0:4beb2ea291ec 44 * virtual ~MyHTTPScript();
boro 0:4beb2ea291ec 45 * string call(vector<string> names, vector<string> values);
boro 0:4beb2ea291ec 46 * };
boro 0:4beb2ea291ec 47 *
boro 0:4beb2ea291ec 48 * string MyHTTPScript::call(vector<string> names, vector<string> values) {
boro 0:4beb2ea291ec 49 *
boro 0:4beb2ea291ec 50 * string response;
boro 0:4beb2ea291ec 51 *
boro 0:4beb2ea291ec 52 * response += " <h2>";
boro 0:4beb2ea291ec 53 * for (uint32_t i = 0; i < min(names.size(), values.size()); i++) {
boro 0:4beb2ea291ec 54 * response += " <p>"+names[i]+"="+values[i]+"</p>";
boro 0:4beb2ea291ec 55 * }
boro 0:4beb2ea291ec 56 * response += " </h2>";
boro 0:4beb2ea291ec 57 *
boro 0:4beb2ea291ec 58 * return response;
boro 0:4beb2ea291ec 59 * }
boro 0:4beb2ea291ec 60 * </code></pre>
boro 0:4beb2ea291ec 61 * This script returns the parameters that were passed to it by the http server.
boro 0:4beb2ea291ec 62 * <br/>
boro 0:4beb2ea291ec 63 * Before this script can be used, it needs to be registered with the http server
boro 0:4beb2ea291ec 64 * with the <code>add()</code> method as follows:
boro 0:4beb2ea291ec 65 * <pre><code>
boro 0:4beb2ea291ec 66 * httpServer->add("myScript", new MyHTTPScript());
boro 0:4beb2ea291ec 67 * </code></pre>
boro 0:4beb2ea291ec 68 * When the <code>call()</code> method of the script is called by the http server,
boro 0:4beb2ea291ec 69 * it receives two string vectors: a vector with the names of the arguments passed
boro 0:4beb2ea291ec 70 * in the URL, and a vector with the corresponding values of the arguments.
boro 0:4beb2ea291ec 71 * <br/>
boro 0:4beb2ea291ec 72 * An example of an http request calling this script is as follows:
boro 0:4beb2ea291ec 73 * <pre><code>
boro 0:4beb2ea291ec 74 * http://192.168.1.1:8080/cgi-bin/myScript?x=0.5&y=-0.1&z=0.2
boro 0:4beb2ea291ec 75 * </code></pre>
boro 0:4beb2ea291ec 76 * The vectors of arguments passed to the <code>call()</code> method are then
boro 0:4beb2ea291ec 77 * {'x', 'y', 'z'} for the names and {'0.5', '-0.1', '0.2'} for the values.
boro 0:4beb2ea291ec 78 * <br/>
boro 0:4beb2ea291ec 79 * The response of the <code>call()</code> method is a <code>string</code> object
boro 0:4beb2ea291ec 80 * which is placed within an xhtml page, which in turn is returned by the http
boro 0:4beb2ea291ec 81 * server to the requesting http client.
boro 0:4beb2ea291ec 82 * @see HTTPScript
boro 0:4beb2ea291ec 83 */
boro 0:4beb2ea291ec 84 class HTTPServer {
boro 0:4beb2ea291ec 85
boro 0:4beb2ea291ec 86 public:
boro 0:4beb2ea291ec 87
boro 0:4beb2ea291ec 88 HTTPServer(EthernetInterface& ethernet);
boro 0:4beb2ea291ec 89 virtual ~HTTPServer();
boro 0:4beb2ea291ec 90 void add(string name, HTTPScript* httpScript);
boro 0:4beb2ea291ec 91
boro 0:4beb2ea291ec 92 private:
boro 0:4beb2ea291ec 93
boro 0:4beb2ea291ec 94 static const uint32_t STACK_SIZE = 4096; // stack size of thread, given in [bytes]
boro 0:4beb2ea291ec 95 static const int32_t PORT_NUMBER = 80; // port number of server to use
boro 0:4beb2ea291ec 96 static const uint32_t INPUT_BUFFER_SIZE; // size of transmit buffer, given in [bytes]
boro 0:4beb2ea291ec 97 static const int32_t SOCKET_TIMEOUT; // timeout of socket, given in [ms]
boro 0:4beb2ea291ec 98
boro 0:4beb2ea291ec 99 EthernetInterface& ethernet;
boro 0:4beb2ea291ec 100 TCPServer server;
boro 0:4beb2ea291ec 101 vector<string> httpScriptNames;
boro 0:4beb2ea291ec 102 vector<HTTPScript*> httpScripts;
boro 0:4beb2ea291ec 103 Thread thread;
boro 0:4beb2ea291ec 104
boro 0:4beb2ea291ec 105 string urlDecoder(string url);
boro 0:4beb2ea291ec 106 void run();
boro 0:4beb2ea291ec 107 };
boro 0:4beb2ea291ec 108
boro 0:4beb2ea291ec 109 #endif /* HTTP_SERVER_H_ */
boro 0:4beb2ea291ec 110