Skip to content

Commit ee60e0f

Browse files
committed
fix(p3-http): close stream handles on drop
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
1 parent 8c7ab86 commit ee60e0f

File tree

5 files changed

+42
-21
lines changed

5 files changed

+42
-21
lines changed

crates/test-programs/src/bin/p3_http_outbound_request_response_build.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,9 @@ impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
2525
request
2626
.set_authority(Some("www.example.com"))
2727
.expect("setting authority");
28-
let (remaining, ()) =
29-
futures::join!(contents_tx.write_all(b"request-body".to_vec()), async {
30-
drop(request);
31-
},);
32-
assert!(!remaining.is_empty());
28+
drop(request);
29+
let remaining = contents_tx.write_all(b"request-body".to_vec()).await;
30+
assert_eq!(String::from_utf8_lossy(&remaining), "request-body");
3331
}
3432
{
3533
let headers = Headers::from_list(&[(

crates/wasi-http/src/p3/bindings.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ mod generated {
77
world: "wasi:http/proxy",
88
imports: {
99
"wasi:http/handler/[async]handle": async | store | trappable | tracing,
10+
"wasi:http/types/[drop]request": store | trappable | tracing,
11+
"wasi:http/types/[drop]response": store | trappable | tracing,
1012
"wasi:http/types/[method]request.consume-body": async | store | trappable | tracing,
1113
"wasi:http/types/[method]response.consume-body": async | store | trappable | tracing,
1214
"wasi:http/types/[static]request.new": async | store | trappable | tracing,

crates/wasi-http/src/p3/body.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,22 @@ pub(crate) enum Body {
3636
Consumed,
3737
}
3838

39+
impl Body {
40+
pub(crate) fn drop(self, mut store: impl AsContextMut) {
41+
if let Body::Guest {
42+
contents_rx,
43+
mut trailers_rx,
44+
..
45+
} = self
46+
{
47+
if let Some(mut contents_rx) = contents_rx {
48+
contents_rx.close(&mut store);
49+
}
50+
trailers_rx.close(store);
51+
}
52+
}
53+
}
54+
3955
pub(crate) enum GuestBodyKind {
4056
Request,
4157
Response,

crates/wasi-http/src/p3/host/types.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ use http_body_util::combinators::BoxBody;
1919
use std::io::Cursor;
2020
use std::sync::Arc;
2121
use tokio::sync::oneshot;
22-
use wasmtime::StoreContextMut;
2322
use wasmtime::component::{
2423
Accessor, Destination, FutureProducer, FutureReader, Resource, ResourceTable, StreamProducer,
2524
StreamReader, StreamResult,
2625
};
26+
use wasmtime::{StoreContextMut, component::Access};
2727
use wasmtime_wasi::p3::{FutureOneshotProducer, StreamEmptyProducer};
2828

2929
fn get_fields<'a>(
@@ -481,6 +481,16 @@ impl HostRequestWithStore for WasiHttp {
481481
}
482482
})
483483
}
484+
485+
fn drop<T>(mut store: Access<'_, T, Self>, req: Resource<Request>) -> wasmtime::Result<()> {
486+
let Request { body, .. } = store
487+
.get()
488+
.table
489+
.delete(req)
490+
.context("failed to delete request from table")?;
491+
body.drop(store);
492+
Ok(())
493+
}
484494
}
485495

486496
impl HostRequest for WasiHttpCtxView<'_> {
@@ -594,13 +604,6 @@ impl HostRequest for WasiHttpCtxView<'_> {
594604
let Request { headers, .. } = get_request(self.table, &req)?;
595605
push_fields(self.table, Fields::new_immutable(Arc::clone(headers)))
596606
}
597-
598-
fn drop(&mut self, req: Resource<Request>) -> wasmtime::Result<()> {
599-
self.table
600-
.delete(req)
601-
.context("failed to delete request from table")?;
602-
Ok(())
603-
}
604607
}
605608

606609
impl HostRequestOptions for WasiHttpCtxView<'_> {
@@ -799,6 +802,16 @@ impl HostResponseWithStore for WasiHttp {
799802
}
800803
})
801804
}
805+
806+
fn drop<T>(mut store: Access<'_, T, Self>, res: Resource<Response>) -> wasmtime::Result<()> {
807+
let Response { body, .. } = store
808+
.get()
809+
.table
810+
.delete(res)
811+
.context("failed to delete response from table")?;
812+
body.drop(store);
813+
Ok(())
814+
}
802815
}
803816

804817
impl HostResponse for WasiHttpCtxView<'_> {
@@ -824,13 +837,6 @@ impl HostResponse for WasiHttpCtxView<'_> {
824837
let Response { headers, .. } = get_response(self.table, &res)?;
825838
push_fields(self.table, Fields::new_immutable(Arc::clone(headers)))
826839
}
827-
828-
fn drop(&mut self, res: Resource<Response>) -> wasmtime::Result<()> {
829-
self.table
830-
.delete(res)
831-
.context("failed to delete response from table")?;
832-
Ok(())
833-
}
834840
}
835841

836842
impl Host for WasiHttpCtxView<'_> {

crates/wasi-http/tests/all/p3/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ async fn p3_http_outbound_request_invalid_dnsname() -> anyhow::Result<()> {
216216
run_cli(P3_HTTP_OUTBOUND_REQUEST_INVALID_DNSNAME_COMPONENT, &server).await
217217
}
218218

219-
#[ignore = "unimplemented"] // TODO: implement
220219
#[test_log::test(tokio::test(flavor = "multi_thread"))]
221220
async fn p3_http_outbound_request_response_build() -> anyhow::Result<()> {
222221
let server = Server::http1(1)?;

0 commit comments

Comments
 (0)