@@ -5,7 +5,6 @@ use super::{Body, HttpClient, Request, Response};
55use async_std:: io:: BufReader ;
66use futures:: future:: BoxFuture ;
77use isahc:: http;
8-
98use std:: sync:: Arc ;
109
1110/// Curl-based HTTP Client.
@@ -45,25 +44,83 @@ impl Clone for IsahcClient {
4544impl HttpClient for IsahcClient {
4645 type Error = isahc:: Error ;
4746
48- fn send ( & self , req : Request ) -> BoxFuture < ' static , Result < Response , Self :: Error > > {
47+ fn send ( & self , mut req : Request ) -> BoxFuture < ' static , Result < Response , Self :: Error > > {
4948 let client = self . client . clone ( ) ;
5049 Box :: pin ( async move {
51- let req_hyperium: http:: Request < http_types:: Body > = req. into ( ) ;
52- let ( parts, body) = req_hyperium. into_parts ( ) ;
50+ let mut builder = http:: Request :: builder ( )
51+ . uri ( req. url ( ) . as_str ( ) )
52+ . method ( http:: Method :: from_bytes ( req. method ( ) . to_string ( ) . as_bytes ( ) ) . unwrap ( ) ) ;
53+
54+ for name in req. header_names ( ) {
55+ if let Some ( value) = req. header ( name) {
56+ builder = builder. header ( name. as_str ( ) , value. as_str ( ) ) ;
57+ }
58+ }
59+
60+ let body = req. take_body ( ) ;
61+
5362 let body = match body. len ( ) {
5463 Some ( len) => isahc:: Body :: from_reader_sized ( body, len as u64 ) ,
5564 None => isahc:: Body :: from_reader ( body) ,
5665 } ;
57- let req: http:: Request < isahc:: Body > = http:: Request :: from_parts ( parts, body) ;
58-
59- let res = client. send_async ( req) . await ?;
6066
67+ let request = builder. body ( body) . unwrap ( ) ;
68+ let res = client. send_async ( request) . await ?;
6169 let ( parts, body) = res. into_parts ( ) ;
62-
6370 let len = body. len ( ) . map ( |len| len as usize ) ;
6471 let body = Body :: from_reader ( BufReader :: new ( body) , len) ;
65- let res = http:: Response :: from_parts ( parts, body) ;
66- Ok ( res. into ( ) )
72+ let mut response = http_types:: Response :: new ( parts. status . as_u16 ( ) ) ;
73+ for ( name, value) in & parts. headers {
74+ response. insert_header ( name. as_str ( ) , value. to_str ( ) . unwrap ( ) ) ;
75+ }
76+ response. set_body ( body) ;
77+ Ok ( response)
6778 } )
6879 }
6980}
81+
82+ #[ cfg( test) ]
83+ mod tests {
84+ use super :: * ;
85+ use async_std:: prelude:: * ;
86+ use async_std:: task;
87+ use http_types:: url:: Url ;
88+ use http_types:: Result ;
89+ use std:: time:: Duration ;
90+
91+ fn build_test_request ( url : Url ) -> Request {
92+ let mut req = Request :: new ( http_types:: Method :: Post , url) ;
93+ req. set_body ( "hello" ) ;
94+ req. append_header ( "test" , "value" ) ;
95+ req
96+ }
97+
98+ #[ async_std:: test]
99+ async fn basic_functionality ( ) -> Result < ( ) > {
100+ let port = portpicker:: pick_unused_port ( ) . unwrap ( ) ;
101+ let mut app = tide:: new ( ) ;
102+ app. at ( "/" ) . all ( |mut r : tide:: Request < ( ) > | async move {
103+ let mut response = tide:: Response :: new ( http_types:: StatusCode :: Ok ) ;
104+ response. set_body ( r. body_bytes ( ) . await . unwrap ( ) ) ;
105+ Ok ( response)
106+ } ) ;
107+
108+ let server = task:: spawn ( async move {
109+ app. listen ( ( "localhost" , port) ) . await ?;
110+ Result :: Ok ( ( ) )
111+ } ) ;
112+
113+ let client = task:: spawn ( async move {
114+ task:: sleep ( Duration :: from_millis ( 100 ) ) . await ;
115+ let request =
116+ build_test_request ( Url :: parse ( & format ! ( "http://localhost:{}/" , port) ) . unwrap ( ) ) ;
117+ let mut response: Response = IsahcClient :: new ( ) . send ( request) . await ?;
118+ assert_eq ! ( response. body_string( ) . await . unwrap( ) , "hello" ) ;
119+ Ok ( ( ) )
120+ } ) ;
121+
122+ server. race ( client) . await ?;
123+
124+ Ok ( ( ) )
125+ }
126+ }
0 commit comments