diff --git a/examples/HTTPMethods/HTTPMethods.ino b/examples/HTTPMethods/HTTPMethods.ino index f9864cbf..ce63d4b0 100644 --- a/examples/HTTPMethods/HTTPMethods.ino +++ b/examples/HTTPMethods/HTTPMethods.ino @@ -23,8 +23,6 @@ #include #endif -#define ASYNCWEBSERVER_NO_GLOBAL_HTTP_METHODS 1 -#undef HTTP_ANY #include static AsyncWebServer server(80); @@ -37,14 +35,19 @@ void setup() { WiFi.softAP("esp-captive"); #endif - // curl -v http://192.168.4.1/get-or-post - // curl -v -X POST -d "a=b" http://192.168.4.1/get-or-post - server.on("/get-or-post", WebRequestMethod::HTTP_GET | WebRequestMethod::HTTP_POST, [](AsyncWebServerRequest *request) { + // curl -v http://192.168.4.1/get-or-post => Hello + // curl -v -X POST -d "a=b" http://192.168.4.1/get-or-post => Hello + // curl -v -X PUT -d "a=b" http://192.168.4.1/get-or-post => 404 + // curl -v -X PATCH -d "a=b" http://192.168.4.1/get-or-post => 404 + server.on("/get-or-post", HTTP_GET | HTTP_POST, [](AsyncWebServerRequest *request) { request->send(200, "text/plain", "Hello"); }); - // curl -v http://192.168.4.1/any - server.on("/any", WebRequestMethod::HTTP_ANY, [](AsyncWebServerRequest *request) { + // curl -v http://192.168.4.1/any => Hello + // curl -v -X POST -d "a=b" http://192.168.4.1/any => Hello + // curl -v -X PUT -d "a=b" http://192.168.4.1/any => Hello + // curl -v -X PATCH -d "a=b" http://192.168.4.1/any => Hello + server.on("/any", HTTP_ANY, [](AsyncWebServerRequest *request) { request->send(200, "text/plain", "Hello"); }); diff --git a/src/AsyncJson.cpp b/src/AsyncJson.cpp index 750b1bc7..a85536c2 100644 --- a/src/AsyncJson.cpp +++ b/src/AsyncJson.cpp @@ -115,14 +115,11 @@ size_t AsyncMessagePackResponse::_fillBuffer(uint8_t *data, size_t len) { #if ARDUINOJSON_VERSION_MAJOR == 6 AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(AsyncURIMatcher uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize) - : _uri(std::move(uri)), - _method(AsyncWebRequestMethod::HTTP_GET | AsyncWebRequestMethod::HTTP_POST | AsyncWebRequestMethod::HTTP_PUT | AsyncWebRequestMethod::HTTP_PATCH), - _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} + : _uri(std::move(uri)), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), + _maxContentLength(16384) {} #else AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(AsyncURIMatcher uri, ArJsonRequestHandlerFunction onRequest) - : _uri(std::move(uri)), - _method(AsyncWebRequestMethod::HTTP_GET | AsyncWebRequestMethod::HTTP_POST | AsyncWebRequestMethod::HTTP_PUT | AsyncWebRequestMethod::HTTP_PATCH), - _onRequest(onRequest), _maxContentLength(16384) {} + : _uri(std::move(uri)), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #endif bool AsyncCallbackJsonWebHandler::canHandle(AsyncWebServerRequest *request) const { @@ -135,17 +132,17 @@ bool AsyncCallbackJsonWebHandler::canHandle(AsyncWebServerRequest *request) cons } #if ASYNC_MSG_PACK_SUPPORT == 1 - return request->method() == AsyncWebRequestMethod::HTTP_GET || request->contentType().equalsIgnoreCase(asyncsrv::T_application_json) + return request->method() == HTTP_GET || request->contentType().equalsIgnoreCase(asyncsrv::T_application_json) || request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack); #else - return request->method() == AsyncWebRequestMethod::HTTP_GET || request->contentType().equalsIgnoreCase(asyncsrv::T_application_json); + return request->method() == HTTP_GET || request->contentType().equalsIgnoreCase(asyncsrv::T_application_json); #endif } void AsyncCallbackJsonWebHandler::handleRequest(AsyncWebServerRequest *request) { if (_onRequest) { // GET request: - if (request->method() == AsyncWebRequestMethod::HTTP_GET) { + if (request->method() == HTTP_GET) { JsonVariant json; _onRequest(request, json); return; diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 76251d89..48ef7526 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,6 +45,72 @@ #error Platform not supported #endif +// HTTP method types from the platform's HTTP parser library. +// Arduino ESP32 core provides HTTP_Method.h which typedef's http_method as +// HTTPMethod and defines HTTP_ANY = (HTTPMethod)(255) as the "match any" sentinel. +// Fall back to the raw http_parser.h (always available via the TCP library) or, +// as a last resort, to a fully inline fallback definition. +#if __has_include() +#include +// HTTP_Method.h provides: typedef enum http_method HTTPMethod; +// and: #define HTTP_ANY (HTTPMethod)(255) +#elif __has_include() +#include +// http_parser.h provides enum http_method but not the HTTP_ANY sentinel. +// Define the sentinel here, matching the value used by Arduino's HTTP_Method.h. +#ifndef HTTP_ANY +#define HTTP_ANY ((http_method)(255)) +#endif +#else +// Full fallback for toolchains that expose neither header. +// Enum values match the llhttp/http_parser spec used by all supported platforms. +typedef enum { + HTTP_DELETE = 0, + HTTP_GET = 1, + HTTP_HEAD = 2, + HTTP_POST = 3, + HTTP_PUT = 4, + /* pathological */ + HTTP_CONNECT = 5, + HTTP_OPTIONS = 6, + HTTP_TRACE = 7, + /* WebDAV */ + HTTP_COPY = 8, + HTTP_LOCK = 9, + HTTP_MKCOL = 10, + HTTP_MOVE = 11, + HTTP_PROPFIND = 12, + HTTP_PROPPATCH = 13, + HTTP_SEARCH = 14, + HTTP_UNLOCK = 15, + HTTP_BIND = 16, + HTTP_REBIND = 17, + HTTP_UNBIND = 18, + HTTP_ACL = 19, + /* subversion */ + HTTP_REPORT = 20, + HTTP_MKACTIVITY = 21, + HTTP_CHECKOUT = 22, + HTTP_MERGE = 23, + /* upnp */ + HTTP_MSEARCH = 24, + HTTP_NOTIFY = 25, + HTTP_SUBSCRIBE = 26, + HTTP_UNSUBSCRIBE = 27, + /* RFC-5789 */ + HTTP_PATCH = 28, + HTTP_PURGE = 29, + /* CalDAV */ + HTTP_MKCALENDAR = 30, + /* RFC-2068, section 19.6.1.2 */ + HTTP_LINK = 31, + HTTP_UNLINK = 32, + /* icecast */ + HTTP_SOURCE = 33, +} http_method; +#define HTTP_ANY ((http_method)(255)) +#endif + #include "AsyncWebServerVersion.h" #define ASYNCWEBSERVER_FORK_ESP32Async @@ -78,44 +144,127 @@ class AsyncCallbackWebHandler; class AsyncResponseStream; class AsyncMiddlewareChain; -// Namespace for web request method defines -namespace AsyncWebRequestMethod { -// The long name here is because we sometimes include this in the global namespace -enum AsyncWebRequestMethodType { - 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, -}; -}; // namespace AsyncWebRequestMethod +// WebRequestMethod: a single HTTP request method, taken directly from the +// platform's http_parser enum. HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, +// HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS, HTTP_PROPFIND, HTTP_LOCK, HTTP_UNLOCK, +// HTTP_PROPPATCH, HTTP_MKCOL, HTTP_MOVE, HTTP_COPY and many others are already +// defined globally by the platform headers above — no redefinition needed here. +// HTTP_ANY (= 255) is the "match any method" sentinel, also from the platform. +typedef http_method WebRequestMethod; + +// WebRequestMethodComposite: a compact, allocation-free set of HTTP methods +// that a handler accepts. Internally stored as a 64-bit bitmask (one bit per +// http_method enum value, which spans 0–33 in the current llhttp spec) plus a +// single boolean sentinel for HTTP_ANY (= 255, the "match anything" value). +// A uint64_t bitmask supports up to 64 distinct enum values; the http_method +// enum currently defines 34 values (0–33), so all methods fit with room to +// spare. An empty composite (no bits set, _any == false) matches *nothing*. +// A composite with _any == true matches *any* method. +class WebRequestMethodComposite { +public: + // Empty composite = match nothing. + WebRequestMethodComposite() : _bits(0), _any(false) {} + + // Single-method composite. + WebRequestMethodComposite(WebRequestMethod m) : _bits(0), _any(false) { + _set(m); + } -typedef AsyncWebRequestMethod::AsyncWebRequestMethodType WebRequestMethod; -typedef uint16_t WebRequestMethodComposite; + // Append a method. + WebRequestMethodComposite &add(WebRequestMethod m) { + _set(m); + return *this; + } -// Type-safe helper functions for composite methods -extern constexpr inline WebRequestMethodComposite operator|(WebRequestMethodComposite l, WebRequestMethod r) { - return l | static_cast(r); -}; -extern constexpr inline WebRequestMethodComposite operator|(WebRequestMethod l, WebRequestMethod r) { - return static_cast(l) | r; + // Returns true when this composite contains (or should match) the given + // method. + bool allows(WebRequestMethod m) const { + if (_any) + return true; + if (m == HTTP_ANY) + return false; // HTTP_ANY is not a real request method; only matches when _any is set + const unsigned idx = static_cast(m); + return idx < 64 && (_bits & (1ULL << idx)) != 0; + } + + // Equality: true when the composite holds exactly this one method. + bool operator==(WebRequestMethod m) const { + if (m == HTTP_ANY) + return _any && _bits == 0; + const unsigned idx = static_cast(m); + if (idx >= 64) + return false; + return !_any && _bits == (1ULL << idx); + } + bool operator!=(WebRequestMethod m) const { + return !(*this == m); + } + + // True when this is an empty (match-nothing) composite. + bool empty() const { + return _bits == 0 && !_any; + } + + String toString() const { + if (empty()) { + return "<>"; + } + String result = "<"; + bool first = true; + if (_any) { + result.concat(static_cast(HTTP_ANY)); + first = false; + } + for (unsigned i = 0; i < 64; ++i) { + if (_bits & (1ULL << i)) { + if (!first) { + result += ","; + } + result.concat(static_cast(i)); + first = false; + } + } + result.concat(">"); + return result; + } + +private: + uint64_t _bits; + bool _any; + + void _set(WebRequestMethod m) { + if (m == HTTP_ANY) { + _any = true; + } else { + const unsigned idx = static_cast(m); + if (idx < 64) { + _bits |= (1ULL << idx); + } + } + } }; -#if !defined(ASYNCWEBSERVER_NO_GLOBAL_HTTP_METHODS) -// Import the method enum values to the global namespace -using namespace AsyncWebRequestMethod; -#endif +// Build a composite from two individual methods: HTTP_GET | HTTP_POST +inline WebRequestMethodComposite operator|(WebRequestMethod l, WebRequestMethod r) { + WebRequestMethodComposite c; + c.add(l).add(r); + return c; +} + +// Extend a composite with one more method: (HTTP_GET | HTTP_POST) | HTTP_PUT +inline WebRequestMethodComposite operator|(WebRequestMethodComposite c, WebRequestMethod r) { + c.add(r); + return c; +} + +// Membership test: returns true when composite c contains method m. +// Usage: if (handler._method & request->method()) { /* matched */ } +inline bool operator&(const WebRequestMethodComposite &c, WebRequestMethod m) { + return c.allows(m); +} +inline bool operator&(WebRequestMethod m, const WebRequestMethodComposite &c) { + return c.allows(m); +} #ifndef HAVE_FS_FILE_OPEN_MODE namespace fs { @@ -265,7 +414,7 @@ class AsyncWebServerRequest { uint8_t _parseState; uint8_t _version; - WebRequestMethodComposite _method; + WebRequestMethod _method; String _url; String _host; String _contentType; @@ -355,7 +504,7 @@ class AsyncWebServerRequest { uint8_t version() const { return _version; } - WebRequestMethodComposite method() const { + WebRequestMethod method() const { return _method; } const String &url() const { @@ -374,6 +523,7 @@ class AsyncWebServerRequest { return _isMultipart; } + const char *methodToString(WebRequestMethod method) const; const char *methodToString() const; const char *requestedConnTypeToString() const; @@ -383,10 +533,10 @@ class AsyncWebServerRequest { bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED) const; bool isWebSocketUpgrade() const { - return _method == AsyncWebRequestMethod::HTTP_GET && isExpectedRequestedConnType(RCT_WS); + return _method == HTTP_GET && isExpectedRequestedConnType(RCT_WS); } bool isSSE() const { - return _method == AsyncWebRequestMethod::HTTP_GET && isExpectedRequestedConnType(RCT_EVENT); + return _method == HTTP_GET && isExpectedRequestedConnType(RCT_EVENT); } bool isHTTP() const { return isExpectedRequestedConnType(RCT_DEFAULT, RCT_HTTP); @@ -964,6 +1114,8 @@ class AsyncURIMatcher { #endif private: + friend class AsyncWebServer; + // fields String _value; union { @@ -1556,7 +1708,7 @@ class AsyncWebServer : public AsyncMiddlewareChain { bool removeHandler(AsyncWebHandler *handler); AsyncCallbackWebHandler &on(AsyncURIMatcher uri, ArRequestHandlerFunction onRequest) { - return on(std::move(uri), AsyncWebRequestMethod::HTTP_ANY, onRequest); + return on(std::move(uri), HTTP_ANY, onRequest); } AsyncCallbackWebHandler &on( AsyncURIMatcher uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload = nullptr, diff --git a/src/Middleware.cpp b/src/Middleware.cpp index 42c05af9..94a720ff 100644 --- a/src/Middleware.cpp +++ b/src/Middleware.cpp @@ -249,7 +249,7 @@ void AsyncCorsMiddleware::run(AsyncWebServerRequest *request, ArMiddlewareNext n // Origin header ? => CORS handling if (request->hasHeader(asyncsrv::T_CORS_O)) { // check if this is a preflight request => handle it and return - if (request->method() == AsyncWebRequestMethod::HTTP_OPTIONS) { + if (request->method() == HTTP_OPTIONS) { AsyncWebServerResponse *response = request->beginResponse(200); addCORSHeaders(request, response); request->send(response); diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index dac40c6e..5332e795 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -62,7 +62,7 @@ class AsyncCallbackWebHandler : public AsyncWebHandler { bool _isRegex; public: - AsyncCallbackWebHandler() : _uri(), _method(AsyncWebRequestMethod::HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {} + AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {} void setUri(AsyncURIMatcher uri); void setMethod(WebRequestMethodComposite method) { _method = method; diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 7439f53f..dd088322 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -103,7 +103,7 @@ AsyncStaticWebHandler &AsyncStaticWebHandler::setLastModified() { } bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest *request) const { - return request->isHTTP() && request->method() == AsyncWebRequestMethod::HTTP_GET && request->url().startsWith(_uri) && _getFile(request); + return request->isHTTP() && request->method() == HTTP_GET && request->url().startsWith(_uri) && _getFile(request); } bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest *request) const { diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 3f38fc9d..5e57082d 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -39,12 +39,11 @@ enum { }; AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer *s, AsyncClient *c) - : _client(c), _server(s), _handler(NULL), _response(NULL), _onDisconnectfn(NULL), _temp(), _parseState(PARSE_REQ_START), _version(0), - _method(AsyncWebRequestMethod::HTTP_ANY), _url(), _host(), _contentType(), _boundary(), _authorization(), _reqconntype(RCT_HTTP), - _authMethod(AsyncAuthType::AUTH_NONE), _isMultipart(false), _isPlainPost(false), _expectingContinue(false), _contentLength(0), _parsedLength(0), - _multiParseState(0), _boundaryPosition(0), _itemStartIndex(0), _itemSize(0), _itemName(), _itemFilename(), _itemType(), _itemValue(), _itemBuffer(0), - _itemBufferIndex(0), _itemIsFile(false), _chunkStartIndex(0), _chunkOffset(0), _chunkSize(0), _chunkedParseState(CHUNK_NONE), _chunkedLastChar(0), - _tempObject(NULL) { + : _client(c), _server(s), _handler(NULL), _response(NULL), _onDisconnectfn(NULL), _temp(), _parseState(PARSE_REQ_START), _version(0), _method(HTTP_ANY), + _url(), _host(), _contentType(), _boundary(), _authorization(), _reqconntype(RCT_HTTP), _authMethod(AsyncAuthType::AUTH_NONE), _isMultipart(false), + _isPlainPost(false), _expectingContinue(false), _contentLength(0), _parsedLength(0), _multiParseState(0), _boundaryPosition(0), _itemStartIndex(0), + _itemSize(0), _itemName(), _itemFilename(), _itemType(), _itemValue(), _itemBuffer(0), _itemBufferIndex(0), _itemIsFile(false), _chunkStartIndex(0), + _chunkOffset(0), _chunkSize(0), _chunkedParseState(CHUNK_NONE), _chunkedLastChar(0), _tempObject(NULL) { c->onError( [](void *r, AsyncClient *c, int8_t error) { (void)c; @@ -315,33 +314,39 @@ bool AsyncWebServerRequest::_parseReqHead() { _temp = _temp.substring(index + 1); if (m == T_GET) { - _method = AsyncWebRequestMethod::HTTP_GET; + _method = HTTP_GET; } else if (m == T_POST) { - _method = AsyncWebRequestMethod::HTTP_POST; + _method = HTTP_POST; } else if (m == T_DELETE) { - _method = AsyncWebRequestMethod::HTTP_DELETE; + _method = HTTP_DELETE; } else if (m == T_PUT) { - _method = AsyncWebRequestMethod::HTTP_PUT; + _method = HTTP_PUT; } else if (m == T_PATCH) { - _method = AsyncWebRequestMethod::HTTP_PATCH; + _method = HTTP_PATCH; } else if (m == T_HEAD) { - _method = AsyncWebRequestMethod::HTTP_HEAD; + _method = HTTP_HEAD; } else if (m == T_OPTIONS) { - _method = AsyncWebRequestMethod::HTTP_OPTIONS; + _method = HTTP_OPTIONS; } else if (m == T_PROPFIND) { - _method = AsyncWebRequestMethod::HTTP_PROPFIND; + _method = HTTP_PROPFIND; } else if (m == T_LOCK) { - _method = AsyncWebRequestMethod::HTTP_LOCK; + _method = HTTP_LOCK; } else if (m == T_UNLOCK) { - _method = AsyncWebRequestMethod::HTTP_UNLOCK; + _method = HTTP_UNLOCK; } else if (m == T_PROPPATCH) { - _method = AsyncWebRequestMethod::HTTP_PROPPATCH; + _method = HTTP_PROPPATCH; } else if (m == T_MKCOL) { - _method = AsyncWebRequestMethod::HTTP_MKCOL; + _method = HTTP_MKCOL; } else if (m == T_MOVE) { - _method = AsyncWebRequestMethod::HTTP_MOVE; + _method = HTTP_MOVE; } else if (m == T_COPY) { - _method = AsyncWebRequestMethod::HTTP_COPY; + _method = HTTP_COPY; + } else if (m == T_CONNECT) { + _method = HTTP_CONNECT; + } else if (m == T_TRACE) { + _method = HTTP_TRACE; + } else if (m == T_SEARCH) { + _method = HTTP_SEARCH; } else { return false; } @@ -1312,52 +1317,54 @@ String AsyncWebServerRequest::urlDecode(const String &text) const { } const char *AsyncWebServerRequest::methodToString() const { - if (_method == AsyncWebRequestMethod::HTTP_ANY) { - return T_ANY; - } - if (_method & AsyncWebRequestMethod::HTTP_GET) { - return T_GET; - } - if (_method & AsyncWebRequestMethod::HTTP_POST) { - return T_POST; - } - if (_method & AsyncWebRequestMethod::HTTP_DELETE) { - return T_DELETE; - } - if (_method & AsyncWebRequestMethod::HTTP_PUT) { - return T_PUT; - } - if (_method & AsyncWebRequestMethod::HTTP_PATCH) { - return T_PATCH; - } - if (_method & AsyncWebRequestMethod::HTTP_HEAD) { - return T_HEAD; - } - if (_method & AsyncWebRequestMethod::HTTP_OPTIONS) { - return T_OPTIONS; - } - if (_method & AsyncWebRequestMethod::HTTP_PROPFIND) { - return T_PROPFIND; - } - if (_method & AsyncWebRequestMethod::HTTP_LOCK) { - return T_LOCK; - } - if (_method & AsyncWebRequestMethod::HTTP_UNLOCK) { - return T_UNLOCK; - } - if (_method & AsyncWebRequestMethod::HTTP_PROPPATCH) { - return T_PROPPATCH; - } - if (_method & AsyncWebRequestMethod::HTTP_MKCOL) { - return T_MKCOL; - } - if (_method & AsyncWebRequestMethod::HTTP_MOVE) { - return T_MOVE; - } - if (_method & AsyncWebRequestMethod::HTTP_COPY) { - return T_COPY; + return methodToString(_method); +} + +const char *AsyncWebServerRequest::methodToString(WebRequestMethod method) const { + switch (method) { + case HTTP_DELETE: return T_DELETE; + case HTTP_GET: return T_GET; + case HTTP_HEAD: return T_HEAD; + case HTTP_POST: return T_POST; + case HTTP_PUT: return T_PUT; + /* pathological */ + case HTTP_CONNECT: return T_CONNECT; + case HTTP_OPTIONS: return T_OPTIONS; + case HTTP_TRACE: return T_TRACE; + /* WebDAV */ + case HTTP_COPY: return T_COPY; + case HTTP_LOCK: return T_LOCK; + case HTTP_MKCOL: return T_MKCOL; + case HTTP_MOVE: return T_MOVE; + case HTTP_PROPFIND: return T_PROPFIND; + case HTTP_PROPPATCH: return T_PROPPATCH; + case HTTP_SEARCH: return T_SEARCH; + case HTTP_UNLOCK: return T_UNLOCK; + case HTTP_BIND: return T_BIND; + case HTTP_REBIND: return T_REBIND; + case HTTP_UNBIND: return T_UNBIND; + case HTTP_ACL: return T_ACL; + /* subversion */ + case HTTP_REPORT: return T_REPORT; + case HTTP_MKACTIVITY: return T_MKACTIVITY; + case HTTP_CHECKOUT: return T_CHECKOUT; + case HTTP_MERGE: return T_MERGE; + /* upnp */ + case HTTP_MSEARCH: return T_MSEARCH; + case HTTP_NOTIFY: return T_NOTIFY; + case HTTP_SUBSCRIBE: return T_SUBSCRIBE; + case HTTP_UNSUBSCRIBE: return T_UNSUBSCRIBE; + /* RFC-5789 */ + case HTTP_PATCH: return T_PATCH; + case HTTP_PURGE: return T_PURGE; + /* CalDAV */ + case HTTP_MKCALENDAR: return T_MKCALENDAR; + /* RFC-2068, section 19.6.1.2 */ + case HTTP_LINK: return T_LINK; + case HTTP_UNLINK: return T_UNLINK; + case HTTP_ANY: return T_ANY; + default: return T_UNKNOWN; } - return T_UNKNOWN; } const char *AsyncWebServerRequest::requestedConnTypeToString() const { diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 2ab5bcd4..e95c03a4 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -3,6 +3,7 @@ #include "ESPAsyncWebServer.h" #include "WebHandlerImpl.h" +#include "AsyncWebServerLogging.h" #include #include @@ -156,6 +157,7 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request) { AsyncCallbackWebHandler &AsyncWebServer::on( AsyncURIMatcher uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody ) { + async_ws_log_v("+Handler: %s %s", uri._value.c_str(), method.toString().c_str()); AsyncCallbackWebHandler *handler = new AsyncCallbackWebHandler(); handler->setUri(std::move(uri)); handler->setMethod(method); diff --git a/src/literals.h b/src/literals.h index 71cf1274..9799e624 100644 --- a/src/literals.h +++ b/src/literals.h @@ -119,6 +119,25 @@ 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_CONNECT[] = "CONNECT"; +static constexpr const char T_TRACE[] = "TRACE"; +static constexpr const char T_SEARCH[] = "SEARCH"; +static constexpr const char T_BIND[] = "BIND"; +static constexpr const char T_REBIND[] = "REBIND"; +static constexpr const char T_UNBIND[] = "UNBIND"; +static constexpr const char T_ACL[] = "ACL"; +static constexpr const char T_REPORT[] = "REPORT"; +static constexpr const char T_MKACTIVITY[] = "MKACTIVITY"; +static constexpr const char T_CHECKOUT[] = "CHECKOUT"; +static constexpr const char T_MERGE[] = "MERGE"; +static constexpr const char T_MSEARCH[] = "M-SEARCH"; +static constexpr const char T_NOTIFY[] = "NOTIFY"; +static constexpr const char T_SUBSCRIBE[] = "SUBSCRIBE"; +static constexpr const char T_UNSUBSCRIBE[] = "UNSUBSCRIBE"; +static constexpr const char T_PURGE[] = "PURGE"; +static constexpr const char T_MKCALENDAR[] = "MKCALENDAR"; +static constexpr const char T_LINK[] = "LINK"; +static constexpr const char T_UNLINK[] = "UNLINK"; static constexpr const char T_UNKNOWN[] = "UNKNOWN"; // Req content types