@@ -19,24 +19,33 @@ compile_error!(
1919#[ derive( thiserror:: Error , Debug ) ]
2020pub enum Error {
2121 #[ error( "{0} doesn't have an valid host" ) ]
22- InvalidHost ( Uri ) ,
22+ InvalidHost ( Box < Uri > ) ,
2323 #[ error( transparent) ]
2424 IoError ( #[ from] std:: io:: Error ) ,
2525 #[ error( transparent) ]
2626 HyperError ( #[ from] hyper:: Error ) ,
2727 #[ error( "Failed to connect to {0}, {1}" ) ]
28- ConnectError ( Uri , hyper:: Error ) ,
28+ ConnectError ( Box < Uri > , hyper:: Error ) ,
2929
3030 #[ cfg( feature = "native-tls-client" ) ]
3131 #[ error( "Failed to connect with TLS to {0}, {1}" ) ]
32- TlsConnectError ( Uri , native_tls:: Error ) ,
32+ TlsConnectError ( Box < Uri > , native_tls:: Error ) ,
3333 #[ cfg( feature = "native-tls-client" ) ]
3434 #[ error( transparent) ]
3535 NativeTlsError ( #[ from] tokio_native_tls:: native_tls:: Error ) ,
3636
3737 #[ cfg( feature = "rustls-client" ) ]
3838 #[ error( "Failed to connect with TLS to {0}, {1}" ) ]
39- TlsConnectError ( Uri , std:: io:: Error ) ,
39+ TlsConnectError ( Box < Uri > , std:: io:: Error ) ,
40+
41+ #[ error( "Failed to parse URI: {0}" ) ]
42+ UriParsingError ( #[ from] hyper:: http:: uri:: InvalidUri ) ,
43+
44+ #[ error( "Failed to parse URI parts: {0}" ) ]
45+ UriPartsError ( #[ from] hyper:: http:: uri:: InvalidUriParts ) ,
46+
47+ #[ error( "TLS connector initialization failed: {0}" ) ]
48+ TlsConnectorError ( String ) ,
4049}
4150
4251/// Upgraded connections
@@ -72,21 +81,39 @@ impl Default for DefaultClient {
7281impl DefaultClient {
7382 #[ cfg( feature = "native-tls-client" ) ]
7483 pub fn new ( ) -> Self {
75- let tls_connector_no_alpn = native_tls:: TlsConnector :: builder ( ) . build ( ) . unwrap ( ) ;
84+ Self :: try_new ( ) . unwrap_or_else ( |err| {
85+ panic ! ( "Failed to create DefaultClient: {}" , err) ;
86+ } )
87+ }
88+
89+ #[ cfg( feature = "native-tls-client" ) ]
90+ pub fn try_new ( ) -> Result < Self , Error > {
91+ let tls_connector_no_alpn = native_tls:: TlsConnector :: builder ( ) . build ( ) . map_err ( |e| {
92+ Error :: TlsConnectorError ( format ! ( "Failed to build no-ALPN connector: {}" , e) )
93+ } ) ?;
7694 let tls_connector_alpn_h2 = native_tls:: TlsConnector :: builder ( )
7795 . request_alpns ( & [ "h2" , "http/1.1" ] )
7896 . build ( )
79- . unwrap ( ) ;
97+ . map_err ( |e| {
98+ Error :: TlsConnectorError ( format ! ( "Failed to build ALPN-H2 connector: {}" , e) )
99+ } ) ?;
80100
81- Self {
101+ Ok ( Self {
82102 tls_connector_no_alpn : tokio_native_tls:: TlsConnector :: from ( tls_connector_no_alpn) ,
83103 tls_connector_alpn_h2 : tokio_native_tls:: TlsConnector :: from ( tls_connector_alpn_h2) ,
84104 with_upgrades : false ,
85- }
105+ } )
86106 }
87107
88108 #[ cfg( feature = "rustls-client" ) ]
89109 pub fn new ( ) -> Self {
110+ Self :: try_new ( ) . unwrap_or_else ( |err| {
111+ panic ! ( "Failed to create DefaultClient: {}" , err) ;
112+ } )
113+ }
114+
115+ #[ cfg( feature = "rustls-client" ) ]
116+ pub fn try_new ( ) -> Result < Self , Error > {
90117 use std:: sync:: Arc ;
91118
92119 let mut root_cert_store = tokio_rustls:: rustls:: RootCertStore :: empty ( ) ;
@@ -100,15 +127,15 @@ impl DefaultClient {
100127 . with_no_client_auth ( ) ;
101128 tls_connector_alpn_h2. alpn_protocols = vec ! [ b"h2" . to_vec( ) , b"http/1.1" . to_vec( ) ] ;
102129
103- Self {
130+ Ok ( Self {
104131 tls_connector_no_alpn : tokio_rustls:: TlsConnector :: from ( Arc :: new (
105132 tls_connector_no_alpn,
106133 ) ) ,
107134 tls_connector_alpn_h2 : tokio_rustls:: TlsConnector :: from ( Arc :: new (
108135 tls_connector_alpn_h2,
109136 ) ) ,
110137 with_upgrades : false ,
111- }
138+ } )
112139 }
113140
114141 /// Enable HTTP upgrades
@@ -204,7 +231,9 @@ impl DefaultClient {
204231 B :: Data : Send ,
205232 B :: Error : Into < Box < dyn std:: error:: Error + Send + Sync > > ,
206233 {
207- let host = uri. host ( ) . ok_or_else ( || Error :: InvalidHost ( uri. clone ( ) ) ) ?;
234+ let host = uri
235+ . host ( )
236+ . ok_or_else ( || Error :: InvalidHost ( Box :: new ( uri. clone ( ) ) ) ) ?;
208237 let port =
209238 uri. port_u16 ( )
210239 . unwrap_or ( if uri. scheme ( ) == Some ( & hyper:: http:: uri:: Scheme :: HTTPS ) {
@@ -223,18 +252,18 @@ impl DefaultClient {
223252 . tls_connector ( http_version)
224253 . connect ( host, tcp)
225254 . await
226- . map_err ( |err| Error :: TlsConnectError ( uri. clone ( ) , err) ) ?;
255+ . map_err ( |err| Error :: TlsConnectError ( Box :: new ( uri. clone ( ) ) , err) ) ?;
227256 #[ cfg( feature = "rustls-client" ) ]
228257 let tls = self
229258 . tls_connector ( http_version)
230259 . connect (
231260 host. to_string ( )
232261 . try_into ( )
233- . map_err ( |_| Error :: InvalidHost ( uri. clone ( ) ) ) ?,
262+ . map_err ( |_| Error :: InvalidHost ( Box :: new ( uri. clone ( ) ) ) ) ?,
234263 tcp,
235264 )
236265 . await
237- . map_err ( |err| Error :: TlsConnectError ( uri. clone ( ) , err) ) ?;
266+ . map_err ( |err| Error :: TlsConnectError ( Box :: new ( uri. clone ( ) ) , err) ) ?;
238267
239268 #[ cfg( feature = "native-tls-client" ) ]
240269 let is_h2 = matches ! (
@@ -251,7 +280,7 @@ impl DefaultClient {
251280 let ( sender, conn) = client:: conn:: http2:: Builder :: new ( TokioExecutor :: new ( ) )
252281 . handshake ( TokioIo :: new ( tls) )
253282 . await
254- . map_err ( |err| Error :: ConnectError ( uri. clone ( ) , err) ) ?;
283+ . map_err ( |err| Error :: ConnectError ( Box :: new ( uri. clone ( ) ) , err) ) ?;
255284
256285 tokio:: spawn ( conn) ;
257286
@@ -262,7 +291,7 @@ impl DefaultClient {
262291 . title_case_headers ( true )
263292 . handshake ( TokioIo :: new ( tls) )
264293 . await
265- . map_err ( |err| Error :: ConnectError ( uri. clone ( ) , err) ) ?;
294+ . map_err ( |err| Error :: ConnectError ( Box :: new ( uri. clone ( ) ) , err) ) ?;
266295
267296 tokio:: spawn ( conn. with_upgrades ( ) ) ;
268297
@@ -274,7 +303,7 @@ impl DefaultClient {
274303 . title_case_headers ( true )
275304 . handshake ( TokioIo :: new ( tcp) )
276305 . await
277- . map_err ( |err| Error :: ConnectError ( uri. clone ( ) , err) ) ?;
306+ . map_err ( |err| Error :: ConnectError ( Box :: new ( uri. clone ( ) ) , err) ) ?;
278307 tokio:: spawn ( conn. with_upgrades ( ) ) ;
279308 Ok ( SendRequest :: Http1 ( sender) )
280309 }
@@ -312,7 +341,10 @@ where
312341 }
313342 }
314343 }
315- remove_authority ( & mut req) ;
344+ if let Err ( err) = remove_authority ( & mut req) {
345+ tracing:: error!( "Failed to remove authority from URI: {}" , err) ;
346+ // Continue with the original request if URI modification fails
347+ }
316348 sender. send_request ( req) . await
317349 }
318350 SendRequest :: Http2 ( sender) => {
@@ -336,9 +368,10 @@ impl<B> SendRequest<B> {
336368 }
337369}
338370
339- fn remove_authority < B > ( req : & mut Request < B > ) {
371+ fn remove_authority < B > ( req : & mut Request < B > ) -> Result < ( ) , hyper :: http :: uri :: InvalidUriParts > {
340372 let mut parts = req. uri ( ) . clone ( ) . into_parts ( ) ;
341373 parts. scheme = None ;
342374 parts. authority = None ;
343- * req. uri_mut ( ) = Uri :: from_parts ( parts) . unwrap ( ) ;
375+ * req. uri_mut ( ) = Uri :: from_parts ( parts) ?;
376+ Ok ( ( ) )
344377}
0 commit comments