mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-09-30 20:52:31 +07:00
Send 100 Continue only when the request body is read
The server wrote 100 Continue as soon as it saw the expectation, before pre_routing_handler, pre_request_handler, or routing ran. A request those handlers rejected, or one that matched no route, still invited the client to send a body the server would never read. Defer the interim response until the body is about to be read. If the request is answered without reading the body, 100 Continue is never sent and the connection is closed, since whether and when the client sends the body is unknown. Also treat a 417 returned by expect_100_continue_handler as the final response. It used to be written as a bare status line, after which the request was processed and a second response was written.
This commit is contained in:
@@ -564,14 +564,15 @@ svr.set_pre_request_handler([](const auto& req, auto& res) {
|
||||
|
||||
```
|
||||
Request received
|
||||
│
|
||||
├─ expect_100_continue_handler (when the request has "Expect: 100-continue")
|
||||
│ └─ returns a status other than 100 → stop here
|
||||
│
|
||||
├─ pre_routing_handler route not matched yet, body not read
|
||||
│ └─ returns Handled → stop here
|
||||
│
|
||||
├─ file_request_handler (GET/HEAD, static file serving)
|
||||
│
|
||||
├─ expect_100_continue_handler (when the request has "Expect: 100-continue")
|
||||
│
|
||||
├─ route matching → req.matched_route is set
|
||||
│
|
||||
├─ pre_request_handler route matched, body NOT read yet
|
||||
@@ -587,6 +588,8 @@ Request received
|
||||
|
||||
Use `pre_routing_handler` to reject a request as early as possible, before the route is known. Use `pre_request_handler` for route-specific checks, since `req.matched_route` is available and the body has not been read yet.
|
||||
|
||||
For a request with `Expect: 100-continue`, the `100 Continue` response is not sent until the body is about to be read. A request rejected before that point (by `pre_routing_handler`, `pre_request_handler`, or because no route matched) gets its final response without `100 Continue`, so the client never sends the body.
|
||||
|
||||
A WebSocket upgrade request that matches a route registered with `svr.WebSocket()` takes a shorter path: `pre_routing_handler`, then route matching (`req.matched_route` is set), then `pre_request_handler`, then the WebSocket handler. If either hook returns `Handled`, its response is sent as a regular HTTP response and the connection is not upgraded. Once the connection is upgraded, `post_routing_handler` does not run.
|
||||
|
||||
### Response user data
|
||||
@@ -848,7 +851,9 @@ svr.Get("/content", [&](const Request &req, Response &res) {
|
||||
|
||||
### 'Expect: 100-continue' handler
|
||||
|
||||
By default, the server sends a `100 Continue` response for an `Expect: 100-continue` header.
|
||||
By default, the server accepts an `Expect: 100-continue` header and sends a `100 Continue` response when it starts reading the request body. If the request is answered without reading the body, `100 Continue` is not sent and the connection is closed after the response.
|
||||
|
||||
The handler runs before `pre_routing_handler`. Returning `100` lets the request proceed; returning any other status sends that status as the final response and closes the connection.
|
||||
|
||||
```cpp
|
||||
// Send a '417 Expectation Failed' response.
|
||||
|
||||
Reference in New Issue
Block a user