Skip to content

Commit f905395

Browse files
committed
feat: added filters and removeable routes
1 parent 685f2c9 commit f905395

File tree

5 files changed

+287
-17
lines changed

5 files changed

+287
-17
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include <WiFi.h>
2+
#include <WiFiClient.h>
3+
#include <ESP8266WebServer.h>
4+
#include <ESP8266mDNS.h>
5+
6+
// Your STA WiFi Credentials
7+
// ( This is the AP your ESP will connect to )
8+
const char *ssid = "...";
9+
const char *password = "...";
10+
11+
// Your AP WiFi Credentials
12+
// ( This is the AP your ESP will broadcast )
13+
const char *ap_ssid = "ESP32_Demo";
14+
const char *ap_password = "";
15+
16+
WebServer server(80);
17+
18+
const int led = 13;
19+
20+
// ON_STA_FILTER - Only accept requests coming from STA interface
21+
bool ON_STA_FILTER(WebServer &server) {
22+
return WiFi.STA.hasIP() && WiFi.STA.localIP() == server.client().localIP();
23+
}
24+
25+
// ON_AP_FILTER - Only accept requests coming from AP interface
26+
bool ON_AP_FILTER(WebServer &server) {
27+
return WiFi.AP.hasIP() && WiFi.AP.localIP() == server.client().localIP();
28+
}
29+
30+
void handleNotFound() {
31+
digitalWrite(led, 1);
32+
String message = "File Not Found\n\n";
33+
message += "URI: ";
34+
message += server.uri();
35+
message += "\nMethod: ";
36+
message += (server.method() == HTTP_GET) ? "GET" : "POST";
37+
message += "\nArguments: ";
38+
message += server.args();
39+
message += "\n";
40+
for (uint8_t i = 0; i < server.args(); i++) {
41+
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
42+
}
43+
server.send(404, "text/plain", message);
44+
digitalWrite(led, 0);
45+
}
46+
47+
void setup(void) {
48+
pinMode(led, OUTPUT);
49+
digitalWrite(led, 0);
50+
Serial.begin(115200);
51+
WiFi.mode(WIFI_AP_STA);
52+
// Connect to STA
53+
WiFi.begin(ssid, password);
54+
// Start AP
55+
WiFi.softAP(ap_ssid, ap_password);
56+
Serial.println("");
57+
58+
// Wait for connection
59+
while (WiFi.status() != WL_CONNECTED) {
60+
delay(500);
61+
Serial.print(".");
62+
}
63+
Serial.println("");
64+
Serial.print("Connected to ");
65+
Serial.println(ssid);
66+
Serial.print("IP address: ");
67+
Serial.println(WiFi.localIP());
68+
69+
if (MDNS.begin("esp32")) {
70+
Serial.println("MDNS responder started");
71+
}
72+
73+
// This route will be accessible by STA clients only
74+
server.on("/", [&]() {
75+
digitalWrite(led, 1);
76+
server.send(200, "text/plain", "Hi!, This route is accessible for STA clients only");
77+
digitalWrite(led, 0);
78+
}).setFilter(ON_STA_FILTER);
79+
80+
// This route will be accessible by AP clients only
81+
server.on("/", [&]() {
82+
digitalWrite(led, 1);
83+
server.send(200, "text/plain", "Hi!, This route is accessible for AP clients only");
84+
digitalWrite(led, 0);
85+
}).setFilter(ON_AP_FILTER);
86+
87+
server.on("/inline", []() {
88+
server.send(200, "text/plain", "this works as well");
89+
});
90+
91+
server.onNotFound(handleNotFound);
92+
93+
server.begin();
94+
Serial.println("HTTP server started");
95+
}
96+
97+
void loop(void) {
98+
server.handleClient();
99+
delay(2); //allow the cpu to switch to other tasks
100+
}

libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,25 +230,73 @@ void ESP8266WebServerTemplate<ServerType>::requestAuthentication(HTTPAuthMethod
230230
}
231231

