Skip to content

Commit 3902aa4

Browse files
Bmooijme-no-dev
authored andcommitted
Adding path arguments to WebServer (espressif#1994)
1 parent f9d1b24 commit 3902aa4

File tree

5 files changed

+113
-3
lines changed

5 files changed

+113
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <WiFi.h>
2+
#include <WiFiClient.h>
3+
#include <WebServer.h>
4+
#include <ESPmDNS.h>
5+
6+
const char *ssid = "........";
7+
const char *password = "........";
8+
9+
WebServer server(80);
10+
11+
void setup(void) {
12+
Serial.begin(9600);
13+
WiFi.mode(WIFI_STA);
14+
WiFi.begin(ssid, password);
15+
Serial.println("");
16+
17+
// Wait for connection
18+
while (WiFi.status() != WL_CONNECTED) {
19+
delay(500);
20+
Serial.print(".");
21+
}
22+
Serial.println("");
23+
Serial.print("Connected to ");
24+
Serial.println(ssid);
25+
Serial.print("IP address: ");
26+
Serial.println(WiFi.localIP());
27+
28+
if (MDNS.begin("esp32")) {
29+
Serial.println("MDNS responder started");
30+
}
31+
32+
server.on("/", []() {
33+
server.send(200, "text/plain", "hello from esp32!");
34+
});
35+
36+
server.on("/users/{}", []() {
37+
String user = server.pathArg(0);
38+
server.send(200, "text/plain", "User: '" + user + "'");
39+
});
40+
41+
server.on("/users/{}/devices/{}", []() {
42+
String user = server.pathArg(0);
43+
String device = server.pathArg(1);
44+
server.send(200, "text/plain", "User: '" + user + "' and Device: '" + device + "'");
45+
});
46+
47+
server.begin();
48+
Serial.println("HTTP server started");
49+
}
50+
51+
void loop(void) {
52+
server.handleClient();
53+
}

libraries/WebServer/src/WebServer.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,11 @@ void WebServer::_streamFileCore(const size_t fileSize, const String & fileName,
509509
send(200, contentType, "");
510510
}
511511

512+
String WebServer::pathArg(unsigned int i) {
513+
if (_currentHandler != nullptr)
514+
return _currentHandler->pathArg(i);
515+
return "";
516+
}
512517

513518
String WebServer::arg(String name) {
514519
for (int j = 0; j < _postArgsLen; ++j) {

libraries/WebServer/src/WebServer.h

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ class WebServer
9797
virtual WiFiClient client() { return _currentClient; }
9898
HTTPUpload& upload() { return *_currentUpload; }
9999

100+
String pathArg(unsigned int i); // get request path argument by number
100101
String arg(String name); // get request argument value by name
101102
String arg(int i); // get request argument value by number
102103
String argName(int i); // get request argument name by number

libraries/WebServer/src/detail/RequestHandler.h

+12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#ifndef REQUESTHANDLER_H
22
#define REQUESTHANDLER_H
33

4+
#include <vector>
5+
#include <assert.h>
6+
47
class RequestHandler {
58
public:
69
virtual ~RequestHandler() { }
@@ -14,6 +17,15 @@ class RequestHandler {
1417

1518
private:
1619
RequestHandler* _next = nullptr;
20+
21+
protected:
22+
std::vector<String> pathArgs;
23+
24+
public:
25+
const String& pathArg(unsigned int i) {
26+
assert(i < pathArgs.size());
27+
return pathArgs[i];
28+
}
1729
};
1830

1931
#endif //REQUESTHANDLER_H

libraries/WebServer/src/detail/RequestHandlersImpl.h

+42-3
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,55 @@ class FunctionRequestHandler : public RequestHandler {
1515
, _uri(uri)
1616
, _method(method)
1717
{
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);
1827
}
1928

2029
bool canHandle(HTTPMethod requestMethod, String requestUri) override {
2130
if (_method != HTTP_ANY && _method != requestMethod)
2231
return false;
2332

24-
if (requestUri != _uri)
25-
return false;
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+
}
2665

27-
return true;
66+
return requestUriIndex >= requestUri.length();
2867
}
2968

3069
bool canUpload(String requestUri) override {

0 commit comments

Comments
 (0)