4545#error Platform not supported
4646#endif
4747
48+ // HTTP method types from the platform's HTTP parser library.
49+ // Arduino ESP32 core provides HTTP_Method.h which typedef's http_method as
50+ // HTTPMethod and defines HTTP_ANY = (HTTPMethod)(255) as the "match any" sentinel.
51+ // Fall back to the raw http_parser.h (always available via the TCP library) or,
52+ // as a last resort, to a fully inline fallback definition.
53+ #if __has_include(<HTTP_Method.h>)
54+ #include < HTTP_Method.h>
55+ // HTTP_Method.h provides: typedef enum http_method HTTPMethod;
56+ // and: #define HTTP_ANY (HTTPMethod)(255)
57+ #elif __has_include(<http_parser.h>)
58+ #include < http_parser.h>
59+ // http_parser.h provides enum http_method but not the HTTP_ANY sentinel.
60+ // Define the sentinel here, matching the value used by Arduino's HTTP_Method.h.
61+ #ifndef HTTP_ANY
62+ #define HTTP_ANY ((http_method)(255 ))
63+ #endif
64+ #else
65+ // Full fallback for toolchains that expose neither header.
66+ // Enum values match the llhttp/http_parser spec used by all supported platforms.
67+ typedef enum {
68+ HTTP_DELETE = 0 ,
69+ HTTP_GET = 1 ,
70+ HTTP_HEAD = 2 ,
71+ HTTP_POST = 3 ,
72+ HTTP_PUT = 4 ,
73+ /* pathological */
74+ HTTP_CONNECT = 5 ,
75+ HTTP_OPTIONS = 6 ,
76+ HTTP_TRACE = 7 ,
77+ /* WebDAV */
78+ HTTP_COPY = 8 ,
79+ HTTP_LOCK = 9 ,
80+ HTTP_MKCOL = 10 ,
81+ HTTP_MOVE = 11 ,
82+ HTTP_PROPFIND = 12 ,
83+ HTTP_PROPPATCH = 13 ,
84+ HTTP_SEARCH = 14 ,
85+ HTTP_UNLOCK = 15 ,
86+ HTTP_BIND = 16 ,
87+ HTTP_REBIND = 17 ,
88+ HTTP_UNBIND = 18 ,
89+ HTTP_ACL = 19 ,
90+ /* subversion */
91+ HTTP_REPORT = 20 ,
92+ HTTP_MKACTIVITY = 21 ,
93+ HTTP_CHECKOUT = 22 ,
94+ HTTP_MERGE = 23 ,
95+ /* upnp */
96+ HTTP_MSEARCH = 24 ,
97+ HTTP_NOTIFY = 25 ,
98+ HTTP_SUBSCRIBE = 26 ,
99+ HTTP_UNSUBSCRIBE = 27 ,
100+ /* RFC-5789 */
101+ HTTP_PATCH = 28 ,
102+ HTTP_PURGE = 29 ,
103+ /* CalDAV */
104+ HTTP_MKCALENDAR = 30 ,
105+ /* RFC-2068, section 19.6.1.2 */
106+ HTTP_LINK = 31 ,
107+ HTTP_UNLINK = 32 ,
108+ /* icecast */
109+ HTTP_SOURCE = 33 ,
110+ } http_method;
111+ #define HTTP_ANY ((http_method)(255 ))
112+ #endif
113+
48114#include " AsyncWebServerVersion.h"
49115#define ASYNCWEBSERVER_FORK_ESP32Async
50116
@@ -78,44 +144,82 @@ class AsyncCallbackWebHandler;
78144class AsyncResponseStream ;
79145class AsyncMiddlewareChain ;
80146
81- // Namespace for web request method defines
82- namespace AsyncWebRequestMethod {
83- // The long name here is because we sometimes include this in the global namespace
84- enum AsyncWebRequestMethodType {
85- HTTP_GET = 0b0000000000000001 ,
86- HTTP_POST = 0b0000000000000010 ,
87- HTTP_DELETE = 0b0000000000000100 ,
88- HTTP_PUT = 0b0000000000001000 ,
89- HTTP_PATCH = 0b0000000000010000 ,
90- HTTP_HEAD = 0b0000000000100000 ,
91- HTTP_OPTIONS = 0b0000000001000000 ,
92- HTTP_PROPFIND = 0b0000000010000000 ,
93- HTTP_LOCK = 0b0000000100000000 ,
94- HTTP_UNLOCK = 0b0000001000000000 ,
95- HTTP_PROPPATCH = 0b0000010000000000 ,
96- HTTP_MKCOL = 0b0000100000000000 ,
97- HTTP_MOVE = 0b0001000000000000 ,
98- HTTP_COPY = 0b0010000000000000 ,
99- HTTP_RESERVED = 0b0100000000000000 ,
100- HTTP_ANY = 0b0111111111111111 ,
101- };
102- }; // namespace AsyncWebRequestMethod
147+ // WebRequestMethod: a single HTTP request method, taken directly from the
148+ // platform's http_parser enum. HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT,
149+ // HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS, HTTP_PROPFIND, HTTP_LOCK, HTTP_UNLOCK,
150+ // HTTP_PROPPATCH, HTTP_MKCOL, HTTP_MOVE, HTTP_COPY and many others are already
151+ // defined globally by the platform headers above — no redefinition needed here.
152+ // HTTP_ANY (= 255) is the "match any method" sentinel, also from the platform.
153+ typedef http_method WebRequestMethod;
154+
155+ // WebRequestMethodComposite: an ordered list of HTTP methods that a handler
156+ // accepts. An empty composite matches *nothing*. A composite containing
157+ // HTTP_ANY matches *any* method.
158+ class WebRequestMethodComposite {
159+ public:
160+ // Empty composite = match nothing.
161+ WebRequestMethodComposite () {}
103162
104- typedef AsyncWebRequestMethod::AsyncWebRequestMethodType WebRequestMethod;
105- typedef uint16_t WebRequestMethodComposite;
163+ // Single-method composite.
164+ WebRequestMethodComposite (WebRequestMethod m) {
165+ _methods.push_back (m);
166+ }
106167
107- // Type-safe helper functions for composite methods
108- extern constexpr inline WebRequestMethodComposite operator |(WebRequestMethodComposite l, WebRequestMethod r) {
109- return l | static_cast <WebRequestMethodComposite>(r);
110- };
111- extern constexpr inline WebRequestMethodComposite operator |(WebRequestMethod l, WebRequestMethod r) {
112- return static_cast <WebRequestMethodComposite>(l) | r;
168+ // Append a method.
169+ WebRequestMethodComposite &add (WebRequestMethod m) {
170+ _methods.push_back (m);
171+ return *this ;
172+ }
173+
174+ // Returns true when this composite contains (or should match) the given
175+ // method.
176+ bool contains (WebRequestMethod m) const {
177+ for (const auto &method : _methods) {
178+ if (method == HTTP_ANY || method == m) {
179+ return true ;
180+ }
181+ }
182+ return false ;
183+ }
184+
185+ // Equality: true when the composite holds exactly this one method.
186+ bool operator ==(WebRequestMethod m) const {
187+ return _methods.size () == 1 && _methods[0 ] == m;
188+ }
189+ bool operator !=(WebRequestMethod m) const {
190+ return !(*this == m);
191+ }
192+
193+ // True when this is an empty (match-nothing) composite.
194+ bool empty () const {
195+ return _methods.empty ();
196+ }
197+
198+ private:
199+ std::vector<WebRequestMethod> _methods;
113200};
114201
115- #if !defined(ASYNCWEBSERVER_NO_GLOBAL_HTTP_METHODS)
116- // Import the method enum values to the global namespace
117- using namespace AsyncWebRequestMethod ;
118- #endif
202+ // Build a composite from two individual methods: HTTP_GET | HTTP_POST
203+ inline WebRequestMethodComposite operator |(WebRequestMethod l, WebRequestMethod r) {
204+ WebRequestMethodComposite c;
205+ c.add (l).add (r);
206+ return c;
207+ }
208+
209+ // Extend a composite with one more method: (HTTP_GET | HTTP_POST) | HTTP_PUT
210+ inline WebRequestMethodComposite operator |(WebRequestMethodComposite c, WebRequestMethod r) {
211+ c.add (r);
212+ return c;
213+ }
214+
215+ // Membership test: returns true when composite c contains method m.
216+ // Usage: if (handler._method ^ request->method()) { /* matched */ }
217+ inline bool operator &(const WebRequestMethodComposite &c, WebRequestMethod m) {
218+ return c.contains (m);
219+ }
220+ inline bool operator &(WebRequestMethod m, const WebRequestMethodComposite &c) {
221+ return c.contains (m);
222+ }
119223
120224#ifndef HAVE_FS_FILE_OPEN_MODE
121225namespace fs {
@@ -188,7 +292,7 @@ class AsyncWebHeader {
188292 [[deprecated(" Use AsyncWebHeader::parse(data) instead" )]]
189293#endif
190294 AsyncWebHeader (const String &data)
191- : AsyncWebHeader(parse(data)){};
295+ : AsyncWebHeader(parse(data)) {};
192296
193297 AsyncWebHeader &operator =(const AsyncWebHeader &) = default ;
194298 AsyncWebHeader &operator =(AsyncWebHeader &&other) = default ;
@@ -265,7 +369,7 @@ class AsyncWebServerRequest {
265369 uint8_t _parseState;
266370
267371 uint8_t _version;
268- WebRequestMethodComposite _method;
372+ WebRequestMethod _method;
269373 String _url;
270374 String _host;
271375 String _contentType;
@@ -355,7 +459,7 @@ class AsyncWebServerRequest {
355459 uint8_t version () const {
356460 return _version;
357461 }
358- WebRequestMethodComposite method () const {
462+ WebRequestMethod method () const {
359463 return _method;
360464 }
361465 const String &url () const {
@@ -380,13 +484,14 @@ class AsyncWebServerRequest {
380484 RequestedConnectionType requestedConnType () const {
381485 return _reqconntype;
382486 }
383- bool isExpectedRequestedConnType (RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED)
384- const ;
487+ bool isExpectedRequestedConnType (
488+ RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED
489+ ) const ;
385490 bool isWebSocketUpgrade () const {
386- return _method == AsyncWebRequestMethod:: HTTP_GET && isExpectedRequestedConnType (RCT_WS);
491+ return _method == HTTP_GET && isExpectedRequestedConnType (RCT_WS);
387492 }
388493 bool isSSE () const {
389- return _method == AsyncWebRequestMethod:: HTTP_GET && isExpectedRequestedConnType (RCT_EVENT);
494+ return _method == HTTP_GET && isExpectedRequestedConnType (RCT_EVENT);
390495 }
391496 bool isHTTP () const {
392497 return isExpectedRequestedConnType (RCT_DEFAULT, RCT_HTTP);
@@ -574,7 +679,8 @@ class AsyncWebServerRequest {
574679 return beginResponse (code, contentType.c_str (), content, len, callback);
575680 }
576681#ifndef ESP8266
577- [[deprecated(" Replaced by beginResponse(int code, const String& contentType, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr)"
682+ [[deprecated(
683+ " Replaced by beginResponse(int code, const String& contentType, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr)"
578684 )]]
579685#endif
580686 AsyncWebServerResponse *beginResponse_P (int code, const String &contentType, PGM_P content, AwsTemplateProcessor callback = nullptr );
@@ -1556,7 +1662,7 @@ class AsyncWebServer : public AsyncMiddlewareChain {
15561662 bool removeHandler (AsyncWebHandler *handler);
15571663
15581664 AsyncCallbackWebHandler &on (AsyncURIMatcher uri, ArRequestHandlerFunction onRequest) {
1559- return on (std::move (uri), AsyncWebRequestMethod:: HTTP_ANY, onRequest);
1665+ return on (std::move (uri), HTTP_ANY, onRequest);
15601666 }
15611667 AsyncCallbackWebHandler &on (
15621668 AsyncURIMatcher uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload = nullptr ,
0 commit comments