@@ -5,7 +5,6 @@ use super::{Body, HttpClient, Request, Response};
5
5
use async_std:: io:: BufReader ;
6
6
use futures:: future:: BoxFuture ;
7
7
use isahc:: http;
8
-
9
8
use std:: sync:: Arc ;
10
9
11
10
/// Curl-based HTTP Client.
@@ -45,25 +44,83 @@ impl Clone for IsahcClient {
45
44
impl HttpClient for IsahcClient {
46
45
type Error = isahc:: Error ;
47
46
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 > > {
49
48
let client = self . client . clone ( ) ;
50
49
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
+
53
62
let body = match body. len ( ) {
54
63
Some ( len) => isahc:: Body :: from_reader_sized ( body, len as u64 ) ,
55
64
None => isahc:: Body :: from_reader ( body) ,
56
65
} ;
57
- let req: http:: Request < isahc:: Body > = http:: Request :: from_parts ( parts, body) ;
58
-
59
- let res = client. send_async ( req) . await ?;
60
66
67
+ let request = builder. body ( body) . unwrap ( ) ;
68
+ let res = client. send_async ( request) . await ?;
61
69
let ( parts, body) = res. into_parts ( ) ;
62
-
63
70
let len = body. len ( ) . map ( |len| len as usize ) ;
64
71
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)
67
78
} )
68
79
}
69
80
}
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 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