Skip to content
Merged
14 changes: 7 additions & 7 deletions libraries/WebServer/src/Parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ bool WebServer::_parseRequest(NetworkClient &client) {
//attach handler
RequestHandler *handler;
for (handler = _firstHandler; handler; handler = handler->next()) {
if (handler->canHandle(_currentMethod, _currentUri)) {
if (handler->canHandle(*this, _currentMethod, _currentUri)) {
break;
}
}
Expand Down Expand Up @@ -176,7 +176,7 @@ bool WebServer::_parseRequest(NetworkClient &client) {
}
}

if (!isForm && _currentHandler && _currentHandler->canRaw(_currentUri)) {
if (!isForm && _currentHandler && _currentHandler->canRaw(*this, _currentUri)) {
log_v("Parse raw");
_currentRaw.reset(new HTTPRaw());
_currentRaw->status = RAW_START;
Expand Down Expand Up @@ -334,7 +334,7 @@ void WebServer::_parseArguments(String data) {

void WebServer::_uploadWriteByte(uint8_t b) {
if (_currentUpload->currentSize == HTTP_UPLOAD_BUFLEN) {
if (_currentHandler && _currentHandler->canUpload(_currentUri)) {
if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) {
_currentHandler->upload(*this, _currentUri, *_currentUpload);
}
_currentUpload->totalSize += _currentUpload->currentSize;
Expand Down Expand Up @@ -449,7 +449,7 @@ bool WebServer::_parseForm(NetworkClient &client, String boundary, uint32_t len)
_currentUpload->totalSize = 0;
_currentUpload->currentSize = 0;
log_v("Start File: %s Type: %s", _currentUpload->filename.c_str(), _currentUpload->type.c_str());
if (_currentHandler && _currentHandler->canUpload(_currentUri)) {
if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) {
_currentHandler->upload(*this, _currentUri, *_currentUpload);
}
_currentUpload->status = UPLOAD_FILE_WRITE;
Expand Down Expand Up @@ -488,12 +488,12 @@ bool WebServer::_parseForm(NetworkClient &client, String boundary, uint32_t len)
}
}
// Found the boundary string, finish processing this file upload
if (_currentHandler && _currentHandler->canUpload(_currentUri)) {
if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) {
_currentHandler->upload(*this, _currentUri, *_currentUpload);
}
_currentUpload->totalSize += _currentUpload->currentSize;
_currentUpload->status = UPLOAD_FILE_END;
if (_currentHandler && _currentHandler->canUpload(_currentUri)) {
if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) {
_currentHandler->upload(*this, _currentUri, *_currentUpload);
}
log_v("End File: %s Type: %s Size: %d", _currentUpload->filename.c_str(), _currentUpload->type.c_str(), (int)_currentUpload->totalSize);
Expand Down Expand Up @@ -567,7 +567,7 @@ String WebServer::urlDecode(const String &text) {

bool WebServer::_parseFormUploadAborted() {
_currentUpload->status = UPLOAD_FILE_ABORTED;
if (_currentHandler && _currentHandler->canUpload(_currentUri)) {
if (_currentHandler && _currentHandler->canUpload(*this, _currentUri)) {
_currentHandler->upload(*this, _currentUri, *_currentUpload);
}
return false;
Expand Down
29 changes: 23 additions & 6 deletions libraries/WebServer/src/WebServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
*/

#include <Arduino.h>

#if SOC_WIFI_SUPPORTED
#include "WiFi.h"
#endif

#include <esp32-hal-log.h>
#include <libb64/cdecode.h>
#include <libb64/cencode.h>
Expand Down Expand Up @@ -306,16 +311,18 @@ void WebServer::requestAuthentication(HTTPAuthMethod mode, const char *realm, co
send(401, String(FPSTR(mimeTable[html].mimeType)), authFailMsg);
}

void WebServer::on(const Uri &uri, WebServer::THandlerFunction handler) {
on(uri, HTTP_ANY, handler);
RequestHandler& WebServer::on(const Uri &uri, WebServer::THandlerFunction handler) {
return on(uri, HTTP_ANY, handler);
}

void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn) {
on(uri, method, fn, _fileUploadHandler);
RequestHandler& WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn) {
return on(uri, method, fn, _fileUploadHandler);
}

void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn) {
_addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method));
RequestHandler& WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn) {
FunctionRequestHandler *handler = new FunctionRequestHandler(fn, ufn, uri, method);
_addRequestHandler(handler);
return *handler;
}

void WebServer::addHandler(RequestHandler *handler) {
Expand Down Expand Up @@ -796,3 +803,13 @@ String WebServer::_responseCodeToString(int code) {
default: return F("");
}
}

#if SOC_WIFI_SUPPORTED
bool ON_STA_FILTER(WebServer &server) {
return WiFi.STA.localIP() == server.client().localIP();
}

bool ON_AP_FILTER(WebServer &server) {
return WiFi.AP.localIP() == server.client().localIP();
}
#endif
15 changes: 12 additions & 3 deletions libraries/WebServer/src/WebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,10 @@ class WebServer {
void requestAuthentication(HTTPAuthMethod mode = BASIC_AUTH, const char *realm = NULL, const String &authFailMsg = String(""));

typedef std::function<void(void)> THandlerFunction;
void on(const Uri &uri, THandlerFunction fn);
void on(const Uri &uri, HTTPMethod method, THandlerFunction fn);
void on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn); //ufn handles file uploads
typedef std::function<bool(WebServer &server)> FilterFunction;
RequestHandler& on(const Uri &uri, THandlerFunction fn);
RequestHandler& on(const Uri &uri, HTTPMethod method, THandlerFunction fn);
RequestHandler& on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn); //ufn handles file uploads
void addHandler(RequestHandler *handler);
void serveStatic(const char *uri, fs::FS &fs, const char *path, const char *cache_header = NULL);
void onNotFound(THandlerFunction fn); //called when handler is not assigned
Expand Down Expand Up @@ -292,4 +293,12 @@ class WebServer {
String _srealm; // Store the Auth realm between Calls
};

/*
Request Filters
*/

bool ON_STA_FILTER(WebServer &server);

bool ON_AP_FILTER(WebServer &server);

#endif //ESP8266WEBSERVER_H
31 changes: 31 additions & 0 deletions libraries/WebServer/src/detail/RequestHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
class RequestHandler {
public:
virtual ~RequestHandler() {}

/*
note: old handler API for backward compatibility
*/

virtual bool canHandle(HTTPMethod method, String uri) {
(void)method;
(void)uri;
Expand All @@ -20,6 +25,27 @@ class RequestHandler {
(void)uri;
return false;
}

/*
note: new handler API with support for filters etc.
*/

virtual bool canHandle(WebServer &server, HTTPMethod method, String uri) {
(void)server;
(void)method;
(void)uri;
return false;
}
virtual bool canUpload(WebServer &server, String uri) {
(void)server;
(void)uri;
return false;
}
virtual bool canRaw(WebServer &server, String uri) {
(void)server;
(void)uri;
return false;
}
virtual bool handle(WebServer &server, HTTPMethod requestMethod, String requestUri) {
(void)server;
(void)requestMethod;
Expand All @@ -37,6 +63,11 @@ class RequestHandler {
(void)raw;
}

virtual RequestHandler& setFilter(std::function<bool(WebServer&)> filter) {
(void)filter;
return *this;
}

RequestHandler *next() {
return _next;
}
Expand Down
68 changes: 61 additions & 7 deletions libraries/WebServer/src/detail/RequestHandlersImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class FunctionRequestHandler : public RequestHandler {

return true;
}

bool canRaw(String requestUri) override {
if (!_ufn || _method == HTTP_GET) {
return false;
Expand All @@ -44,9 +45,32 @@ class FunctionRequestHandler : public RequestHandler {
return true;
}

bool canHandle(WebServer &server, HTTPMethod requestMethod, String requestUri) override {
if (_method != HTTP_ANY && _method != requestMethod) {
return false;
}

return _uri->canHandle(requestUri, pathArgs) && (_filter != NULL ? _filter(server) : true);
}

bool canUpload(WebServer &server, String requestUri) override {
if (!_ufn || !canHandle(server, HTTP_POST, requestUri)) {
return false;
}

return true;
}

bool canRaw(WebServer &server, String requestUri) override {
if (!_ufn || _method == HTTP_GET || (_filter != NULL ? _filter(server) == false : false)) {
return false;
}

return true;
}

bool handle(WebServer &server, HTTPMethod requestMethod, String requestUri) override {
(void)server;
if (!canHandle(requestMethod, requestUri)) {
if (!canHandle(server, requestMethod, requestUri)) {
return false;
}

Expand All @@ -55,24 +79,30 @@ class FunctionRequestHandler : public RequestHandler {
}

void upload(WebServer &server, String requestUri, HTTPUpload &upload) override {
(void)server;
(void)upload;
if (canUpload(requestUri)) {
if (canUpload(server, requestUri)) {
_ufn();
}
}

void raw(WebServer &server, String requestUri, HTTPRaw &raw) override {
(void)server;
(void)raw;
if (canRaw(requestUri)) {
if (canRaw(server, requestUri)) {
_ufn();
}
}

FunctionRequestHandler& setFilter(WebServer::FilterFunction filter) {
_filter = filter;
return *this;
}

protected:
WebServer::THandlerFunction _fn;
WebServer::THandlerFunction _ufn;
// _filter should return 'true' when the request should be handled
// and 'false' when the request should be ignored
WebServer::FilterFunction _filter;
Uri *_uri;
HTTPMethod _method;
};
Expand Down Expand Up @@ -100,8 +130,24 @@ class StaticRequestHandler : public RequestHandler {
return true;
}

bool canHandle(WebServer &server, HTTPMethod requestMethod, String requestUri) override {
if (requestMethod != HTTP_GET) {
return false;
}

if ((_isFile && requestUri != _uri) || !requestUri.startsWith(_uri)) {
return false;
}

if (_filter != NULL ? _filter(server) == false : false) {
return false;
}

return true;
}

bool handle(WebServer &server, HTTPMethod requestMethod, String requestUri) override {
if (!canHandle(requestMethod, requestUri)) {
if (!canHandle(server, requestMethod, requestUri)) {
return false;
}

Expand Down Expand Up @@ -197,7 +243,15 @@ class StaticRequestHandler : public RequestHandler {
return (result);
} // calcETag

StaticRequestHandler& setFilter(WebServer::FilterFunction filter) {
_filter = filter;
return *this;
}

protected:
// _filter should return 'true' when the request should be handled
// and 'false' when the request should be ignored
WebServer::FilterFunction _filter;
FS _fs;
String _uri;
String _path;
Expand Down