hyperium / hyperium/hyper

Streaming request recv hang if client interrupted

Open
#3,291 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug
Dominant language
Rust
Stars
16.3k
Forks
1.8k
Avg merge
1d 22h
Merged PRs (30d)
14

Description

Version
v0.14.27

Platform
Linux demo 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Tested on several other linux platforms(ubuntu, debian, etc), same issue occurred.

Description

I tried this code: add a stream request handler in the echo example as below.

diff --git a/examples/echo.rs b/examples/echo.rs
index ff757304..6fa05793 100644
--- a/examples/echo.rs
+++ b/examples/echo.rs
@@ -4,10 +4,25 @@ use futures_util::TryStreamExt;
 use hyper::service::{make_service_fn, service_fn};
 use hyper::{Body, Method, Request, Response, Server, StatusCode};

+use futures_util:: StreamExt;
+
 /// This is our service handler. It receives a Request, routes on its
 /// path, and returns a Future of a Response.
 async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
     match (req.method(), req.uri().path()) {
+
+        // Serve streaming body
+        (&Method::POST, "/stream") => {
+
+            let mut payload = req.into_body();
+            while let Some(item) = payload.next().await {
+                let item = item?;
+                println!("payload len: {}", item.len());
+            }
+            println!("stream body finished");
+            Ok(Response::default())
+        }
+

then run it

$ cargo run --example echo --features=full
Compiling hyper v0.14.27 (/home/workspace/hyper)
    Finished dev [unoptimized + debuginfo] target(s) in 3.22s
     Running `target/debug/examples/echo`
Listening on http://127.0.0.1:3000

Open another terminal, and test against the server by curl:

curl -v -X POST --data-binary @"YOUR_TEST_FILE" --limit-rate 1M http://127.0.0.1:3000/stream

I expected to see this happen:

Normally logs like below will output by the echo server if curl finished correctly(transfer succeed), which is expected.

...
payload len: 65536
payload len: 65536
payload len: 17317
stream body finished

However, if curl was interruptted by CTRL + C, the stream body finished won't be printed and the session seems hang forever on the server side.

...
payload len: 65536
payload len: 65536
==> hang here

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the streaming handler shown in examples/echo.rs and reproduce the request with the provided curl command, then interrupt the upload with Ctrl+C. Investigate why the body stream does not finish after client interruption; done means the server no longer hangs and the interrupted stream is handled correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.