Skip to content

Commit 4246dec

Browse files
committed
Add HTTP QUERY method (RFC 10008)
Recognize QUERY in the request-line parser, expose HTTP_QUERY, and accept it on AsyncCallbackJsonWebHandler so safe, idempotent queries can carry a JSON body. Platform http_method mapping is gated until ESP-IDF/Arduino define HTTP_QUERY.
1 parent a52ca62 commit 4246dec

7 files changed

Lines changed: 44 additions & 1 deletion

File tree

docs/requests.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
```cpp
88
request->version(); // uint8_t: 0 = HTTP/1.0, 1 = HTTP/1.1
9-
request->method(); // enum: HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS
9+
request->method(); // enum: HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS, HTTP_QUERY
1010
request->url(); // String: URL of the request (not including host, port or GET parameters)
1111
request->host(); // String: The requested host (can be used for virtual hosting)
1212
request->contentType(); // String: ContentType of the request (not available in Handler::canHandle)

examples/arduino/HTTPMethodsWithArduino/HTTPMethodsWithArduino.ino

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ void setup() {
8787
request->send(200, "text/plain", "Hello");
8888
});
8989

90+
// HTTP_Method.h / http_parser.h is included above: use the namespaced bit, not HTTP_QUERY.
91+
// curl -v -X QUERY -H 'Content-Type: application/json' -d '{"q":1}' http://192.168.4.1/query
92+
server.on("/query", AsyncWebRequestMethod::HTTP_QUERY, [](AsyncWebServerRequest *request) {
93+
request->send(200, "text/plain", request->methodToString());
94+
});
95+
9096
#if ASYNC_JSON_SUPPORT == 1
9197
// curl -v http://192.168.4.1/test => Not Implemented
9298
// curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/test => OK
@@ -116,6 +122,10 @@ void setup() {
116122
assert(composite3 == composite4);
117123
assert(composite1 != composite3);
118124
assert(composite5 == AsyncWebRequestMethod::HTTP_GET);
125+
126+
WebRequestMethodComposite queryMethod = AsyncWebRequestMethod::HTTP_QUERY;
127+
assert(queryMethod.matches(AsyncWebRequestMethod::HTTP_QUERY));
128+
assert(!queryMethod.matches(AsyncWebRequestMethod::HTTP_GET));
119129
}
120130

121131
// not needed

examples/arduino/HTTPMethodsWithESPIDF/HTTPMethodsWithESPIDF.ino

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ void setup() {
9090
request->send(200, "text/plain", "Hello");
9191
});
9292

93+
// http_parser.h is included above: use the namespaced bit, not HTTP_QUERY (platform enum 33).
94+
// curl -v -X QUERY -H 'Content-Type: application/json' -d '{"q":1}' http://192.168.4.1/query
95+
server.on("/query", AsyncWebRequestMethod::HTTP_QUERY, [](AsyncWebServerRequest *request) {
96+
request->send(200, "text/plain", request->methodToString());
97+
});
98+
9399
#if ASYNC_JSON_SUPPORT == 1
94100
// curl -v http://192.168.4.1/test => Not Implemented
95101
// curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/test => OK
@@ -119,6 +125,10 @@ void setup() {
119125
assert(composite3 == composite4);
120126
assert(composite1 != composite3);
121127
assert(composite5 == AsyncWebRequestMethod::HTTP_GET);
128+
129+
WebRequestMethodComposite queryMethod = AsyncWebRequestMethod::HTTP_QUERY;
130+
assert(queryMethod.matches(AsyncWebRequestMethod::HTTP_QUERY));
131+
assert(!queryMethod.matches(AsyncWebRequestMethod::HTTP_GET));
122132
}
123133

124134
// not needed

examples/arduino/Json/Json.ino

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,20 @@ void setup() {
8787

8888
server.addHandler(handler);
8989

90+
// curl -v -X QUERY -H 'Content-Type: application/json' -d '{"q":1}' http://192.168.4.1/json-query
91+
AsyncCallbackJsonWebHandler *queryHandler = new AsyncCallbackJsonWebHandler("/json-query");
92+
queryHandler->setMethod(HTTP_QUERY);
93+
queryHandler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) {
94+
serializeJson(json, Serial);
95+
Serial.println();
96+
AsyncJsonResponse *response = new AsyncJsonResponse();
97+
JsonObject root = response->getRoot().to<JsonObject>();
98+
root["hello"] = json.as<JsonObject>()["q"];
99+
response->setLength();
100+
request->send(response);
101+
});
102+
server.addHandler(queryHandler);
103+
90104
// New Json API since 3.8.2, which works for both Json and MessagePack bodies
91105
// curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json3
92106

src/ESPAsyncWebServer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ enum AsyncWebRequestMethodType : uint32_t {
151151
HTTP_LINK = 1u << 22,
152152
HTTP_UNLINK = 1u << 23,
153153

154+
/* RFC 10008 */
155+
HTTP_QUERY = 1u << 24,
156+
154157
/* icecast */
155158
// HTTP_SOURCE
156159

src/WebRequest.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,8 @@ WebRequestMethod stringToMethod(const String &m) {
15441544
return AsyncWebRequestMethod::HTTP_UNBIND;
15451545
} else if (m == T_ACL) {
15461546
return AsyncWebRequestMethod::HTTP_ACL;
1547+
} else if (m == T_QUERY) {
1548+
return AsyncWebRequestMethod::HTTP_QUERY;
15471549
} else {
15481550
return AsyncWebRequestMethod::HTTP_INVALID;
15491551
}
@@ -1579,6 +1581,8 @@ const char *methodToString(WebRequestMethod method) {
15791581
/* RFC-2068, section 19.6.1.2 */
15801582
case AsyncWebRequestMethod::HTTP_LINK: return T_LINK;
15811583
case AsyncWebRequestMethod::HTTP_UNLINK: return T_UNLINK;
1584+
/* RFC 10008 */
1585+
case AsyncWebRequestMethod::HTTP_QUERY: return T_QUERY;
15821586
// Unsupported
15831587
default: return T_UNKNOWN;
15841588
}

src/literals.h

Lines changed: 2 additions & 0 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";
@@ -137,6 +138,7 @@ static constexpr const char T_ACL[] = "ACL";
137138
static constexpr const char T_PURGE[] = "PURGE";
138139
static constexpr const char T_LINK[] = "LINK";
139140
static constexpr const char T_UNLINK[] = "UNLINK";
141+
static constexpr const char T_QUERY[] = "QUERY";
140142

141143
// Req content types
142144
static constexpr const char T_RCT_HTTP[] = "RCT_HTTP";

0 commit comments

Comments
 (0)