Skip to content

HTTP Method matching is incorrect on RP2040 / RP2350 #398

@sonodima

Description

@sonodima

Platform

RP2040

IDE / Tooling

PlatformIO

What happened?

On RP2040 and RP2350 targets using earlephilhower/arduino-pico, route handlers registered for a specific HTTP method (e.g. HTTP_GET) are incorrectly triggered by other methods (e.g. HTTP_POST). This is because WebRequestMethod is mapped to http_method, which is not a bitmask.

Package Versions:

Package Version
ESPAsyncWebServer 3.10.0
RPAsyncTCP 1.3.2
PlatformIO 3.3.4
Pico SDK 2.2.1-develop
Arduino Pico 5.5.1

In ESPAsyncWebServer.h, WebRequestMethod is aliased to http_method:

#if defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
typedef enum http_method WebRequestMethod;

The http_method enum comes from the http_parser library bundled with arduino-pico and uses sequential integer values:

/* Request Methods */
#define HTTP_METHOD_MAP(XX)         \
  XX(0,  DELETE,      DELETE)       \
  XX(1,  GET,         GET)          \
  XX(2,  HEAD,        HEAD)         \
  XX(3,  POST,        POST)         \
  XX(4,  PUT,         PUT)          \
  /* pathological */                \
  XX(5,  CONNECT,     CONNECT)      \
  XX(6,  OPTIONS,     OPTIONS)      \
  XX(7,  TRACE,       TRACE)        \
  /* WebDAV */                      \
  XX(8,  COPY,        COPY)         \
  XX(9,  LOCK,        LOCK)         \
  XX(10, MKCOL,       MKCOL)        \
  XX(11, MOVE,        MOVE)         \
  XX(12, PROPFIND,    PROPFIND)     \
  XX(13, PROPPATCH,   PROPPATCH)    \
  XX(14, SEARCH,      SEARCH)       \
  XX(15, UNLOCK,      UNLOCK)       \
  XX(16, BIND,        BIND)         \
  XX(17, REBIND,      REBIND)       \
  XX(18, UNBIND,      UNBIND)       \
  XX(19, ACL,         ACL)          \
  /* subversion */                  \
  XX(20, REPORT,      REPORT)       \
  XX(21, MKACTIVITY,  MKACTIVITY)   \
  XX(22, CHECKOUT,    CHECKOUT)     \
  XX(23, MERGE,       MERGE)        \
  /* upnp */                        \
  XX(24, MSEARCH,     M-SEARCH)     \
  XX(25, NOTIFY,      NOTIFY)       \
  XX(26, SUBSCRIBE,   SUBSCRIBE)    \
  XX(27, UNSUBSCRIBE, UNSUBSCRIBE)  \
  /* RFC-5789 */                    \
  XX(28, PATCH,       PATCH)        \
  XX(29, PURGE,       PURGE)        \
  /* CalDAV */                      \
  XX(30, MKCALENDAR,  MKCALENDAR)   \
  /* RFC-2068, section 19.6.1.2 */  \
  XX(31, LINK,        LINK)         \
  XX(32, UNLINK,      UNLINK)       \
  /* icecast */                     \
  XX(33, SOURCE,      SOURCE)       \

enum http_method
  {
#define XX(num, name, string) HTTP_##name = num,
  HTTP_METHOD_MAP(XX)
#undef XX
  };

In this library (and e.g. for the ESP32 target) method checks work via bitwise AND, so with sequential enum values, these checks produce false positives:

HTTP_POST (3) & HTTP_GET (1) == 1

Stack Trace

There is no crash, but the handlers are registered incorrectly.

Minimal Reproductible Example (MRE)

Register a route handler restricted to HTTP_GET:

webServer.on("/ping", HTTP_GET, [](AsyncWebServerRequest* request) {
  request->send(200, "text/plain", "pong");
});

Send a POST request to /ping. The handler fires, even though it should not.

I confirm that:

  • I have read the documentation.
  • I have searched for similar discussions.
  • I have searched for similar issues.
  • I have looked at the examples.
  • I have upgraded to the lasted version of ESPAsyncWebServer (and AsyncTCP for ESP32).

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions