11use crate :: FieldMap ;
22use crate :: p3:: bindings:: http:: types:: { ErrorCode , Trailers } ;
3+ use crate :: p3:: helpers:: FutureReaderExt ;
34use crate :: p3:: { WasiHttp , WasiHttpCtxView } ;
45use bytes:: Bytes ;
56use core:: iter;
@@ -13,8 +14,8 @@ use std::sync::Arc;
1314use tokio:: sync:: { mpsc, oneshot} ;
1415use tokio_util:: sync:: PollSender ;
1516use wasmtime:: component:: {
16- Access , Destination , FutureConsumer , FutureReader , Resource , Source , StreamConsumer ,
17- StreamProducer , StreamReader , StreamResult ,
17+ Access , Destination , FutureReader , Resource , Source , StreamConsumer , StreamProducer ,
18+ StreamReader , StreamResult ,
1819} ;
1920use wasmtime:: error:: Context as _;
2021use wasmtime:: { AsContextMut , StoreContextMut } ;
@@ -39,33 +40,6 @@ pub(crate) enum Body {
3940 } ,
4041}
4142
42- /// [FutureConsumer] implementation for future passed to `consume-body`.
43- struct BodyResultConsumer (
44- Option < oneshot:: Sender < Box < dyn Future < Output = Result < ( ) , ErrorCode > > + Send > > > ,
45- ) ;
46-
47- impl < D > FutureConsumer < D > for BodyResultConsumer
48- where
49- D : ' static ,
50- {
51- type Item = Result < ( ) , ErrorCode > ;
52-
53- fn poll_consume (
54- mut self : Pin < & mut Self > ,
55- _: & mut Context < ' _ > ,
56- store : StoreContextMut < D > ,
57- mut src : Source < ' _ , Self :: Item > ,
58- _: bool ,
59- ) -> Poll < wasmtime:: Result < ( ) > > {
60- let mut res = None ;
61- src. read ( store, & mut res) . context ( "failed to read result" ) ?;
62- let res = res. context ( "result value missing" ) ?;
63- let tx = self . 0 . take ( ) . context ( "polled after returning `Ready`" ) ?;
64- _ = tx. send ( Box :: new ( async { res } ) ) ;
65- Poll :: Ready ( Ok ( ( ) ) )
66- }
67- }
68-
6943impl Body {
7044 /// Implementation of `consume-body` shared between requests and responses
7145 pub ( crate ) fn consume < T > (
@@ -77,25 +51,22 @@ impl Body {
7751 StreamReader < u8 > ,
7852 FutureReader < Result < Option < Resource < Trailers > > , ErrorCode > > ,
7953 ) > {
80- Ok ( match self {
54+ let ( contents_rx , trailers_rx , result_tx ) = match self {
8155 Body :: Guest {
8256 contents_rx : Some ( contents_rx) ,
8357 trailers_rx,
8458 result_tx,
85- } => {
86- fut. pipe ( & mut store, BodyResultConsumer ( Some ( result_tx) ) ) ?;
87- ( contents_rx, trailers_rx)
88- }
59+ } => ( contents_rx, trailers_rx, result_tx) ,
8960 Body :: Guest {
9061 contents_rx : None ,
9162 trailers_rx,
9263 result_tx,
93- } => {
94- fut. pipe ( & mut store, BodyResultConsumer ( Some ( result_tx) ) ) ?;
95- ( StreamReader :: new ( & mut store, iter:: empty ( ) ) ?, trailers_rx)
96- }
64+ } => (
65+ StreamReader :: new ( & mut store, iter:: empty ( ) ) ?,
66+ trailers_rx,
67+ result_tx,
68+ ) ,
9769 Body :: Host { body, result_tx } => {
98- fut. pipe ( & mut store, BodyResultConsumer ( Some ( result_tx) ) ) ?;
9970 let ( trailers_tx, trailers_rx) = oneshot:: channel ( ) ;
10071 (
10172 StreamReader :: new (
@@ -107,9 +78,16 @@ impl Body {
10778 } ,
10879 ) ?,
10980 FutureReader :: new ( & mut store, trailers_rx) ?,
81+ result_tx,
11082 )
11183 }
112- } )
84+ } ;
85+
86+ fut. pipe_cb ( & mut store, |_, res| {
87+ _ = result_tx. send ( Box :: new ( async { res } ) ) ;
88+ Ok ( ( ) )
89+ } ) ?;
90+ Ok ( ( contents_rx, trailers_rx) )
11391 }
11492
11593 /// Implementation of `drop` shared between requests and responses
@@ -275,13 +253,21 @@ impl GuestBody {
275253 getter : fn ( & mut T ) -> WasiHttpCtxView < ' _ > ,
276254 ) -> wasmtime:: Result < Self > {
277255 let ( trailers_http_tx, trailers_http_rx) = oneshot:: channel ( ) ;
278- trailers_rx. pipe (
279- & mut store,
280- GuestTrailerConsumer {
281- tx : Some ( trailers_http_tx) ,
282- getter,
283- } ,
284- ) ?;
256+ trailers_rx. pipe_cb ( & mut store, move |data, res| {
257+ let res = match res {
258+ Ok ( Some ( trailers) ) => {
259+ let WasiHttpCtxView { table, .. } = getter ( data) ;
260+ let trailers = table
261+ . delete ( trailers)
262+ . context ( "failed to delete trailers" ) ?;
263+ Ok ( Some ( Arc :: from ( trailers) ) )
264+ }
265+ Ok ( None ) => Ok ( None ) ,
266+ Err ( err) => Err ( err) ,
267+ } ;
268+ _ = trailers_http_tx. send ( res) ;
269+ Ok ( ( ) )
270+ } ) ?;
285271
286272 let contents_rx = if let Some ( rx) = contents_rx {
287273 let ( http_tx, http_rx) = mpsc:: channel ( 1 ) ;
@@ -401,44 +387,6 @@ impl http_body::Body for GuestBody {
401387 }
402388}
403389
404- /// [FutureConsumer] implementation for trailers originating in the guest.
405- struct GuestTrailerConsumer < T > {
406- tx : Option < oneshot:: Sender < Result < Option < Arc < FieldMap > > , ErrorCode > > > ,
407- getter : fn ( & mut T ) -> WasiHttpCtxView < ' _ > ,
408- }
409-
410- impl < D > FutureConsumer < D > for GuestTrailerConsumer < D >
411- where
412- D : ' static ,
413- {
414- type Item = Result < Option < Resource < Trailers > > , ErrorCode > ;
415-
416- fn poll_consume (
417- mut self : Pin < & mut Self > ,
418- _: & mut Context < ' _ > ,
419- mut store : StoreContextMut < D > ,
420- mut src : Source < ' _ , Self :: Item > ,
421- _: bool ,
422- ) -> Poll < wasmtime:: Result < ( ) > > {
423- let mut res = None ;
424- src. read ( & mut store, & mut res)
425- . context ( "failed to read result" ) ?;
426- let res = match res. context ( "result value missing" ) ? {
427- Ok ( Some ( trailers) ) => {
428- let WasiHttpCtxView { table, .. } = ( self . getter ) ( store. data_mut ( ) ) ;
429- let trailers = table
430- . delete ( trailers)
431- . context ( "failed to delete trailers" ) ?;
432- Ok ( Some ( Arc :: from ( trailers) ) )
433- }
434- Ok ( None ) => Ok ( None ) ,
435- Err ( err) => Err ( err) ,
436- } ;
437- _ = self . tx . take ( ) . unwrap ( ) . send ( res) ;
438- Poll :: Ready ( Ok ( ( ) ) )
439- }
440- }
441-
442390/// [StreamProducer] implementation for bodies originating in the host.
443391pub ( crate ) struct HostBodyStreamProducer < T > {
444392 pub ( crate ) body : UnsyncBoxBody < Bytes , ErrorCode > ,
0 commit comments