actix-web/actix-http
asonix af30b7e679 actix-http: h1: stop pipelining when not reading full requests
The existing pipelining behavior of the h1 dispatcher can cause client timeouts
if the entire request body isn't read. It puts the dispatcher into a state where
it refuses to read more (payload dropped) but there are still bytes in the buffer
from the request body.

This solution adds the SHUTDOWN flag in addition to the FINISHED flag
when completing a response when both the following are true:

1. There are no messages in `this.messages`
2. There is still a payload in `this.payload`

This combination implies two things. First, that we have not parsed a
pipelined request after the request we have just responded to. Second,
that the current request payload has not been fed an EOF. Because there
are no pipelined requests, we know that the current request payload
belongs to the request we have just responded to, and because the
request payload has not been fed an EOF, we know we never finished
reading it.

When this occurs, adding the SHUTDOWN flag to the dispatcher triggers a
`flush` and a `poll_shutdown` on the IO resource on the next poll.
2025-08-07 18:01:06 -05:00
..
benches perf: remove unnecessary allocation when writing http dates (#3261) 2024-02-07 03:47:30 +00:00
examples chore: address clippy lints 2025-05-09 20:21:02 +01:00
src actix-http: h1: stop pipelining when not reading full requests 2025-08-07 18:01:06 -05:00
tests build(deps): update derive_more requirement from 1 to 2 (#3571) 2025-02-10 01:27:56 +00:00
CHANGES.md chore(actix-http): prepare release 3.11.0 2025-05-10 06:18:25 +01:00
Cargo.toml chore(actix-http): prepare release 3.11.0 2025-05-10 06:18:25 +01:00
LICENSE-APACHE prepare release beta 4 (#1659) 2020-09-09 22:14:11 +01:00
LICENSE-MIT prepare release beta 4 (#1659) 2020-09-09 22:14:11 +01:00
README.md chore(actix-http): prepare release 3.11.0 2025-05-10 06:18:25 +01:00

README.md

actix-http

HTTP types and services for the Actix ecosystem.

crates.io Documentation Version MIT or Apache 2.0 licensed
dependency status Download Chat on Discord

Examples

use std::{env, io};

use actix_http::{HttpService, Response};
use actix_server::Server;
use futures_util::future;
use http::header::HeaderValue;
use tracing::info;

#[actix_rt::main]
async fn main() -> io::Result<()> {
    env::set_var("RUST_LOG", "hello_world=info");
    env_logger::init();

    Server::build()
        .bind("hello-world", "127.0.0.1:8080", || {
            HttpService::build()
                .client_timeout(1000)
                .client_disconnect(1000)
                .finish(|_req| {
                    info!("{:?}", _req);
                    let mut res = Response::Ok();
                    res.header("x-head", HeaderValue::from_static("dummy value!"));
                    future::ok::<_, ()>(res.body("Hello world!"))
                })
                .tcp()
        })?
        .run()
        .await
}