Skip to content

Commit f3d4fa7

Browse files
committed
Add HTTP request methods defined by WebDAV RFC 4918
1 parent bf0869b commit f3d4fa7

File tree

5 files changed

+128
-9
lines changed

5 files changed

+128
-9
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// SPDX-License-Identifier: LGPL-3.0-or-later
2+
// Copyright 2016-2026 Hristo Gochkov, Mathieu Carbou, Emil Muratov, Mitch Bradley
3+
4+
//
5+
// - Test for additional WebDAV request methods
6+
//
7+
8+
#include <Arduino.h>
9+
#if defined(ESP32) || defined(LIBRETINY)
10+
#include <AsyncTCP.h>
11+
#include <WiFi.h>
12+
#elif defined(ESP8266)
13+
#include <ESP8266WiFi.h>
14+
#include <ESPAsyncTCP.h>
15+
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
16+
#include <RPAsyncTCP.h>
17+
#include <WiFi.h>
18+
#endif
19+
20+
#include <ESPAsyncWebServer.h>
21+
22+
using namespace asyncsrv;
23+
24+
// Tests:
25+
//
26+
// Send requests with various methods
27+
// curl -s -X PROPFIND http://192.168.4.1/
28+
// curl -s -X LOCK http://192.168.4.1/
29+
// curl -s -X UNLOCK http://192.168.4.1/
30+
// curl -s -X PROPPATCH http://192.168.4.1/
31+
// curl -s -X MKCOL http://192.168.4.1/
32+
// curl -s -X MOVE http://192.168.4.1/
33+
// curl -s -X COPY http://192.168.4.1/
34+
//
35+
// In all cases, the request will be accepted with text/plain response 200 like
36+
// "Got method PROPFIND on URL /"
37+
38+
static AsyncWebServer server(80);
39+
40+
void setup() {
41+
Serial.begin(115200);
42+
43+
#if ASYNCWEBSERVER_WIFI_SUPPORTED
44+
WiFi.mode(WIFI_AP);
45+
WiFi.softAP("esp-captive");
46+
#endif
47+
48+
server.onNotFound([](AsyncWebServerRequest *request) {
49+
String resp("Got method ");
50+
resp += request->methodToString();
51+
resp += " on URL ";
52+
resp += request->url();
53+
resp += "\r\n";
54+
55+
Serial.print(resp);
56+
57+
request->send(200, "text/plain", resp.c_str());
58+
});
59+
60+
server.begin();
61+
}
62+
63+
void loop() {
64+
delay(100);
65+
}

platformio.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ src_dir = examples/PerfTests
3939
; src_dir = examples/URIMatcherTest
4040
; src_dir = examples/WebSocket
4141
; src_dir = examples/WebSocketEasy
42+
; src_dir = examples/WebDAVMethods
4243

4344
[env]
4445
framework = arduino

