@@ -95,8 +95,27 @@ impl Client {
9595 }
9696 }
9797
98+ /// Perform a blocking HTTP request using this client.
99+ /// Does not start an async executor.
100+ pub fn request_blocking ( & self , request : Request ) -> HttpResult < Response > {
101+ let handle = self . request_helper ( request) ?;
102+ handle. perform ( ) ?;
103+ Ok ( WorkerServer :: process_response ( handle) )
104+ }
105+
98106 /// Perform an HTTP request using this client.
99107 pub async fn request ( & self , request : Request ) -> HttpResult < Response > {
108+ let handle = self . request_helper ( request) ?;
109+ let ( sender, receiver) = oneshot:: channel ( ) ;
110+ let req = Message {
111+ easy : handle,
112+ sender,
113+ } ;
114+ self . channel . as_ref ( ) . unwrap ( ) . send ( req) . unwrap ( ) ;
115+ receiver. await . unwrap ( )
116+ }
117+
118+ fn request_helper ( & self , request : Request ) -> HttpResult < Easy2 < Collector > > {
100119 let url = request. uri ( ) . to_string ( ) ;
101120 debug ! ( target: "network::fetch" , url) ;
102121 let mut collector = Collector :: new ( self . stats . clone ( ) ) ;
@@ -141,14 +160,7 @@ impl Client {
141160 }
142161 handle. http_headers ( headers) ?;
143162
144- let ( sender, receiver) = oneshot:: channel ( ) ;
145- let req = Message {
146- easy : handle,
147- sender,
148- } ;
149-
150- self . channel . as_ref ( ) . unwrap ( ) . send ( req) . unwrap ( ) ;
151- receiver. await . unwrap ( )
163+ Ok ( handle)
152164 }
153165
154166 /// Returns the number pending bytes across all active transfers.
@@ -242,6 +254,24 @@ impl WorkerServer {
242254 }
243255 }
244256
257+ fn process_response ( mut easy : Easy2 < Collector > ) -> Response {
258+ let mut response =
259+ std:: mem:: replace ( & mut easy. get_mut ( ) . response , Response :: new ( Vec :: new ( ) ) ) ;
260+ if let Ok ( status) = easy. response_code ( )
261+ && status != 0
262+ && let Ok ( status) = http:: StatusCode :: from_u16 ( status as u16 )
263+ {
264+ * response. status_mut ( ) = status;
265+ }
266+ // Would be nice to set HTTP version via `response.version_mut()`, but `curl` doesn't have it exposed.
267+ let extensions = Extensions {
268+ client_ip : easy. primary_ip ( ) . ok ( ) . flatten ( ) . map ( str:: to_string) ,
269+ effective_url : easy. effective_url ( ) . ok ( ) . flatten ( ) . map ( str:: to_string) ,
270+ } ;
271+ response. extensions_mut ( ) . insert ( extensions) ;
272+ response
273+ }
274+
245275 /// Marks the start of a new timeout window.
246276 fn reset_low_speed_timeout ( & mut self ) {
247277 self . low_speed_window_start = Instant :: now ( ) ;
@@ -297,23 +327,8 @@ impl WorkerServer {
297327 return ;
298328 } ;
299329 let result = msg. result_for2 ( & handle) . expect ( "handle must have a result" ) ;
300- let mut easy = self . multi . remove2 ( handle) . expect ( "handle must be in multi" ) ;
301- let mut response = std:: mem:: replace (
302- & mut easy. get_mut ( ) . response ,
303- Response :: new ( Vec :: new ( ) ) ,
304- ) ;
305- if let Ok ( status) = easy. response_code ( )
306- && status != 0
307- && let Ok ( status) = http:: StatusCode :: from_u16 ( status as u16 )
308- {
309- * response. status_mut ( ) = status;
310- }
311- // Would be nice to set HTTP version via `response.version_mut()`, but `curl` doesn't have it exposed.
312- let extensions = Extensions {
313- client_ip : easy. primary_ip ( ) . ok ( ) . flatten ( ) . map ( str:: to_string) ,
314- effective_url : easy. effective_url ( ) . ok ( ) . flatten ( ) . map ( str:: to_string) ,
315- } ;
316- response. extensions_mut ( ) . insert ( extensions) ;
330+ let easy = self . multi . remove2 ( handle) . expect ( "handle must be in multi" ) ;
331+ let response = Self :: process_response ( easy) ;
317332 let _ = sender. send ( result. map ( |( ) | response) . map_err ( Into :: into) ) ;
318333 } ) ;
319334
0 commit comments