Skip to content

Commit 43e996b

Browse files
committed
Tighten QUERY: opt-in JsonHandler, HTTP_PARSER_HAS_QUERY mapping
Do not enable QUERY on AsyncCallbackJsonWebHandler by default. Map the platform http_method enumerator only when HTTP_PARSER_HAS_QUERY is defined (enum members are not preprocessor macros). Add Accept-Query and a Json example curl.
1 parent 7e9a7b2 commit 43e996b

5 files changed

Lines changed: 16 additions & 9 deletions

File tree

docs/requests.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@ request->contentLength(); // size_t: ContentLength of the request (not availabl
1414
request->multipart(); // bool: True if the request has content type "multipart"
1515
```
1616

17-
`HTTP_QUERY` is [RFC 10008](https://www.rfc-editor.org/rfc/rfc10008.html): a safe, idempotent method that carries the query in the request body (same body path as POST/PUT/PATCH whenever `Content-Length` or chunked transfer is present). `AsyncCallbackJsonWebHandler` accepts QUERY with `Content-Type: application/json`. Unknown methods still abort the connection.
17+
`HTTP_QUERY` is [RFC 10008](https://www.rfc-editor.org/rfc/rfc10008.html): a safe, idempotent method that carries the query in the request body (same body path as POST/PUT/PATCH whenever `Content-Length` or chunked transfer is present). Unknown methods still abort the connection.
18+
19+
`AsyncCallbackJsonWebHandler` does **not** enable QUERY by default. Call `setMethod(HTTP_QUERY)` (alone or combined with POST/PUT). QUERY still requires `Content-Type: application/json` (or MessagePack). Advertise supported query media types with `Accept-Query` (`asyncsrv::T_Accept_Query`), e.g. `application/json`.
20+
21+
Platform `http_method` mapping is compiled in only when the platform parser defines `HTTP_PARSER_HAS_QUERY` (ESP-IDF after QUERY support). The library parser always recognizes `QUERY`.
1822

1923
Register it like any other verb:
2024

2125
```cpp
2226
server.on("/search", HTTP_QUERY, [](AsyncWebServerRequest *request) {
23-
request->send(200, "text/plain", "ok");
27+
AsyncWebServerResponse *res = request->beginResponse(200, "text/plain", "ok");
28+
res->addHeader("Accept-Query", "application/json");
29+
request->send(res);
2430
});
2531

2632
auto *json = new AsyncCallbackJsonWebHandler("/search", [](AsyncWebServerRequest *request, JsonVariant &json) {

examples/arduino/Json/Json.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ void setup() {
6363

6464
// curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json2
6565
// curl -v -X PUT -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json2
66+
// curl -v -X QUERY -H 'Content-Type: application/json' -d '{"q":"You"}' http://192.168.4.1/json2
6667
//
6768
// edge cases:
6869
//
@@ -74,7 +75,7 @@ void setup() {
7475
// curl -v -X POST -H "Content-Type: application/json" -d "123456789" -H "Content-Length: 8" http://192.168.4.1/json2 => 12345678
7576
// curl -v -X POST -H "Content-Type: application/json" -d "123456789" -H "Content-Length: 9" http://192.168.4.1/json2 => 413: Content length exceeds maximum allowed
7677
handler->setMaxContentLength(8);
77-
handler->setMethod(HTTP_POST | HTTP_PUT);
78+
handler->setMethod(HTTP_POST | HTTP_PUT | HTTP_QUERY);
7879
handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) {
7980
serializeJson(json, Serial);
8081
Serial.println();

src/AsyncJson.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ size_t AsyncMessagePackResponse::_fillBuffer(uint8_t *data, size_t len) {
113113

114114
// Body handler supporting both content types: JSON and MessagePack
115115
constexpr static WebRequestMethodComposite JsonHandlerMethods =
116-
AsyncWebRequestMethod::HTTP_GET | AsyncWebRequestMethod::HTTP_POST | AsyncWebRequestMethod::HTTP_PUT | AsyncWebRequestMethod::HTTP_PATCH
117-
| AsyncWebRequestMethod::HTTP_QUERY;
116+
AsyncWebRequestMethod::HTTP_GET | AsyncWebRequestMethod::HTTP_POST | AsyncWebRequestMethod::HTTP_PUT | AsyncWebRequestMethod::HTTP_PATCH;
118117

119118
#if ARDUINOJSON_VERSION_MAJOR == 6
120119
AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(AsyncURIMatcher uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize)

src/ESPAsyncWebServer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class WebRequestMethodComposite {
230230
: MAP_EXTERNAL_TERNARY(HTTP_PURGE)
231231
: MAP_EXTERNAL_TERNARY(HTTP_LINK)
232232
: MAP_EXTERNAL_TERNARY(HTTP_UNLINK)
233-
#if defined(HTTP_QUERY)
233+
#if defined(HTTP_PARSER_HAS_QUERY)
234234
: MAP_EXTERNAL_TERNARY(HTTP_QUERY)
235235
#endif
236236
#if defined(HTTP_ANY)

src/literals.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static constexpr const char T__opaque[] = "\", opaque=\"";
3636
static constexpr const char T_100_CONTINUE[] = "100-continue";
3737
static constexpr const char T_13[] = "13";
3838
static constexpr const char T_ACCEPT[] = "Accept";
39+
static constexpr const char T_Accept_Query[] = "Accept-Query";
3940
static constexpr const char T_Accept_Ranges[] = "Accept-Ranges";
4041
static constexpr const char T_attachment[] = "attachment; filename=\"";
4142
static constexpr const char T_AUTH[] = "Authorization";
@@ -244,9 +245,9 @@ DECLARE_STR(T_HTTP_CODE_507, "Insufficient Storage");
244245
DECLARE_STR(T_HTTP_CODE_ANY, "Unknown code");
245246

246247
static constexpr const char *T_only_once_headers[] = {
247-
T_Accept_Ranges, T_Content_Length, T_Content_Type, T_Connection, T_CORS_ACAC, T_CORS_ACAH, T_CORS_ACAM, T_CORS_ACAO,
248-
T_CORS_ACMA, T_CORS_O, T_Date, T_DIGEST, T_ETag, T_Last_Modified, T_LOCATION, T_retry_after,
249-
T_Transfer_Encoding, T_Content_Location, T_Server, T_WWW_AUTH
248+
T_Accept_Ranges, T_Accept_Query, T_Content_Length, T_Content_Type, T_Connection, T_CORS_ACAC, T_CORS_ACAH, T_CORS_ACAM,
249+
T_CORS_ACAO, T_CORS_ACMA, T_CORS_O, T_Date, T_DIGEST, T_ETag, T_Last_Modified, T_LOCATION,
250+
T_retry_after, T_Transfer_Encoding, T_Content_Location, T_Server, T_WWW_AUTH
250251
};
251252
static constexpr size_t T_only_once_headers_len = sizeof(T_only_once_headers) / sizeof(T_only_once_headers[0]);
252253
static constexpr size_t T__GZ_LEN = sizeof(T__gz) - 1;

0 commit comments

Comments
 (0)