src/ESPAsyncWebServer.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,22 @@ typedef enum http_method WebRequestMethod;
8585
#else
8686
#ifndef WEBSERVER_H
8787
typedef enum {
88-
HTTP_GET = 0b00000001,
89-
HTTP_POST = 0b00000010,
90-
HTTP_DELETE = 0b00000100,
91-
HTTP_PUT = 0b00001000,
92-
HTTP_PATCH = 0b00010000,
93-
HTTP_HEAD = 0b00100000,
94-
HTTP_OPTIONS = 0b01000000,
95-
HTTP_ANY = 0b01111111,
88+
HTTP_GET = 0b0000000000000001,
89+
HTTP_POST = 0b0000000000000010,
90+
HTTP_DELETE = 0b0000000000000100,
91+
HTTP_PUT = 0b0000000000001000,
92+
HTTP_PATCH = 0b0000000000010000,
93+
HTTP_HEAD = 0b0000000000100000,
94+
HTTP_OPTIONS = 0b0000000001000000,
95+
HTTP_PROPFIND = 0b0000000010000000,
96+
HTTP_LOCK = 0b0000000100000000,
97+
HTTP_UNLOCK = 0b0000001000000000,
98+
HTTP_PROPPATCH = 0b0000010000000000,
99+
HTTP_MKCOL = 0b0000100000000000,
100+
HTTP_MOVE = 0b0001000000000000,
101+
HTTP_COPY = 0b0010000000000000,
102+
HTTP_RESERVED = 0b0100000000000000,
103+
HTTP_ANY = 0b0111111111111111,
96104
} WebRequestMethod;
97105
#endif
98106
#endif
@@ -114,7 +122,7 @@ class FileOpenMode {
114122
#define RESPONSE_TRY_AGAIN 0xFFFFFFFF
115123
#define RESPONSE_STREAM_BUFFER_SIZE 1460
116124

117-
typedef uint8_t WebRequestMethodComposite;
125+
typedef uint16_t WebRequestMethodComposite;
118126
typedef std::function<void(void)> ArDisconnectHandler;
119127

120128
/*

src/WebRequest.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,20 @@ bool AsyncWebServerRequest::_parseReqHead() {
309309
_method = HTTP_HEAD;
310310
} else if (m == T_OPTIONS) {
311311
_method = HTTP_OPTIONS;
312+
} else if (m == T_PROPFIND) {
313+
_method = HTTP_PROPFIND;
314+
} else if (m == T_LOCK) {
315+
_method = HTTP_LOCK;
316+
} else if (m == T_UNLOCK) {
317+
_method = HTTP_UNLOCK;
318+
} else if (m == T_PROPPATCH) {
319+
_method = HTTP_PROPPATCH;
320+
} else if (m == T_MKCOL) {
321+
_method = HTTP_MKCOL;
322+
} else if (m == T_MOVE) {
323+
_method = HTTP_MOVE;
324+
} else if (m == T_COPY) {
325+
_method = HTTP_COPY;
312326
} else {
313327
return false;
314328
}
@@ -1154,6 +1168,27 @@ const char *AsyncWebServerRequest::methodToString() const {
11541168
if (_method & HTTP_OPTIONS) {
11551169
return T_OPTIONS;
11561170
}
1171+
if (_method & HTTP_PROPFIND) {
1172+
return T_PROPFIND;
1173+
}
1174+
if (_method & HTTP_LOCK) {
1175+
return T_LOCK;
1176+
}
1177+
if (_method & HTTP_UNLOCK) {
1178+
return T_UNLOCK;
1179+
}
1180+
if (_method & HTTP_PROPPATCH) {
1181+
return T_PROPPATCH;
1182+
}
1183+
if (_method & HTTP_MKCOL) {
1184+
return T_MKCOL;
1185+
}
1186+
if (_method & HTTP_MOVE) {
1187+
return T_MOVE;
1188+
}
1189+
if (_method & HTTP_COPY) {
1190+
return T_COPY;
1191+
}
11571192
return T_UNKNOWN;
11581193
}
11591194

src/literals.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ static constexpr const char T_uri[] = "uri";
101101
static constexpr const char T_username[] = "username";
102102
static constexpr const char T_WS[] = "websocket";
103103
static constexpr const char T_WWW_AUTH[] = "WWW-Authenticate";
104+
static constexpr const char T_X_Expected_Entity_Length[] = "X-Expected-Entity-Length";
104105

105106
// HTTP Methods
106107
static constexpr const char T_ANY[] = "ANY";
@@ -111,6 +112,13 @@ static constexpr const char T_DELETE[] = "DELETE";
111112
static constexpr const char T_PATCH[] = "PATCH";
112113
static constexpr const char T_HEAD[] = "HEAD";
113114
static constexpr const char T_OPTIONS[] = "OPTIONS";
115+
static constexpr const char T_PROPFIND[] = "PROPFIND";
116+
static constexpr const char T_LOCK[] = "LOCK";
117+
static constexpr const char T_UNLOCK[] = "UNLOCK";
118+
static constexpr const char T_PROPPATCH[] = "PROPPATCH";
119+
static constexpr const char T_MKCOL[] = "MKCOL";
120+
static constexpr const char T_MOVE[] = "MOVE";
121+
static constexpr const char T_COPY[] = "COPY";
114122
static constexpr const char T_UNKNOWN[] = "UNKNOWN";
115123

116124
// Req content types
@@ -183,6 +191,7 @@ DECLARE_STR(T_HTTP_CODE_203, "Non-Authoritative Information");
183191
DECLARE_STR(T_HTTP_CODE_204, "No Content");
184192
DECLARE_STR(T_HTTP_CODE_205, "Reset Content");
185193
DECLARE_STR(T_HTTP_CODE_206, "Partial Content");
194+
DECLARE_STR(T_HTTP_CODE_207, "Multi Status");
186195
DECLARE_STR(T_HTTP_CODE_300, "Multiple Choices");
187196
DECLARE_STR(T_HTTP_CODE_301, "Moved Permanently");
188197
DECLARE_STR(T_HTTP_CODE_302, "Found");
@@ -215,6 +224,7 @@ DECLARE_STR(T_HTTP_CODE_502, "Bad Gateway");
215224
DECLARE_STR(T_HTTP_CODE_503, "Service Unavailable");
216225
DECLARE_STR(T_HTTP_CODE_504, "Gateway Time-out");
217226
DECLARE_STR(T_HTTP_CODE_505, "HTTP Version Not Supported");
227+
DECLARE_STR(T_HTTP_CODE_507, "Insufficient Storage");
218228
DECLARE_STR(T_HTTP_CODE_ANY, "Unknown code");
219229

220230
static constexpr const char *T_only_once_headers[] = {

0 commit comments

Comments
 (0)