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

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions