Drop sender to prevent async client read deadlock.

Fixes #1729.

Co-authored-by: Wesley Norris <repnop@outlook.com>
This commit is contained in:
Sergio Benitez 2021-06-25 09:27:36 -07:00
parent 0b2fcb9f4b
commit c3ee34e295
2 changed files with 28 additions and 1 deletions

View File

@ -167,8 +167,8 @@ impl LocalResponse<'_> {
});
loop {
let mut buf = Vec::with_capacity(1024);
// TODO: Try to fill as much as the buffer before send it off?
let mut buf = Vec::with_capacity(1024);
match self.read_buf(&mut buf).await {
Ok(n) if n == 0 => break,
Ok(_) => tx.send(Ok(buf)).await.ok()?,
@ -179,6 +179,9 @@ impl LocalResponse<'_> {
}
}
// NOTE: We _must_ drop tx now to prevent a deadlock!
drop(tx);
reader.await.ok()
}

View File

@ -0,0 +1,24 @@
#![cfg(feature = "json")]
#[macro_use] extern crate rocket;
use rocket::serde::json::Json;
#[get("/int")] fn int() -> Json<i32> { Json(5) }
#[get("/nil")] fn nil() -> Json<()> { Json(()) }
#[async_test]
async fn async_json_works() {
use rocket::local::asynchronous::Client;
let client = Client::debug_with(routes![int, nil]).await.unwrap();
let int0 = client.get("/int").dispatch().await.into_json::<u32>().await;
let int1 = client.get("/int").dispatch().await.into_json::<i32>().await;
assert_eq!(int0, Some(5));
assert_eq!(int1, Some(5));
let nil0 = client.get("/nil").dispatch().await.into_json::<()>().await;
assert_eq!(nil0, Some(()));
}