Skip to content

Commit 2d659d2

Browse files
committed
Add example for adding and removing middleware functions of different datatypes
Signed-off-by: pvogt09 <[email protected]>
1 parent 15ef3f9 commit 2d659d2

File tree

3 files changed

+188
-1
lines changed

3 files changed

+188
-1
lines changed

.github/workflows/build-examples-master.yml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
- HTML-Forms
1515
- HTTPS-and-HTTP
1616
- Middleware
17+
- Middleware-Remove
1718
- Parameters
1819
- Parameter-Validation
1920
- Put-Post-Echo

.github/workflows/build-examples-pr.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
- HTML-Forms
1414
- HTTPS-and-HTTP
1515
- Middleware
16+
- Middleware-Remove
1617
- Parameters
1718
- Parameter-Validation
1819
- Put-Post-Echo
@@ -51,4 +52,4 @@ jobs:
5152
name: "CI%3A Build Examples"
5253
env:
5354
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54-
55+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/**
2+
* Example for the ESP32 HTTP(S) Webserver
3+
*
4+
* IMPORTANT NOTE:
5+
* To run this script, your need to
6+
* 1) Enter your WiFi SSID and PSK below this comment
7+
* 2) Make sure to have certificate data available. You will find a
8+
* shell script and instructions to do so in the library folder
9+
* under extras/
10+
*
11+
* This script will install an HTTPS Server on your ESP32 with the following
12+
* functionalities:
13+
* - Do the same as the Middleware.ino example
14+
* - Show how to add and remove additional middlewares with different datatypes
15+
*/
16+
17+
// TODO: Configure your WiFi here
18+
#define WIFI_SSID "<your ssid goes here>"
19+
#define WIFI_PSK "<your pre-shared key goes here>"
20+
21+
// Include certificate data (see note above)
22+
#include "cert.h"
23+
#include "private_key.h"
24+
25+
// We will use wifi
26+
#include <WiFi.h>
27+
28+
// For the middleware
29+
#include <functional>
30+
31+
// Includes for the server
32+
#include <HTTPSServer.hpp>
33+
#include <SSLCert.hpp>
34+
#include <HTTPRequest.hpp>
35+
#include <HTTPResponse.hpp>
36+
#include <HTTPMiddlewareFunction.hpp>
37+
38+
// The HTTPS Server comes in a separate namespace. For easier use, include it here.
39+
using namespace httpsserver;
40+
41+
// Create an SSL certificate object from the files included above
42+
SSLCert cert = SSLCert(
43+
example_crt_DER, example_crt_DER_len,
44+
example_key_DER, example_key_DER_len
45+
);
46+
47+
// Create an SSL-enabled server that uses the certificate
48+
// The contstructor takes some more parameters, but we go for default values here.
49+
HTTPSServer secureServer = HTTPSServer(&cert);
50+
51+
// Declare some handler functions for the various URLs on the server
52+
void handleRoot(HTTPRequest * req, HTTPResponse * res);
53+
void handle404(HTTPRequest * req, HTTPResponse * res);
54+
55+
// Declare a middleware function.
56+
// Parameters:
57+
// req: Request data, can be used to access URL, HTTP Method, Headers, ...
58+
// res: Response data, can be used to access HTTP Status, Headers, ...
59+
// next: This function is used to pass control down the chain. If you have done your work
60+
// with the request object, you may decide if you want to process the request.
61+
// If you do so, you call the next() function, and the next middleware function (if
62+
// there is any) or the actual requestHandler will be called.
63+
// If you want to skip the request, you do not call next, and set for example status
64+
// code 403 on the response to show that the user is not allowed to access a specific
65+
// resource.
66+
// The Authentication examples provides more details on this.
67+
void middlewareLogging(HTTPRequest * req, HTTPResponse * res, std::function<void()> next);
68+
69+
void middlewareRawPointer(HTTPRequest * req, HTTPResponse * res, std::function<void()> next);
70+
71+
void setup() {
72+
// For logging
73+
Serial.begin(115200);
74+
75+
// Connect to WiFi
76+
Serial.println("Setting up WiFi");
77+
WiFi.begin(WIFI_SSID, WIFI_PSK);
78+
while (WiFi.status() != WL_CONNECTED) {
79+
Serial.print(".");
80+
delay(500);
81+
}
82+
Serial.print("Connected. IP=");
83+
Serial.println(WiFi.localIP());
84+
85+
// For every resource available on the server, we need to create a ResourceNode
86+
// The ResourceNode links URL and HTTP method to a handler function
87+
ResourceNode * nodeRoot = new ResourceNode("/", "GET", &handleRoot);
88+
ResourceNode * node404 = new ResourceNode("", "GET", &handle404);
89+
90+
// Add the root node to the server
91+
secureServer.registerNode(nodeRoot);
92+
93+
// Add the 404 not found node to the server.
94+
// The path is ignored for the default node.
95+
secureServer.setDefaultNode(node404);
96+
97+
// Add the middleware. The function will be called globally for every request
98+
// Note: The functions are called in the order they are added to the server.
99+
// Also, if you want a middleware to handle only specific requests, you can check
100+
// the URL within the middleware function.
101+
secureServer.addMiddleware(middlewareLogging);
102+
secureServer.addMiddleware(middlewareRawPointer);
103+
// add a std::function middleware function
104+
const HTTPSMiddlewareFunction std_function{middlewareLogging};
105+
secureServer.addMiddleware(std_function);
106+
const auto outside_variable = 10;
107+
// Add a lambda middleware function
108+
const auto lamda = [outside_variable](HTTPRequest * req, HTTPResponse * res, std::function<void()> next) {
109+
Serial.print("Middleware Lambda with outside variable ");
110+
Serial.println(outside_variable);
111+
};
112+
secureServer.addMiddleware(lamda);
113+
114+
Serial.println("Removing middlewares...");
115+
// Remove the raw function pointer middleware
116+
secureServer.removeMiddleware(middlewareRawPointer);
117+
// Remove the std::function middleware
118+
secureServer.removeMiddleware(std_function);
119+
// Remove the lambda middleware
120+
secureServer.removeMiddleware(lamda);
121+
122+
Serial.println("Starting server...");
123+
secureServer.start();
124+
if (secureServer.isRunning()) {
125+
Serial.println("Server ready.");
126+
}
127+
}
128+
129+
void loop() {
130+
// This call will let the server do its work
131+
secureServer.loop();
132+
133+
// Other code would go here...
134+
delay(1);
135+
}
136+
137+
// We want to log the following information for every request:
138+
// - Response Status
139+
// - Request Method
140+
// - Request String (URL + Parameters)
141+
void middlewareLogging(HTTPRequest * req, HTTPResponse * res, std::function<void()> next) {
142+
// We want to print the response status, so we need to call next() first.
143+
next();
144+
// After the call, the status is (hopefully) set by the handler function, so we can
145+
// access it for logging.
146+
Serial.printf("middlewareLogging(): %3d\t%s\t\t%s\n",
147+
// Status code (like: 200)
148+
res->getStatusCode(),
149+
// Method used for the request (like: GET)
150+
req->getMethod().c_str(),
151+
// Request string (like /index.html)
152+
req->getRequestString().c_str());
153+
}
154+
155+
void middlewareRawPointer(HTTPRequest * req, HTTPResponse * res, std::function<void()> next) {
156+
Serial.print("Middleware Raw Pointer");
157+
next();
158+
}
159+
160+
// For details on the implementation of the hanlder functions, refer to the Static-Page example.
161+
void handleRoot(HTTPRequest * req, HTTPResponse * res) {
162+
res->setHeader("Content-Type", "text/html");
163+
res->println("<!DOCTYPE html>");
164+
res->println("<html>");
165+
res->println("<head><title>Hello World!</title></head>");
166+
res->println("<body>");
167+
res->println("<h1>Hello World!</h1>");
168+
res->print("<p>Your server is running for ");
169+
res->print((int)(millis()/1000), DEC);
170+
res->println(" seconds.</p>");
171+
res->println("</body>");
172+
res->println("</html>");
173+
}
174+
175+
void handle404(HTTPRequest * req, HTTPResponse * res) {
176+
req->discardRequestBody();
177+
res->setStatusCode(404);
178+
res->setStatusText("Not Found");
179+
res->setHeader("Content-Type", "text/html");
180+
res->println("<!DOCTYPE html>");
181+
res->println("<html>");
182+
res->println("<head><title>Not Found</title></head>");
183+
res->println("<body><h1>404 Not Found</h1><p>The requested resource was not found on this server.</p></body>");
184+
res->println("</html>");
185+
}

0 commit comments

Comments
 (0)