11use crate :: wit:: wasi:: http0_2_0:: outgoing_handler;
22use crate :: wit:: wasi:: http0_2_0:: types:: {
3- ErrorCode , IncomingBody , IncomingResponse , OutgoingBody , OutgoingRequest ,
3+ ErrorCode , FutureIncomingResponse , IncomingBody , IncomingResponse , OutgoingBody ,
4+ OutgoingRequest ,
45} ;
56
67use spin_executor:: bindings:: wasi:: io;
78use spin_executor:: bindings:: wasi:: io:: streams:: { InputStream , OutputStream , StreamError } ;
89
910use futures:: { future, sink, stream, Sink , Stream } ;
1011
11- pub use spin_executor:: run;
12+ pub use spin_executor:: { run, CancelOnDropToken } ;
1213
1314use std:: cell:: RefCell ;
1415use std:: future:: Future ;
@@ -18,37 +19,46 @@ use std::task::Poll;
1819const READ_SIZE : u64 = 16 * 1024 ;
1920
2021pub ( crate ) fn outgoing_body ( body : OutgoingBody ) -> impl Sink < Vec < u8 > , Error = StreamError > {
21- struct Outgoing ( Option < ( OutputStream , OutgoingBody ) > ) ;
22+ struct Outgoing {
23+ stream_and_body : Option < ( OutputStream , OutgoingBody ) > ,
24+ cancel_token : Option < CancelOnDropToken > ,
25+ }
2226
2327 impl Drop for Outgoing {
2428 fn drop ( & mut self ) {
25- if let Some ( ( stream, body) ) = self . 0 . take ( ) {
29+ drop ( self . cancel_token . take ( ) ) ;
30+
31+ if let Some ( ( stream, body) ) = self . stream_and_body . take ( ) {
2632 drop ( stream) ;
2733 _ = OutgoingBody :: finish ( body, None ) ;
2834 }
2935 }
3036 }
3137
3238 let stream = body. write ( ) . expect ( "response body should be writable" ) ;
33- let pair = Rc :: new ( RefCell :: new ( Outgoing ( Some ( ( stream, body) ) ) ) ) ;
39+ let outgoing = Rc :: new ( RefCell :: new ( Outgoing {
40+ stream_and_body : Some ( ( stream, body) ) ,
41+ cancel_token : None ,
42+ } ) ) ;
3443
3544 sink:: unfold ( ( ) , {
3645 move |( ) , chunk : Vec < u8 > | {
3746 future:: poll_fn ( {
3847 let mut offset = 0 ;
3948 let mut flushing = false ;
40- let pair = pair . clone ( ) ;
49+ let outgoing = outgoing . clone ( ) ;
4150
4251 move |context| {
43- let pair = pair . borrow ( ) ;
44- let ( stream, _) = & pair . 0 . as_ref ( ) . unwrap ( ) ;
52+ let mut outgoing = outgoing . borrow_mut ( ) ;
53+ let ( stream, _) = & outgoing . stream_and_body . as_ref ( ) . unwrap ( ) ;
4554 loop {
4655 match stream. check_write ( ) {
4756 Ok ( 0 ) => {
48- spin_executor:: push_waker (
49- stream. subscribe ( ) ,
50- context. waker ( ) . clone ( ) ,
51- ) ;
57+ outgoing. cancel_token =
58+ Some ( CancelOnDropToken :: from ( spin_executor:: push_waker (
59+ stream. subscribe ( ) ,
60+ context. waker ( ) . clone ( ) ,
61+ ) ) ) ;
5262 break Poll :: Pending ;
5363 }
5464 Ok ( count) => {
@@ -93,14 +103,33 @@ pub(crate) fn outgoing_body(body: OutgoingBody) -> impl Sink<Vec<u8>, Error = St
93103pub ( crate ) fn outgoing_request_send (
94104 request : OutgoingRequest ,
95105) -> impl Future < Output = Result < IncomingResponse , ErrorCode > > {
106+ struct State {
107+ response : Option < Result < FutureIncomingResponse , ErrorCode > > ,
108+ cancel_token : Option < CancelOnDropToken > ,
109+ }
110+
111+ impl Drop for State {
112+ fn drop ( & mut self ) {
113+ drop ( self . cancel_token . take ( ) ) ;
114+ drop ( self . response . take ( ) ) ;
115+ }
116+ }
117+
96118 let response = outgoing_handler:: handle ( request, None ) ;
119+ let mut state = State {
120+ response : Some ( response) ,
121+ cancel_token : None ,
122+ } ;
97123 future:: poll_fn ( {
98- move |context| match & response {
124+ move |context| match & state . response . as_ref ( ) . unwrap ( ) {
99125 Ok ( response) => {
100126 if let Some ( response) = response. get ( ) {
101127 Poll :: Ready ( response. unwrap ( ) )
102128 } else {
103- spin_executor:: push_waker ( response. subscribe ( ) , context. waker ( ) . clone ( ) ) ;
129+ state. cancel_token = Some ( CancelOnDropToken :: from ( spin_executor:: push_waker (
130+ response. subscribe ( ) ,
131+ context. waker ( ) . clone ( ) ,
132+ ) ) ) ;
104133 Poll :: Pending
105134 }
106135 }
@@ -113,11 +142,16 @@ pub(crate) fn outgoing_request_send(
113142pub fn incoming_body (
114143 body : IncomingBody ,
115144) -> impl Stream < Item = Result < Vec < u8 > , io:: streams:: Error > > {
116- struct Incoming ( Option < ( InputStream , IncomingBody ) > ) ;
145+ struct Incoming {
146+ stream_and_body : Option < ( InputStream , IncomingBody ) > ,
147+ cancel_token : Option < CancelOnDropToken > ,
148+ }
117149
118150 impl Drop for Incoming {
119151 fn drop ( & mut self ) {
120- if let Some ( ( stream, body) ) = self . 0 . take ( ) {
152+ drop ( self . cancel_token . take ( ) ) ;
153+
154+ if let Some ( ( stream, body) ) = self . stream_and_body . take ( ) {
121155 drop ( stream) ;
122156 IncomingBody :: finish ( body) ;
123157 }
@@ -126,14 +160,21 @@ pub fn incoming_body(
126160
127161 stream:: poll_fn ( {
128162 let stream = body. stream ( ) . expect ( "response body should be readable" ) ;
129- let pair = Incoming ( Some ( ( stream, body) ) ) ;
163+ let mut incoming = Incoming {
164+ stream_and_body : Some ( ( stream, body) ) ,
165+ cancel_token : None ,
166+ } ;
130167
131168 move |context| {
132- if let Some ( ( stream, _) ) = & pair . 0 {
169+ if let Some ( ( stream, _) ) = & incoming . stream_and_body {
133170 match stream. read ( READ_SIZE ) {
134171 Ok ( buffer) => {
135172 if buffer. is_empty ( ) {
136- spin_executor:: push_waker ( stream. subscribe ( ) , context. waker ( ) . clone ( ) ) ;
173+ incoming. cancel_token =
174+ Some ( CancelOnDropToken :: from ( spin_executor:: push_waker (
175+ stream. subscribe ( ) ,
176+ context. waker ( ) . clone ( ) ,
177+ ) ) ) ;
137178 Poll :: Pending
138179 } else {
139180 Poll :: Ready ( Some ( Ok ( buffer) ) )
0 commit comments