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