Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cfe8526

Browse filesBrowse files
Bmooijme-no-dev
authored andcommitted
Add Uri with support for regexUri and globUri (espressif#3441)
* Add Uri with support for staticUri, regexUri and globUri * Add newline to end of files * Update example * Suppress gcc warnings (unused params)
1 parent c09ec5b commit cfe8526
Copy full SHA for cfe8526

File tree

Expand file treeCollapse file tree

8 files changed

+182
-54
lines changed
Filter options
Expand file treeCollapse file tree

8 files changed

+182
-54
lines changed

‎libraries/WebServer/examples/PathArgServer/PathArgServer.ino

Copy file name to clipboardExpand all lines: libraries/WebServer/examples/PathArgServer/PathArgServer.ino
+5-2Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
#include <WebServer.h>
44
#include <ESPmDNS.h>
55

6+
#include <uri/UriBraces.h>
7+
#include <uri/UriRegex.h>
8+
69
const char *ssid = "........";
710
const char *password = "........";
811

@@ -33,12 +36,12 @@ void setup(void) {
3336
server.send(200, "text/plain", "hello from esp32!");
3437
});
3538

36-
server.on("/users/{}", []() {
39+
server.on(UriBraces("/users/{}"), []() {
3740
String user = server.pathArg(0);
3841
server.send(200, "text/plain", "User: '" + user + "'");
3942
});
4043

41-
server.on("/users/{}/devices/{}", []() {
44+
server.on(UriRegex("^\\/users\\/([0-9]+)\\/devices\\/([0-9]+)$"), []() {
4245
String user = server.pathArg(0);
4346
String device = server.pathArg(1);
4447
server.send(200, "text/plain", "User: '" + user + "' and Device: '" + device + "'");

‎libraries/WebServer/src/Uri.h

Copy file name to clipboard
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef URI_H
2+
#define URI_H
3+
4+
#include <Arduino.h>
5+
#include <vector>
6+
7+
class Uri {
8+
9+
protected:
10+
const String _uri;
11+
12+
public:
13+
Uri(const char *uri) : _uri(uri) {}
14+
Uri(const String &uri) : _uri(uri) {}
15+
virtual ~Uri() {}
16+
17+
virtual Uri* clone() const {
18+
return new Uri(_uri);
19+
};
20+
21+
virtual void initPathArgs(__attribute__((unused)) std::vector<String> &pathArgs) {}
22+
23+
virtual bool canHandle(const String &requestUri, __attribute__((unused)) std::vector<String> &pathArgs) {
24+
return _uri == requestUri;
25+
}
26+
};
27+
28+
#endif

‎libraries/WebServer/src/WebServer.cpp

Copy file name to clipboardExpand all lines: libraries/WebServer/src/WebServer.cpp
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,15 @@ void WebServer::requestAuthentication(HTTPAuthMethod mode, const char* realm, co
245245
send(401, String(FPSTR(mimeTable[html].mimeType)), authFailMsg);
246246
}
247247

248-
void WebServer::on(const String &uri, WebServer::THandlerFunction handler) {
248+
void WebServer::on(const Uri &uri, WebServer::THandlerFunction handler) {
249249
on(uri, HTTP_ANY, handler);
250250
}
251251

252-
void WebServer::on(const String &uri, HTTPMethod method, WebServer::THandlerFunction fn) {
252+
void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn) {
253253
on(uri, method, fn, _fileUploadHandler);
254254
}
255255

256-
void WebServer::on(const String &uri, HTTPMethod method, WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn) {
256+
void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn) {
257257
_addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method));
258258
}
259259

‎libraries/WebServer/src/WebServer.h

Copy file name to clipboardExpand all lines: libraries/WebServer/src/WebServer.h
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <memory>
2929
#include <WiFi.h>
3030
#include "HTTP_Method.h"
31+
#include "Uri.h"
3132

3233
enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END,
3334
UPLOAD_FILE_ABORTED };
@@ -84,9 +85,9 @@ class WebServer
8485
void requestAuthentication(HTTPAuthMethod mode = BASIC_AUTH, const char* realm = NULL, const String& authFailMsg = String("") );
8586

8687
typedef std::function<void(void)> THandlerFunction;
87-
void on(const String &uri, THandlerFunction handler);
88-
void on(const String &uri, HTTPMethod method, THandlerFunction fn);
89-
void on(const String &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn);
88+
void on(const Uri &uri, THandlerFunction handler);
89+
void on(const Uri &uri, HTTPMethod method, THandlerFunction fn);
90+
void on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn);
9091
void addHandler(RequestHandler* handler);
9192
void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL );
9293
void onNotFound(THandlerFunction fn); //called when handler is not assigned

‎libraries/WebServer/src/detail/RequestHandlersImpl.h

Copy file name to clipboardExpand all lines: libraries/WebServer/src/detail/RequestHandlersImpl.h
+10-46Lines changed: 10 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,30 @@
44
#include "RequestHandler.h"
55
#include "mimetable.h"
66
#include "WString.h"
7+
#include "Uri.h"
78

89
using namespace mime;
910

1011
class FunctionRequestHandler : public RequestHandler {
1112
public:
12-
FunctionRequestHandler(WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn, const String &uri, HTTPMethod method)
13+
FunctionRequestHandler(WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn, const Uri &uri, HTTPMethod method)
1314
: _fn(fn)
1415
, _ufn(ufn)
15-
, _uri(uri)
16+
, _uri(uri.clone())
1617
, _method(method)
1718
{
18-
int numParams = 0, start = 0;
19-
do {
20-
start = _uri.indexOf("{}", start);
21-
if (start > 0) {
22-
numParams++;
23-
start += 2;
24-
}
25-
} while (start > 0);
26-
pathArgs.resize(numParams);
19+
_uri->initPathArgs(pathArgs);
20+
}
21+
22+
~FunctionRequestHandler() {
23+
delete _uri;
2724
}
2825

2926
bool canHandle(HTTPMethod requestMethod, String requestUri) override {
3027
if (_method != HTTP_ANY && _method != requestMethod)
3128
return false;
3229

33-
if (_uri == requestUri)
34-
return true;
35-
36-
size_t uriLength = _uri.length();
37-
unsigned int pathArgIndex = 0;
38-
unsigned int requestUriIndex = 0;
39-
for (unsigned int i = 0; i < uriLength; i++, requestUriIndex++) {
40-
char uriChar = _uri[i];
41-
char requestUriChar = requestUri[requestUriIndex];
42-
43-
if (uriChar == requestUriChar)
44-
continue;
45-
if (uriChar != '{')
46-
return false;
47-
48-
i += 2; // index of char after '}'
49-
if (i >= uriLength) {
50-
// there is no char after '}'
51-
pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex);
52-
return pathArgs[pathArgIndex].indexOf("/") == -1; // path argument may not contain a '/'
53-
}
54-
else
55-
{
56-
char charEnd = _uri[i];
57-
int uriIndex = requestUri.indexOf(charEnd, requestUriIndex);
58-
if (uriIndex < 0)
59-
return false;
60-
pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex, uriIndex);
61-
requestUriIndex = (unsigned int) uriIndex;
62-
}
63-
pathArgIndex++;
64-
}
65-
66-
return requestUriIndex >= requestUri.length();
30+
return _uri->canHandle(requestUri, pathArgs);
6731
}
6832

6933
bool canUpload(String requestUri) override {
@@ -92,7 +56,7 @@ class FunctionRequestHandler : public RequestHandler {
9256
protected:
9357
WebServer::THandlerFunction _fn;
9458
WebServer::THandlerFunction _ufn;
95-
String _uri;
59+
Uri *_uri;
9660
HTTPMethod _method;
9761
};
9862

+66Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#ifndef URI_BRACES_H
2+
#define URI_BRACES_H
3+
4+
#include "Uri.h"
5+
6+
class UriBraces : public Uri {
7+
8+
public:
9+
explicit UriBraces(const char *uri) : Uri(uri) {};
10+
explicit UriBraces(const String &uri) : Uri(uri) {};
11+
12+
Uri* clone() const override final {
13+
return new UriBraces(_uri);
14+
};
15+
16+
void initPathArgs(std::vector<String> &pathArgs) override final {
17+
int numParams = 0, start = 0;
18+
do {
19+
start = _uri.indexOf("{}", start);
20+
if (start > 0) {
21+
numParams++;
22+
start += 2;
23+
}
24+
} while (start > 0);
25+
pathArgs.resize(numParams);
26+
}
27+
28+
bool canHandle(const String &requestUri, std::vector<String> &pathArgs) override final {
29+
if (Uri::canHandle(requestUri, pathArgs))
30+
return true;
31+
32+
size_t uriLength = _uri.length();
33+
unsigned int pathArgIndex = 0;
34+
unsigned int requestUriIndex = 0;
35+
for (unsigned int i = 0; i < uriLength; i++, requestUriIndex++) {
36+
char uriChar = _uri[i];
37+
char requestUriChar = requestUri[requestUriIndex];
38+
39+
if (uriChar == requestUriChar)
40+
continue;
41+
if (uriChar != '{')
42+
return false;
43+
44+
i += 2; // index of char after '}'
45+
if (i >= uriLength) {
46+
// there is no char after '}'
47+
pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex);
48+
return pathArgs[pathArgIndex].indexOf("/") == -1; // path argument may not contain a '/'
49+
}
50+
else
51+
{
52+
char charEnd = _uri[i];
53+
int uriIndex = requestUri.indexOf(charEnd, requestUriIndex);
54+
if (uriIndex < 0)
55+
return false;
56+
pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex, uriIndex);
57+
requestUriIndex = (unsigned int) uriIndex;
58+
}
59+
pathArgIndex++;
60+
}
61+
62+
return requestUriIndex >= requestUri.length();
63+
}
64+
};
65+
66+
#endif

