@@ -37,55 +37,72 @@ pub(crate) enum Body {
3737 /// Channel, on which transmission result will be written
3838 result_tx : oneshot:: Sender < Box < dyn Future < Output = Result < ( ) , ErrorCode > > + Send > > ,
3939 } ,
40- /// Body is consumed.
41- Consumed ,
40+ }
41+
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+ }
4267}
4368
4469impl Body {
4570 /// Implementation of `consume-body` shared between requests and responses
4671 pub ( crate ) fn consume < T > (
4772 self ,
4873 mut store : Access < ' _ , T , WasiHttp > ,
74+ fut : FutureReader < Result < ( ) , ErrorCode > > ,
4975 getter : fn ( & mut T ) -> WasiHttpCtxView < ' _ > ,
50- ) -> Result <
51- (
52- StreamReader < u8 > ,
53- FutureReader < Result < Option < Resource < Trailers > > , ErrorCode > > ,
54- ) ,
55- ( ) ,
56- > {
76+ ) -> (
77+ StreamReader < u8 > ,
78+ FutureReader < Result < Option < Resource < Trailers > > , ErrorCode > > ,
79+ ) {
5780 match self {
5881 Body :: Guest {
5982 contents_rx : Some ( contents_rx) ,
6083 trailers_rx,
6184 result_tx,
6285 } => {
63- // TODO: Use a result specified by the caller
64- // https://github.com/WebAssembly/wasi-http/issues/176
65- _ = result_tx. send ( Box :: new ( async { Ok ( ( ) ) } ) ) ;
66- Ok ( ( contents_rx, trailers_rx) )
86+ fut. pipe ( & mut store, BodyResultConsumer ( Some ( result_tx) ) ) ;
87+ ( contents_rx, trailers_rx)
6788 }
6889 Body :: Guest {
6990 contents_rx : None ,
7091 trailers_rx,
7192 result_tx,
7293 } => {
94+ fut. pipe ( & mut store, BodyResultConsumer ( Some ( result_tx) ) ) ;
7395 let instance = store. instance ( ) ;
74- // TODO: Use a result specified by the caller
75- // https://github.com/WebAssembly/wasi-http/issues/176
76- _ = result_tx. send ( Box :: new ( async { Ok ( ( ) ) } ) ) ;
77- Ok ( (
96+ (
7897 StreamReader :: new ( instance, & mut store, iter:: empty ( ) ) ,
7998 trailers_rx,
80- ) )
99+ )
81100 }
82101 Body :: Host { body, result_tx } => {
102+ fut. pipe ( & mut store, BodyResultConsumer ( Some ( result_tx) ) ) ;
83103 let instance = store. instance ( ) ;
84- // TODO: Use a result specified by the caller
85- // https://github.com/WebAssembly/wasi-http/issues/176
86- _ = result_tx. send ( Box :: new ( async { Ok ( ( ) ) } ) ) ;
87104 let ( trailers_tx, trailers_rx) = oneshot:: channel ( ) ;
88- Ok ( (
105+ (
89106 StreamReader :: new (
90107 instance,
91108 & mut store,
@@ -96,9 +113,8 @@ impl Body {
96113 } ,
97114 ) ,
98115 FutureReader :: new ( instance, & mut store, trailers_rx) ,
99- ) )
116+ )
100117 }
101- Body :: Consumed => Err ( ( ) ) ,
102118 }
103119 }
104120
@@ -390,31 +406,6 @@ impl http_body::Body for GuestBody {
390406 }
391407}
392408
393- /// [http_body::Body] that has been consumed.
394- pub ( crate ) struct ConsumedBody ;
395-
396- impl http_body:: Body for ConsumedBody {
397- type Data = Bytes ;
398- type Error = ErrorCode ;
399-
400- fn poll_frame (
401- self : Pin < & mut Self > ,
402- _cx : & mut Context < ' _ > ,
403- ) -> Poll < Option < Result < http_body:: Frame < Self :: Data > , Self :: Error > > > {
404- Poll :: Ready ( Some ( Err ( ErrorCode :: InternalError ( Some (
405- "body consumed" . into ( ) ,
406- ) ) ) ) )
407- }
408-
409- fn is_end_stream ( & self ) -> bool {
410- true
411- }
412-
413- fn size_hint ( & self ) -> http_body:: SizeHint {
414- http_body:: SizeHint :: with_exact ( 0 )
415- }
416- }
417-
418409/// [FutureConsumer] implementation for trailers originating in the guest.
419410struct GuestTrailerConsumer < T > {
420411 tx : Option < oneshot:: Sender < Result < Option < Arc < HeaderMap > > , ErrorCode > > > ,
@@ -434,10 +425,10 @@ where
434425 mut src : Source < ' _ , Self :: Item > ,
435426 _: bool ,
436427 ) -> Poll < wasmtime:: Result < ( ) > > {
437- let mut result = None ;
438- src. read ( store. as_context_mut ( ) , & mut result )
428+ let mut res = None ;
429+ src. read ( & mut store, & mut res )
439430 . context ( "failed to read result" ) ?;
440- let res = match result . context ( "result value missing" ) ? {
431+ let res = match res . context ( "result value missing" ) ? {
441432 Ok ( Some ( trailers) ) => {
442433 let WasiHttpCtxView { table, .. } = ( self . getter ) ( store. data_mut ( ) ) ;
443434 let trailers = table
0 commit comments