@@ -6,7 +6,12 @@ use ethers_middleware::gas_oracle::{GasCategory, GasOracle, Polygon};
66use ethers_providers:: { is_local_endpoint, Middleware , Provider , DEFAULT_LOCAL_POLL_INTERVAL } ;
77use eyre:: WrapErr ;
88use reqwest:: { IntoUrl , Url } ;
9- use std:: { borrow:: Cow , env, path:: Path , time:: Duration } ;
9+ use std:: {
10+ borrow:: Cow ,
11+ env,
12+ path:: { Path , PathBuf } ,
13+ time:: Duration ,
14+ } ;
1015use url:: ParseError ;
1116
1217/// Helper type alias for a retry provider
@@ -68,31 +73,23 @@ impl ProviderBuilder {
6873 }
6974
7075 let url = Url :: parse ( url_str)
71- . or_else ( |err| {
72- match err {
73- ParseError :: RelativeUrlWithoutBase => {
74- let path = Path :: new ( url_str) ;
75- let absolute_path = if path. is_absolute ( ) {
76- path. to_path_buf ( )
77- } else {
78- // Assume the path is relative to the current directory.
79- // Don't use `std::fs::canonicalize` as it requires the path to exist.
80- // It should be possible to construct a provider and only
81- // attempt to establish a connection later
82- let current_dir =
83- env:: current_dir ( ) . expect ( "Current directory should exist" ) ;
84- current_dir. join ( path)
85- } ;
86-
87- let path_str =
88- absolute_path. to_str ( ) . expect ( "Path should be a valid string" ) ;
89-
90- // invalid url: non-prefixed URL scheme is not allowed, so we assume the URL
91- // is for a local file
92- Url :: parse ( format ! ( "file://{path_str}" ) . as_str ( ) )
76+ . or_else ( |err| match err {
77+ ParseError :: RelativeUrlWithoutBase => {
78+ let path = Path :: new ( url_str) ;
79+
80+ if let Ok ( path) = resolve_path ( path) {
81+ Url :: parse (
82+ format ! (
83+ "file://{path_str}" ,
84+ path_str = path. to_str( ) . expect( "Should be valid string" )
85+ )
86+ . as_str ( ) ,
87+ )
88+ } else {
89+ Err ( err)
9390 }
94- _ => Err ( err) ,
9591 }
92+ _ => Err ( err) ,
9693 } )
9794 . wrap_err ( format ! ( "Invalid provider url: {url_str}" ) ) ;
9895
@@ -280,6 +277,28 @@ where
280277 provider. estimate_eip1559_fees ( None ) . await . wrap_err ( "Failed fetch EIP1559 fees" )
281278}
282279
280+ #[ cfg( not( windows) ) ]
281+ fn resolve_path ( path : & Path ) -> Result < PathBuf , ( ) > {
282+ if path. is_absolute ( ) {
283+ Ok ( path. to_path_buf ( ) )
284+ } else {
285+ Ok ( env:: current_dir ( )
286+ . map ( |current_dir| current_dir. join ( path) )
287+ . expect ( "Current directory should exist" ) )
288+ }
289+ }
290+
291+ #[ cfg( windows) ]
292+ fn resolve_path ( path : & Path ) -> Result < PathBuf , ( ) > {
293+ let path_str = path. to_str ( ) . expect ( "Path should be a valid string" ) ;
294+
295+ if path_str. starts_with ( r"\\.\pipe\" ) {
296+ Ok ( PathBuf :: from ( path_str) )
297+ } else {
298+ Err ( ( ) )
299+ }
300+ }
301+
283302#[ cfg( test) ]
284303mod tests {
285304 use super :: * ;
0 commit comments