Skip to content

Commit 4c8a29a

Browse files
committed
Expose request handlers in ESP8266WebServer
as discussed in #837
1 parent 0c703b3 commit 4c8a29a

File tree

5 files changed

+113
-106
lines changed

5 files changed

+113
-106
lines changed

libraries/ESP8266WebServer/keywords.txt

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ HTTPMethod KEYWORD1
1616
begin KEYWORD2
1717
handleClient KEYWORD2
1818
on KEYWORD2
19+
addHandler KEYWORD2
1920
uri KEYWORD2
2021
method KEYWORD2
2122
client KEYWORD2

libraries/ESP8266WebServer/src/ESP8266WebServer.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "WiFiClient.h"
2727
#include "ESP8266WebServer.h"
2828
#include "FS.h"
29-
#include "detail/RequestHandler.h"
29+
#include "detail/RequestHandlersImpl.h"
3030
// #define DEBUG
3131
#define DEBUG_OUTPUT Serial
3232

@@ -45,7 +45,7 @@ ESP8266WebServer::~ESP8266WebServer() {
4545
return;
4646
RequestHandler* handler = _firstHandler;
4747
while (handler) {
48-
RequestHandler* next = handler->next;
48+
RequestHandler* next = handler->next();
4949
delete handler;
5050
handler = next;
5151
}
@@ -63,13 +63,17 @@ void ESP8266WebServer::on(const char* uri, HTTPMethod method, ESP8266WebServer::
6363
_addRequestHandler(new FunctionRequestHandler(fn, uri, method));
6464
}
6565

66+
void ESP8266WebServer::addHandler(RequestHandler* handler) {
67+
_addRequestHandler(handler);
68+
}
69+
6670
void ESP8266WebServer::_addRequestHandler(RequestHandler* handler) {
6771
if (!_lastHandler) {
6872
_firstHandler = handler;
6973
_lastHandler = handler;
7074
}
7175
else {
72-
_lastHandler->next = handler;
76+
_lastHandler->next(handler);
7377
_lastHandler = handler;
7478
}
7579
}
@@ -293,7 +297,7 @@ void ESP8266WebServer::onNotFound(THandlerFunction fn) {
293297

294298
void ESP8266WebServer::_handleRequest() {
295299
RequestHandler* handler;
296-
for (handler = _firstHandler; handler; handler = handler->next) {
300+
for (handler = _firstHandler; handler; handler = handler->next()) {
297301
if (handler->handle(*this, _currentMethod, _currentUri))
298302
break;
299303
}

libraries/ESP8266WebServer/src/ESP8266WebServer.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END,
3838
#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
3939
#define CONTENT_LENGTH_NOT_SET ((size_t) -2)
4040

41-
class RequestHandler;
41+
class ESP8266WebServer;
42+
43+
#include "detail/RequestHandler.h"
4244

4345
namespace fs {
4446
class FS;
@@ -66,6 +68,7 @@ class ESP8266WebServer
6668
typedef std::function<void(void)> THandlerFunction;
6769
void on(const char* uri, THandlerFunction handler);
6870
void on(const char* uri, HTTPMethod method, THandlerFunction fn);
71+
void addHandler(RequestHandler* handler);
6972
void serveStatic(const char* uri, fs::FS& fs, const char* path);
7073
void onNotFound(THandlerFunction fn); //called when handler is not assigned
7174
void onFileUpload(THandlerFunction fn); //handle file uploads

libraries/ESP8266WebServer/src/detail/RequestHandler.h

+5-101
Original file line numberDiff line numberDiff line change
@@ -3,109 +3,13 @@
33

44
class RequestHandler {
55
public:
6-
RequestHandler(const char* uri, HTTPMethod method)
7-
: _uri(uri)
8-
, _method(method)
9-
, next(NULL)
10-
{
11-
}
6+
virtual bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) { return false; }
127

13-
virtual bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) = 0;
8+
RequestHandler* next() { return _next; }
9+
void next(RequestHandler* r) { _next = r; }
1410

15-
RequestHandler* next;
16-
17-
protected:
18-
String _uri;
19-
HTTPMethod _method;
20-
};
21-
22-
23-
class FunctionRequestHandler : public RequestHandler {
24-
typedef RequestHandler base;
25-
26-
public:
27-
FunctionRequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
28-
: _fn(fn)
29-
, base(uri, method)
30-
{
31-
}
32-
33-
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
34-
if (_method != HTTP_ANY && _method != requestMethod)
35-
return false;
36-
37-
if (requestUri != _uri)
38-
return false;
39-
40-
_fn();
41-
return true;
42-
}
43-
44-
protected:
45-
ESP8266WebServer::THandlerFunction _fn;
46-
};
47-
48-
class StaticRequestHandler : public RequestHandler {
49-
typedef RequestHandler base;
50-
51-
public:
52-
StaticRequestHandler(FS& fs, const char* path, const char* uri)
53-
: _fs(fs)
54-
, base(uri, HTTP_GET)
55-
, _path(path)
56-
{
57-
_isFile = fs.exists(path);
58-
DEBUGV("StaticRequestHandler: path=%s uri=%s isFile=%d\r\n", path, uri, _isFile);
59-
_baseUriLength = _uri.length();
60-
}
61-
62-
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
63-
if (requestMethod != _method)
64-
return false;
65-
DEBUGV("StaticRequestHandler::handle: request=%s _uri=%s\r\n", requestUri.c_str(), _uri.c_str());
66-
if (!requestUri.startsWith(_uri))
67-
return false;
68-
69-
String path(_path);
70-
if (!_isFile) {
71-
// Base URI doesn't point to a file. Append whatever follows this
72-
// URI in request to get the file path.
73-
path += requestUri.substring(_baseUriLength);
74-
}
75-
else if (requestUri != _uri) {
76-
// Base URI points to a file but request doesn't match this URI exactly
77-
return false;
78-
}
79-
DEBUGV("StaticRequestHandler::handle: path=%s, isFile=%d\r\n", path.c_str(), _isFile);
80-
File f = _fs.open(path, "r");
81-
if (!f)
82-
return false;
83-
84-
server.streamFile(f, getContentType(path));
85-
return true;
86-
}
87-
88-
static String getContentType(const String& path) {
89-
if (path.endsWith(".html")) return "text/html";
90-
else if (path.endsWith(".htm")) return "text/html";
91-
else if (path.endsWith(".css")) return "text/css";
92-
else if (path.endsWith(".txt")) return "text/plain";
93-
else if (path.endsWith(".js")) return "application/javascript";
94-
else if (path.endsWith(".png")) return "image/png";
95-
else if (path.endsWith(".gif")) return "image/gif";
96-
else if (path.endsWith(".jpg")) return "image/jpeg";
97-
else if (path.endsWith(".ico")) return "image/x-icon";
98-
else if (path.endsWith(".xml")) return "text/xml";
99-
else if (path.endsWith(".pdf")) return "application/pdf";
100-
else if (path.endsWith(".zip")) return "application/zip";
101-
return "text/plain";
102-
}
103-
104-
protected:
105-
FS _fs;
106-
String _path;
107-
bool _isFile;
108-
size_t _baseUriLength;
11+
private:
12+
RequestHandler* _next = nullptr;
10913
};
11014

11115
#endif //REQUESTHANDLER_H
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#ifndef REQUESTHANDLERSIMPL_H
2+
#define REQUESTHANDLERSIMPL_H
3+
4+
#include "RequestHandler.h"
5+
6+
class FunctionRequestHandler : public RequestHandler {
7+
public:
8+
FunctionRequestHandler(ESP8266WebServer::THandlerFunction fn, const char* uri, HTTPMethod method)
9+
: _fn(fn)
10+
, _uri(uri)
11+
, _method(method)
12+
{
13+
}
14+
15+
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
16+
if (_method != HTTP_ANY && _method != requestMethod)
17+
return false;
18+
19+
if (requestUri != _uri)
20+
return false;
21+
22+
_fn();
23+
return true;
24+
}
25+
26+
protected:
27+
String _uri;
28+
HTTPMethod _method;
29+
ESP8266WebServer::THandlerFunction _fn;
30+
};
31+
32+
class StaticRequestHandler : public RequestHandler {
33+
public:
34+
StaticRequestHandler(FS& fs, const char* path, const char* uri)
35+
: _fs(fs)
36+
, _uri(uri)
37+
, _path(path)
38+
{
39+
_isFile = fs.exists(path);
40+
DEBUGV("StaticRequestHandler: path=%s uri=%s isFile=%d\r\n", path, uri, _isFile);
41+
_baseUriLength = _uri.length();
42+
}
43+
44+
bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
45+
if (requestMethod != HTTP_GET)
46+
return false;
47+
DEBUGV("StaticRequestHandler::handle: request=%s _uri=%s\r\n", requestUri.c_str(), _uri.c_str());
48+
if (!requestUri.startsWith(_uri))
49+
return false;
50+
51+
String path(_path);
52+
if (!_isFile) {
53+
// Base URI doesn't point to a file. Append whatever follows this
54+
// URI in request to get the file path.
55+
path += requestUri.substring(_baseUriLength);
56+
}
57+
else if (requestUri != _uri) {
58+
// Base URI points to a file but request doesn't match this URI exactly
59+
return false;
60+
}
61+
DEBUGV("StaticRequestHandler::handle: path=%s, isFile=%d\r\n", path.c_str(), _isFile);
62+
File f = _fs.open(path, "r");
63+
if (!f)
64+
return false;
65+
66+
server.streamFile(f, getContentType(path));
67+
return true;
68+
}
69+
70+
static String getContentType(const String& path) {
71+
if (path.endsWith(".html")) return "text/html";
72+
else if (path.endsWith(".htm")) return "text/html";
73+
else if (path.endsWith(".css")) return "text/css";
74+
else if (path.endsWith(".txt")) return "text/plain";
75+
else if (path.endsWith(".js")) return "application/javascript";
76+
else if (path.endsWith(".png")) return "image/png";
77+
else if (path.endsWith(".gif")) return "image/gif";
78+
else if (path.endsWith(".jpg")) return "image/jpeg";
79+
else if (path.endsWith(".ico")) return "image/x-icon";
80+
else if (path.endsWith(".xml")) return "text/xml";
81+
else if (path.endsWith(".pdf")) return "application/pdf";
82+
else if (path.endsWith(".zip")) return "application/zip";
83+
return "text/plain";
84+
}
85+
86+
protected:
87+
FS _fs;
88+
String _uri;
89+
String _path;
90+
bool _isFile;
91+
size_t _baseUriLength;
92+
};
93+
94+
95+
#endif //REQUESTHANDLERSIMPL_H

0 commit comments

Comments
 (0)