1414
1515use proxy_wasm:: callout:: http:: HttpClient ;
1616use proxy_wasm:: callout:: promise:: Promise ;
17- use proxy_wasm:: hostcalls;
1817use proxy_wasm:: traits:: * ;
1918use proxy_wasm:: types:: * ;
19+ use std:: cell:: RefCell ;
20+ use std:: rc:: Rc ;
2021use std:: time:: Duration ;
2122
2223proxy_wasm:: main! { {
2324 proxy_wasm:: set_log_level( LogLevel :: Trace ) ;
2425 proxy_wasm:: set_http_context( |_, _| -> Box <dyn HttpContext > { Box :: new( HttpParallelCall :: default ( ) ) } ) ;
2526} }
2627
27- #[ derive( Default ) ]
28+ #[ derive( Default , Clone ) ]
2829struct HttpParallelCall {
29- client : HttpClient ,
30+ client : Rc < RefCell < HttpClient > > ,
3031}
3132
3233impl HttpContext for HttpParallelCall {
3334 fn on_http_request_headers ( & mut self , _: usize , _: bool ) -> Action {
35+ let self_clone_for_promise1 = self . clone ( ) ;
36+ let self_clone_for_promise2 = self . clone ( ) ;
37+ let self_clone_for_join = self . clone ( ) ;
38+
3439 // "Hello, "
3540 let promise1 = self
3641 . client
42+ . borrow_mut ( )
3743 . dispatch (
3844 "httpbin" ,
3945 vec ! [
@@ -45,12 +51,17 @@ impl HttpContext for HttpParallelCall {
4551 vec ! [ ] ,
4652 Duration :: from_secs ( 1 ) ,
4753 )
48- . then ( |( _, _, body_size, _) | get_http_call_response_body_string ( 0 , body_size) )
49- . then ( |body| body. unwrap_or_default ( ) ) ;
54+ . then ( move |( _, _, body_size, _) | {
55+ match self_clone_for_promise1. get_http_call_response_body ( 0 , body_size) {
56+ None => "" . to_owned ( ) ,
57+ Some ( bytes) => String :: from_utf8 ( bytes. to_vec ( ) ) . unwrap ( ) ,
58+ }
59+ } ) ;
5060
5161 // "World!"
5262 let promise2 = self
5363 . client
64+ . borrow_mut ( )
5465 . dispatch (
5566 "httpbin" ,
5667 vec ! [
@@ -62,11 +73,15 @@ impl HttpContext for HttpParallelCall {
6273 vec ! [ ] ,
6374 Duration :: from_secs ( 1 ) ,
6475 )
65- . then ( |( _, _, body_size, _) | get_http_call_response_body_string ( 0 , body_size) )
66- . then ( |body| body. unwrap_or_default ( ) ) ;
76+ . then ( move |( _, _, body_size, _) | {
77+ match self_clone_for_promise2. get_http_call_response_body ( 0 , body_size) {
78+ None => "" . to_owned ( ) ,
79+ Some ( bytes) => String :: from_utf8 ( bytes. to_vec ( ) ) . unwrap ( ) ,
80+ }
81+ } ) ;
6782
68- Promise :: all_of ( vec ! [ promise1, promise2] ) . then ( |results| {
69- send_http_response (
83+ Promise :: all_of ( vec ! [ promise1, promise2] ) . then ( move |results| {
84+ self_clone_for_join . send_http_response (
7085 200 ,
7186 vec ! [ ] ,
7287 Some ( format ! ( "{}{}\n " , results[ 0 ] , results[ 1 ] ) . as_bytes ( ) ) ,
@@ -91,20 +106,7 @@ impl Context for HttpParallelCall {
91106 num_trailers : usize ,
92107 ) {
93108 self . client
109+ . borrow_mut ( )
94110 . callback ( token_id, num_headers, body_size, num_trailers)
95111 }
96112}
97-
98- fn get_http_call_response_body_string ( start : usize , max_size : usize ) -> Option < String > {
99- match hostcalls:: get_buffer ( BufferType :: HttpCallResponseBody , start, max_size) . unwrap ( ) {
100- None => None ,
101- Some ( bytes) => {
102- let body_string = String :: from_utf8 ( bytes. to_vec ( ) ) . unwrap ( ) ;
103- Some ( body_string)
104- }
105- }
106- }
107-
108- fn send_http_response ( status_code : u32 , headers : Vec < ( & str , & str ) > , body : Option < & [ u8 ] > ) {
109- hostcalls:: send_http_response ( status_code, headers, body) . unwrap ( )
110- }
0 commit comments