forked from fhessel/esp32_https_server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParameters.ino
289 lines (245 loc) · 11.5 KB
/
Parameters.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/**
* Example for the ESP32 HTTP(S) Webserver
*
* IMPORTANT NOTE:
* To run this script, your need to
* 1) Enter your WiFi SSID and PSK below this comment
* 2) Make sure to have certificate data available. You will find a
* shell script and instructions to do so in the library folder
* under extras/
*
* This script will install an HTTPS Server on your ESP32 with the following
* functionalities:
* - Show page on web server root that will display some SVG smileys.
* Using a simple HTML form and GET parameters, you can change the colors
* of those images.
* - Provide the svg image with an optional GET parameter that allows to
* modify the background color, URL: /images/awesome.svg
* - Provide an example that shows how wildcard URL parameters get parsed
* URL: /urlparam/some/thing
* - 404 for everything else
*/
// TODO: Configure your WiFi here
#define WIFI_SSID "<your ssid goes here>"
#define WIFI_PSK "<your pre-shared key goes here>"
// Include certificate data (see note above)
#include "cert.h"
#include "private_key.h"
// We will use wifi
#include <WiFi.h>
// Includes for the server
#include <HTTPSServer.hpp>
#include <SSLCert.hpp>
#include <HTTPRequest.hpp>
#include <HTTPResponse.hpp>
// The HTTPS Server comes in a separate namespace. For easier use, include it here.
using namespace httpsserver;
// Create an SSL certificate object from the files included above
SSLCert cert = SSLCert(
example_crt_DER, example_crt_DER_len,
example_key_DER, example_key_DER_len
);
// Create an SSL-enabled server that uses the certificate
// The contstructor takes some more parameters, but we go for default values here.
HTTPSServer secureServer = HTTPSServer(&cert);
// We declare some handler functions (definition at the end of the file)
void handleRoot(HTTPRequest * req, HTTPResponse * res);
void handleSVG(HTTPRequest * req, HTTPResponse * res);
void handleURLParam(HTTPRequest * req, HTTPResponse * res);
void handle404(HTTPRequest * req, HTTPResponse * res);
void setup() {
// For logging
Serial.begin(115200);
// Connect to WiFi
Serial.println("Setting up WiFi");
WiFi.begin(WIFI_SSID, WIFI_PSK);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.print("Connected. IP=");
Serial.println(WiFi.localIP());
// For every resource available on the server, we need to create a ResourceNode
// The ResourceNode links URL and HTTP method to a handler function
ResourceNode * nodeRoot = new ResourceNode("/", "GET", &handleRoot);
ResourceNode * nodeSVG = new ResourceNode("/images/awesome.svg", "GET", &handleSVG);
ResourceNode * node404 = new ResourceNode("", "GET", &handle404);
// URL params
// If you want (for example) to return a specific instance of an object type by its ID
// you can use URLs like /led/1, led/2, ... - And you do not need to register one Resource
// Node per ID, but you can use wildcards in the URL definition. The following function
// has to wildcards, and will match for example to /urlparam/foo/bar, where "foo" and "bar"
// are accessible parameters in the handler function.
// Note: The wildcards can only be used between slashes at the moment (so /urlparam* would
// not work).
ResourceNode * nodeURLParam = new ResourceNode("/urlparam/*/*", "GET", &handleURLParam);
// Add the root node to the server
secureServer.registerNode(nodeRoot);
// Add the SVG image
secureServer.registerNode(nodeSVG);
// Add the URL param node
// Note: The order of nodes may become important here. If you have one node for "/led" (e.g. list of LEDs)
// and one node for /led/* (LED details), you should register the non-parameterized version first. The server
// follows a first-match policy. If you would register the details node first, a call to /led/ will be targetted
// at the details handler function with an empty parameter, which is probably not what you want.
secureServer.registerNode(nodeURLParam);
// Add the 404 not found node to the server.
// The path is ignored for the default node.
secureServer.setDefaultNode(node404);
Serial.println("Starting server...");
secureServer.start();
if (secureServer.isRunning()) {
Serial.println("Server ready.");
}
}
void loop() {
// This call will let the server do its work
secureServer.loop();
// Other code would go here...
delay(1);
}
void handleRoot(HTTPRequest * req, HTTPResponse * res) {
// We will deliver an HTML page
res->setHeader("Content-Type", "text/html");
// Write the response page
res->println("<!DOCTYPE html>");
res->println("<html>");
res->println("<head><title>Hello World!</title></head>");
res->println("<body>");
res->println("<h1>GET parameters</h1>");
// Show a form to select a color to colorize the faces
// We pass the selection as get parameter "shades" to this very same page,
// so we can evaluate it below
res->println("<form method=\"GET\" action=\"/\">Show me faces in shades of ");
res->println("<select name=\"shades\">");
res->println("<option value=\"red\">red</option>");
res->println("<option value=\"green\">green</option>");
res->println("<option value=\"blue\">blue</option>");
res->println("<option value=\"yellow\">yellow</option>");
res->println("<option value=\"cyan\">cyan</option>");
res->println("<option value=\"magenta\">magenta</option>");
res->println("<option value=\"rainbow\">rainbow</option>");
res->println("</select>");
res->println("<button type=\"submit\">Go!</button>");
res->println("</form>");
// Get the params to check if the user did select something
ResourceParameters * params = req->getParams();
std::string paramName = "shades";
// Print 6 faces
for(int i = 0; i < 6; i++) {
// Include the image of the handleSVG function with a specific color code
res->print("<img style=\"height:100px;width:100px\" src=\"images/awesome.svg?color=");
// Depending on the selection we show the images in a specific color shade
// Default is dark gray.
int r = 63, g = 63, b = 63;
if (params->isRequestParameterSet(paramName)) {
std::string paramVal = params->getRequestParameter(paramName);
if (paramVal == "red" || paramVal == "magenta" || paramVal == "yellow" || paramVal == "rainbow") {
r = 128 + random(0, 128);
}
if (paramVal == "green" || paramVal == "cyan" || paramVal == "yellow" || paramVal == "rainbow") {
g = 128 + random(0, 128);
}
if (paramVal == "blue" || paramVal == "magenta" || paramVal == "cyan" || paramVal == "rainbow") {
b = 128 + random(0, 128);
}
}
// Print the random color. As the HTTPResponse extends the Print interface, we can make use of that.
res->print(r, HEX);
res->print(g, HEX);
res->print(b, HEX);
res->print("\" alt=\"Awesome!\" />");
}
// Link to the URL parameter demo
res->println("<h1>URL parameters</h1>");
res->println("<p>You'll find the demo <a href=\"/urlparam/foo/bar\">here</a>.</p>");
res->println("</body>");
res->println("</html>");
}
// This callback responds with an SVG image to a GET request. The icon is the awesome face.
// (borrowed from https://commons.wikimedia.org/wiki/File:718smiley.svg)
//
// If the color request parameter is set (so the URL is like awesome.svg?color=fede58), the
// background of our awesome face is changed.
void handleSVG(HTTPRequest * req, HTTPResponse * res) {
// Get access to the parameters
ResourceParameters * params = req->getParams();
// Set SVG content type
res->setHeader("Content-Type", "image/svg+xml");
// Set a default color
std::string fillColor = "fede58";
// Get request parameter (like awesome.svg?color=ff0000) and validate it
std::string colorParamName = "color";
// Check that the parameter is set
if (params->isRequestParameterSet(colorParamName)) {
// Get the value of the parameter
std::string requestColor = params->getRequestParameter(colorParamName);
// Check for correct length
if (requestColor.length()==6) {
bool colorOk = true;
// Check that we only have characters within [0-9a-fA-F]
for(int i = 1; i < 6 && colorOk; i++) {
if (!(
(requestColor[i]>='0' && requestColor[i]<='9' ) ||
(requestColor[i]>='a' && requestColor[i]<='f' ) ||
(requestColor[i]>='A' && requestColor[i]<='F' )
)) {
colorOk = false;
}
}
// If validation was successful, replace the default color
if (colorOk) {
fillColor = requestColor;
}
}
}
// Print the SVG to the response:
res->print("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
res->print("<svg id=\"svg1923\" width=\"733\" xmlns=\"http://www.w3.org/2000/svg\" height=\"733\">");
res->print("<circle cy=\"366.5\" cx=\"366.5\" r=\"366.5\"/>");
res->print("<circle cy=\"366.5\" cx=\"366.5\" r=\"336.5\" fill=\"#");
// We insert the color from the parameter here
res->printStd(fillColor);
res->print("\"/>");
res->print("<path d=\"m325 665c-121-21-194-115-212-233v-8l-25-1-1-18h481c6 13 10 27 13 41 13 94-38 146-114 193-45 23-93 29-142 26z\"/>");
res->print("<path d=\"m372 647c52-6 98-28 138-62 28-25 46-56 51-87 4-20 1-57-5-70l-423-1c-2 56 39 118 74 157 31 34 72 54 116 63 11 2 38 2 49 0z\" fill=\"#871945\"/>");
res->print("<path d=\"m76 342c-13-26-13-57-9-85 6-27 18-52 35-68 21-20 50-23 77-18 15 4 28 12 39 23 18 17 30 40 36 67 4 20 4 41 0 60l-6 21z\"/>");
res->print("<path d=\"m234 323c5-6 6-40 2-58-3-16-4-16-10-10-14 14-38 14-52 0-15-18-12-41 6-55 3-3 5-5 5-6-1-4-22-8-34-7-42 4-57.6 40-66.2 77-3 17-1 53 4 59h145.2z\" fill=\"#fff\"/>");
res->print("<path d=\"m378 343c-2-3-6-20-7-29-5-28-1-57 11-83 15-30 41-52 72-60 29-7 57 0 82 15 26 17 45 49 50 82 2 12 2 33 0 45-1 10-5 26-8 30z\"/>");
res->print("<path d=\"m565 324c4-5 5-34 4-50-2-14-6-24-8-24-1 0-3 2-6 5-17 17-47 13-58-9-7-16-4-31 8-43 4-4 7-8 7-9 0 0-4-2-8-3-51-17-105 20-115 80-3 15 0 43 3 53z\" fill=\"#fff\"/>");
res->print("<path d=\"m504 590s-46 40-105 53c-66 15-114-7-114-7s14-76 93-95c76-18 126 49 126 49z\" fill=\"#f9bedd\"/>");
res->print("</svg>");
}
// This is a simple handler function that will show the content of URL parameters.
// If you call for example /urlparam/foo/bar, you will get the parameter values
// "foo" and "bar" provided by the ResourceParameters.
void handleURLParam(HTTPRequest * req, HTTPResponse * res) {
// Get access to the parameters
ResourceParameters * params = req->getParams();
// Set a simple content type
res->setHeader("Content-Type", "text/plain");
// The url pattern is: /urlparam/*/*
// This will make the content for the first parameter available on index 0,
// and the second wildcard as index 1.
// Print the first parameter value
res->print("Parameter 1: ");
res->printStd(params->getUrlParameter(0));
// Print the second parameter value
res->print("\nParameter 2: ");
res->printStd(params->getUrlParameter(1));
res->println("\n\nChange the parameters in the URL to see how they get parsed!");
// Note: If you have objects that are identified by an ID, you may also use
// ResourceParameters::getUrlParameterInt(int) for convenience
}
// For details to this function, see the Static-Page example
void handle404(HTTPRequest * req, HTTPResponse * res) {
req->discardRequestBody();
res->setStatusCode(404);
res->setStatusText("Not Found");
res->setHeader("Content-Type", "text/html");
res->println("<!DOCTYPE html>");
res->println("<html>");
res->println("<head><title>Not Found</title></head>");
res->println("<body><h1>404 Not Found</h1><p>The requested resource was not found on this server.</p></body>");
res->println("</html>");
}