232232
template <typename ServerType>
233-
void ESP8266WebServerTemplate<ServerType>::on(const Uri &uri, ESP8266WebServerTemplate<ServerType>::THandlerFunction handler) {
234-
on(uri, HTTP_ANY, handler);
233+
RequestHandler<ServerType>& ESP8266WebServerTemplate<ServerType>::on(const Uri &uri, ESP8266WebServerTemplate<ServerType>::THandlerFunction handler) {
234+
return on(uri, HTTP_ANY, handler);
235235
}
236236

237237
template <typename ServerType>
238-
void ESP8266WebServerTemplate<ServerType>::on(const Uri &uri, HTTPMethod method, ESP8266WebServerTemplate<ServerType>::THandlerFunction fn) {
239-
on(uri, method, fn, _fileUploadHandler);
238+
RequestHandler<ServerType>& ESP8266WebServerTemplate<ServerType>::on(const Uri &uri, HTTPMethod method, ESP8266WebServerTemplate<ServerType>::THandlerFunction fn) {
239+
return on(uri, method, fn, _fileUploadHandler);
240240
}
241241

242242
template <typename ServerType>
243-
void ESP8266WebServerTemplate<ServerType>::on(const Uri &uri, HTTPMethod method, ESP8266WebServerTemplate<ServerType>::THandlerFunction fn, ESP8266WebServerTemplate<ServerType>::THandlerFunction ufn) {
244-
_addRequestHandler(new FunctionRequestHandler<ServerType>(fn, ufn, uri, method));
243+
RequestHandler<ServerType>& ESP8266WebServerTemplate<ServerType>::on(const Uri &uri, HTTPMethod method, ESP8266WebServerTemplate<ServerType>::THandlerFunction fn, ESP8266WebServerTemplate<ServerType>::THandlerFunction ufn) {
244+
RequestHandler<ServerType> *handler = new FunctionRequestHandler<ServerType>(fn, ufn, uri, method);
245+
_addRequestHandler(handler);
246+
return *handler;
247+
}
248+
249+
template <typename ServerType>
250+
bool ESP8266WebServerTemplate<ServerType>::removeRoute(const char *uri) {
251+
return removeRoute(String(uri), HTTP_ANY);
252+
}
253+
254+
template <typename ServerType>
255+
bool ESP8266WebServerTemplate<ServerType>::removeRoute(const char *uri, HTTPMethod method) {
256+
return removeRoute(String(uri), method);
257+
}
258+
259+
template <typename ServerType>
260+
bool ESP8266WebServerTemplate<ServerType>::removeRoute(const String &uri) {
261+
return removeRoute(uri, HTTP_ANY);
262+
}
263+
264+
template <typename ServerType>
265+
bool ESP8266WebServerTemplate<ServerType>::removeRoute(const String &uri, HTTPMethod method) {
266+
bool anyHandlerRemoved = false;
267+
RequestHandlerType *handler = _firstHandler;
268+
RequestHandlerType *previousHandler = nullptr;
269+
270+
while (handler) {
271+
if (handler->canHandle(method, uri)) {
272+
if (_removeRequestHandler(handler)) {
273+
anyHandlerRemoved = true;
274+
// Move to the next handler
275+
if (previousHandler) {
276+
handler = previousHandler->next();
277+
} else {
278+
handler = _firstHandler;
279+
}
280+
continue;
281+
}
282+
}
283+
previousHandler = handler;
284+
handler = handler->next();
285+
}
286+
287+
return anyHandlerRemoved;
245288
}
246289

247290
template <typename ServerType>
248291
void ESP8266WebServerTemplate<ServerType>::addHandler(RequestHandlerType* handler) {
249292
_addRequestHandler(handler);
250293
}
251294

295+
template <typename ServerType>
296+
bool ESP8266WebServerTemplate<ServerType>::removeHandler(RequestHandlerType *handler) {
297+
return _removeRequestHandler(handler);
298+
}
299+
252300
template <typename ServerType>
253301
void ESP8266WebServerTemplate<ServerType>::_addRequestHandler(RequestHandlerType* handler) {
254302
if (!_lastHandler) {
@@ -261,6 +309,33 @@ void ESP8266WebServerTemplate<ServerType>::_addRequestHandler(RequestHandlerType
261309
}
262310
}
263311

312+
template <typename ServerType>
313+
bool ESP8266WebServerTemplate<ServerType>::_removeRequestHandler(RequestHandlerType *handler) {
314+
RequestHandlerType *current = _firstHandler;
315+
RequestHandlerType *previous = nullptr;
316+
317+
while (current != nullptr) {
318+
if (current == handler) {
319+
if (previous == nullptr) {
320+
_firstHandler = current->next();
321+
} else {
322+
previous->next(current->next());
323+
}
324+
325+
if (current == _lastHandler) {
326+
_lastHandler = previous;
327+
}
328+
329+
// Delete 'matching' handler
330+
delete current;
331+
return true;
332+
}
333+
previous = current;
334+
current = current->next();
335+
}
336+
return false;
337+
}
338+
264339
template <typename ServerType>
265340
void ESP8266WebServerTemplate<ServerType>::serveStatic(const char* uri, FS& fs, const char* path, const char* cache_header) {
266341
bool is_file = false;

libraries/ESP8266WebServer/src/ESP8266WebServer.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,17 @@ class ESP8266WebServerTemplate
116116

117117
typedef std::function<void(void)> THandlerFunction;
118118
typedef std::function<String(FS &fs, const String &fName)> ETagFunction;
119-
120-
void on(const Uri &uri, THandlerFunction handler);
121-
void on(const Uri &uri, HTTPMethod method, THandlerFunction fn);
122-
void on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn);
119+
typedef std::function<bool(ESP8266WebServerTemplate<ServerType> &server)> FilterFunction;
120+
121+
RequestHandler<ServerType>& on(const Uri &uri, THandlerFunction handler);
122+
RequestHandler<ServerType>& on(const Uri &uri, HTTPMethod method, THandlerFunction fn);
123+
RequestHandler<ServerType>& on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn);
124+
bool removeRoute(const char *uri);
125+
bool removeRoute(const char *uri, HTTPMethod method);
126+
bool removeRoute(const String &uri);
127+
bool removeRoute(const String &uri, HTTPMethod method);
123128
void addHandler(RequestHandlerType* handler);
129+
bool removeHandler(RequestHandlerType* handler);
124130
void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL );
125131
void onNotFound(THandlerFunction fn); //called when handler is not assigned
126132
void onFileUpload(THandlerFunction fn); //handle file uploads
@@ -306,6 +312,7 @@ class ESP8266WebServerTemplate
306312

307313
protected:
308314
void _addRequestHandler(RequestHandlerType* handler);
315+
bool _removeRequestHandler(RequestHandlerType *handler);
309316
void _handleRequest();
310317
void _finalizeResponse();
311318
ClientFuture _parseRequest(ClientType& client);

libraries/ESP8266WebServer/src/detail/RequestHandler.h

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,60 @@ class RequestHandler {
1212
using WebServerType = ESP8266WebServerTemplate<ServerType>;
1313
public:
1414
virtual ~RequestHandler() { }
15-
virtual bool canHandle(HTTPMethod method, const String& uri) { (void) method; (void) uri; return false; }
16-
virtual bool canUpload(const String& uri) { (void) uri; return false; }
17-
virtual bool handle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) { (void) server; (void) requestMethod; (void) requestUri; return false; }
18-
virtual void upload(WebServerType& server, const String& requestUri, HTTPUpload& upload) { (void) server; (void) requestUri; (void) upload; }
1915

20-
RequestHandler<ServerType>* next() { return _next; }
21-
void next(RequestHandler<ServerType>* r) { _next = r; }
16+
/*
17+
note: old handler API for backward compatibility
18+
*/
19+
20+
virtual bool canHandle(HTTPMethod method, const String& uri) {
21+
(void) method;
22+
(void) uri;
23+
return false;
24+
}
25+
virtual bool canUpload(const String& uri) {
26+
(void) uri;
27+
return false;
28+
}
29+
30+
/*
31+
note: new handler API with support for filters etc.
32+
*/
33+
34+
virtual bool canHandle(WebServerType& server, HTTPMethod method, const String& uri) {
35+
(void) server;
36+
(void) method;
37+
(void) uri;
38+
return false;
39+
}
40+
virtual bool canUpload(WebServerType& server, const String& uri) {
41+
(void) server;
42+
(void) uri;
43+
return false;
44+
}
45+
virtual bool handle(WebServerType& server, HTTPMethod requestMethod, const String& requestUri) {
46+
(void) server;
47+
(void) requestMethod;
48+
(void) requestUri;
49+
return false;
50+
}
51+
virtual void upload(WebServerType& server, const String& requestUri, HTTPUpload& upload) {
52+
(void) server;
53+
(void) requestUri;
54+
(void) upload;
55+
}
56+
57+
RequestHandler<ServerType>* next() {
58+
return _next;
59+
}
60+
61+
void next(RequestHandler<ServerType>* r) {
62+
_next = r;
63+
}
64+
65+
virtual RequestHandler<ServerType>& setFilter(std::function<bool(ESP8266WebServerTemplate<ServerType>&)> filter) {
66+
(void)filter;
67+
return *this;
68+
}
2269

2370
private:
2471
RequestHandler<ServerType>* _next = nullptr;

0 commit comments

Comments
 (0)