‎libraries/WebServer/src/uri/UriGlob.h

Copy file name to clipboard
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef URI_GLOB_H
2+
#define URI_GLOB_H
3+
4+
#include "Uri.h"
5+
#include <fnmatch.h>
6+
7+
class UriGlob : public Uri {
8+
9+
public:
10+
explicit UriGlob(const char *uri) : Uri(uri) {};
11+
explicit UriGlob(const String &uri) : Uri(uri) {};
12+
13+
Uri* clone() const override final {
14+
return new UriGlob(_uri);
15+
};
16+
17+
bool canHandle(const String &requestUri, __attribute__((unused)) std::vector<String> &pathArgs) override final {
18+
return fnmatch(_uri.c_str(), requestUri.c_str(), 0) == 0;
19+
}
20+
};
21+
22+
#endif
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ifndef URI_REGEX_H
2+
#define URI_REGEX_H
3+
4+
#include "Uri.h"
5+
#include <regex>
6+
7+
class UriRegex : public Uri {
8+
9+
public:
10+
explicit UriRegex(const char *uri) : Uri(uri) {};
11+
explicit UriRegex(const String &uri) : Uri(uri) {};
12+
13+
Uri* clone() const override final {
14+
return new UriRegex(_uri);
15+
};
16+
17+
void initPathArgs(std::vector<String> &pathArgs) override final {
18+
std::regex rgx((_uri + "|").c_str());
19+
std::smatch matches;
20+
std::string s{""};
21+
std::regex_search(s, matches, rgx);
22+
pathArgs.resize(matches.size() - 1);
23+
}
24+
25+
bool canHandle(const String &requestUri, std::vector<String> &pathArgs) override final {
26+
if (Uri::canHandle(requestUri, pathArgs))
27+
return true;
28+
29+
unsigned int pathArgIndex = 0;
30+
std::regex rgx(_uri.c_str());
31+
std::smatch matches;
32+
std::string s(requestUri.c_str());
33+
if (std::regex_search(s, matches, rgx)) {
34+
for (size_t i = 1; i < matches.size(); ++i) { // skip first
35+
pathArgs[pathArgIndex] = String(matches[i].str().c_str());
36+
pathArgIndex++;
37+
}
38+
return true;
39+
}
40+
return false;
41+
}
42+
};
43+
44+
#endif

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.