Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions examples/WebDAVMethods/WebDAVMethods.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright 2016-2026 Hristo Gochkov, Mathieu Carbou, Emil Muratov, Mitch Bradley

//
// - Test for additional WebDAV request methods
//

#include <Arduino.h>
#if defined(ESP32) || defined(LIBRETINY)
#include <AsyncTCP.h>
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
#include <RPAsyncTCP.h>
#include <WiFi.h>
#endif

#include <ESPAsyncWebServer.h>

using namespace asyncsrv;

// Tests:
//
// Send requests with various methods
// curl -s -X PROPFIND http://192.168.4.1/
// curl -s -X LOCK http://192.168.4.1/
// curl -s -X UNLOCK http://192.168.4.1/
// curl -s -X PROPPATCH http://192.168.4.1/
// curl -s -X MKCOL http://192.168.4.1/
// curl -s -X MOVE http://192.168.4.1/
// curl -s -X COPY http://192.168.4.1/
//
// In all cases, the request will be accepted with text/plain response 200 like
// "Got method PROPFIND on URL /"

static AsyncWebServer server(80);

void setup() {
Serial.begin(115200);

#if ASYNCWEBSERVER_WIFI_SUPPORTED
WiFi.mode(WIFI_AP);
WiFi.softAP("esp-captive");
#endif

server.onNotFound([](AsyncWebServerRequest *request) {
String resp("Got method ");
resp += request->methodToString();
resp += " on URL ";
resp += request->url();
resp += "\r\n";

Serial.print(resp);

request->send(200, "text/plain", resp.c_str());
});

server.begin();
}

void loop() {
delay(100);
}
1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ src_dir = examples/PerfTests
; src_dir = examples/URIMatcherTest
; src_dir = examples/WebSocket
; src_dir = examples/WebSocketEasy
; src_dir = examples/WebDAVMethods

[env]
framework = arduino
Expand Down
26 changes: 17 additions & 9 deletions src/ESPAsyncWebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,22 @@ typedef enum http_method WebRequestMethod;
#else
#ifndef WEBSERVER_H
typedef enum {
HTTP_GET = 0b00000001,
HTTP_POST = 0b00000010,
HTTP_DELETE = 0b00000100,
HTTP_PUT = 0b00001000,
HTTP_PATCH = 0b00010000,
HTTP_HEAD = 0b00100000,
HTTP_OPTIONS = 0b01000000,
HTTP_ANY = 0b01111111,
HTTP_GET = 0b0000000000000001,
HTTP_POST = 0b0000000000000010,
HTTP_DELETE = 0b0000000000000100,
HTTP_PUT = 0b0000000000001000,
HTTP_PATCH = 0b0000000000010000,
HTTP_HEAD = 0b0000000000100000,
HTTP_OPTIONS = 0b0000000001000000,
HTTP_PROPFIND = 0b0000000010000000,
HTTP_LOCK = 0b0000000100000000,
HTTP_UNLOCK = 0b0000001000000000,
HTTP_PROPPATCH = 0b0000010000000000,
HTTP_MKCOL = 0b0000100000000000,
HTTP_MOVE = 0b0001000000000000,
HTTP_COPY = 0b0010000000000000,
HTTP_RESERVED = 0b0100000000000000,
HTTP_ANY = 0b0111111111111111,
} WebRequestMethod;
#endif
#endif
Expand All @@ -114,7 +122,7 @@ class FileOpenMode {
#define RESPONSE_TRY_AGAIN 0xFFFFFFFF
#define RESPONSE_STREAM_BUFFER_SIZE 1460

typedef uint8_t WebRequestMethodComposite;
typedef uint16_t WebRequestMethodComposite;
typedef std::function<void(void)> ArDisconnectHandler;

/*
Expand Down
35 changes: 35 additions & 0 deletions src/WebRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,20 @@ bool AsyncWebServerRequest::_parseReqHead() {
_method = HTTP_HEAD;
} else if (m == T_OPTIONS) {
_method = HTTP_OPTIONS;
} else if (m == T_PROPFIND) {
_method = HTTP_PROPFIND;
} else if (m == T_LOCK) {
_method = HTTP_LOCK;
} else if (m == T_UNLOCK) {
_method = HTTP_UNLOCK;
} else if (m == T_PROPPATCH) {
_method = HTTP_PROPPATCH;
} else if (m == T_MKCOL) {
_method = HTTP_MKCOL;
} else if (m == T_MOVE) {
_method = HTTP_MOVE;
} else if (m == T_COPY) {
_method = HTTP_COPY;
} else {
return false;
}
Expand Down Expand Up @@ -1154,6 +1168,27 @@ const char *AsyncWebServerRequest::methodToString() const {
if (_method & HTTP_OPTIONS) {
return T_OPTIONS;
}
if (_method & HTTP_PROPFIND) {
return T_PROPFIND;
}
if (_method & HTTP_LOCK) {
return T_LOCK;
}
if (_method & HTTP_UNLOCK) {
return T_UNLOCK;
}
if (_method & HTTP_PROPPATCH) {
return T_PROPPATCH;
}
if (_method & HTTP_MKCOL) {
return T_MKCOL;
}
if (_method & HTTP_MOVE) {
return T_MOVE;
}
if (_method & HTTP_COPY) {
return T_COPY;
}
return T_UNKNOWN;
}

Expand Down
8 changes: 8 additions & 0 deletions src/literals.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ static constexpr const char T_DELETE[] = "DELETE";
static constexpr const char T_PATCH[] = "PATCH";
static constexpr const char T_HEAD[] = "HEAD";
static constexpr const char T_OPTIONS[] = "OPTIONS";
static constexpr const char T_PROPFIND[] = "PROPFIND";
static constexpr const char T_LOCK[] = "LOCK";
static constexpr const char T_UNLOCK[] = "UNLOCK";
static constexpr const char T_PROPPATCH[] = "PROPPATCH";
static constexpr const char T_MKCOL[] = "MKCOL";
static constexpr const char T_MOVE[] = "MOVE";
static constexpr const char T_COPY[] = "COPY";
static constexpr const char T_UNKNOWN[] = "UNKNOWN";

// Req content types
Expand Down Expand Up @@ -183,6 +190,7 @@ DECLARE_STR(T_HTTP_CODE_203, "Non-Authoritative Information");
DECLARE_STR(T_HTTP_CODE_204, "No Content");
DECLARE_STR(T_HTTP_CODE_205, "Reset Content");
DECLARE_STR(T_HTTP_CODE_206, "Partial Content");
DECLARE_STR(T_HTTP_CODE_207, "Multi Status");
DECLARE_STR(T_HTTP_CODE_300, "Multiple Choices");
DECLARE_STR(T_HTTP_CODE_301, "Moved Permanently");
DECLARE_STR(T_HTTP_CODE_302, "Found");
Expand Down