Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/proto/h1/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1349,7 +1349,8 @@ impl Client {
};

// HTTP/1.0 doesn't know about chunked
let can_chunked = head.version == Version::HTTP_11;
// HTTP/2 requests are serialized as HTTP/1.1.
let can_chunked = matches!(head.version, Version::HTTP_11 | Version::HTTP_2);
let headers = &mut head.headers;

// If the user already set specific headers, we should respect them, regardless
Expand Down
44 changes: 44 additions & 0 deletions tests/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,50 @@ mod conn {
rt.block_on(future::join(res, rx).map(|r| r.0)).unwrap();
}

#[tokio::test]
async fn http1_conn_coerces_http2_streaming_request() {
tokio::time::timeout(Duration::from_secs(5), async {
let (client_io, server_io) = tokio::io::duplex(1024);
let svc = hyper::service::service_fn(|req: Request<hyper::body::Incoming>| async {
assert_eq!(req.method(), Method::POST);
assert_eq!(req.version(), hyper::Version::HTTP_11);
let chunked = req.headers().get("transfer-encoding").cloned();
let body = concat(req).await?;
assert_eq!(body, "hello world");
assert_eq!(chunked.as_ref().unwrap(), "chunked");
Ok::<_, hyper::Error>(Response::new(Full::new(body)))
});
let server = tokio::spawn(
hyper::server::conn::http1::Builder::new()
.serve_connection(TokioIo::new(server_io), svc),
);

let (mut client, connection) = conn::http1::handshake(TokioIo::new(client_io))
.await
.unwrap();
let connection = tokio::spawn(connection);
let body = StreamBody::new(futures_util::stream::iter([
Ok::<_, std::convert::Infallible>(Frame::data(Bytes::from_static(b"hello"))),
Ok(Frame::data(Bytes::from_static(b" world"))),
]));
assert_eq!(body.size_hint().exact(), None);
let req = Request::post("/a")
.version(hyper::Version::HTTP_2)
.body(body)
.unwrap();

let response = client.send_request(req).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
assert_eq!(concat(response).await.unwrap(), "hello world");

drop(client);
connection.await.unwrap().unwrap();
server.await.unwrap().unwrap();
})
.await
.expect("coerced request body should reach the server");
}

#[test]
fn pipeline() {
let (server, addr) = setup_std_test_server();
Expand Down
Loading