1- use std:: sync:: Arc ;
1+ use std:: sync:: { Arc , LazyLock } ;
22
33use http:: { Extensions , StatusCode } ;
44use url:: Url ;
@@ -16,11 +16,38 @@ use tracing::{debug, trace, warn};
1616
1717/// Strategy for loading netrc files.
1818enum NetrcMode {
19- Automatic ,
20- Enabled ( netrc :: Netrc ) ,
19+ Automatic ( LazyLock < Option < Netrc > > ) ,
20+ Enabled ( Netrc ) ,
2121 Disabled ,
2222}
2323
24+ impl Default for NetrcMode {
25+ fn default ( ) -> Self {
26+ NetrcMode :: Automatic ( LazyLock :: new ( || match Netrc :: new ( ) {
27+ Ok ( netrc) => Some ( netrc) ,
28+ Err ( netrc:: Error :: Io ( err) ) if err. kind ( ) == std:: io:: ErrorKind :: NotFound => {
29+ debug ! ( "No netrc file found" ) ;
30+ None
31+ }
32+ Err ( err) => {
33+ warn ! ( "Error reading netrc file: {err}" ) ;
34+ None
35+ }
36+ } ) )
37+ }
38+ }
39+
40+ impl NetrcMode {
41+ /// Get the parsed netrc file if enabled.
42+ fn get ( & self ) -> Option < & Netrc > {
43+ match self {
44+ NetrcMode :: Automatic ( lock) => lock. as_ref ( ) ,
45+ NetrcMode :: Enabled ( netrc) => Some ( netrc) ,
46+ NetrcMode :: Disabled => None ,
47+ }
48+ }
49+ }
50+
2451/// A middleware that adds basic authentication to requests.
2552///
2653/// Uses a cache to propagate credentials from previously seen requests and
@@ -37,7 +64,7 @@ pub struct AuthMiddleware {
3764impl AuthMiddleware {
3865 pub fn new ( ) -> Self {
3966 Self {
40- netrc : NetrcMode :: Automatic ,
67+ netrc : NetrcMode :: default ( ) ,
4168 keyring : None ,
4269 cache : None ,
4370 only_authenticated : false ,
@@ -372,39 +399,16 @@ impl AuthMiddleware {
372399 }
373400
374401 // Netrc support based on: <https://github.com/gribouille/netrc>.
375- let credentials = if let Some ( credentials) = match self . netrc {
376- NetrcMode :: Enabled ( ref netrc) => {
377- debug ! ( "Checking netrc for credentials for {url}" ) ;
378- Credentials :: from_netrc (
379- netrc,
380- url,
381- credentials
382- . as_ref ( )
383- . and_then ( |credentials| credentials. username ( ) ) ,
384- )
385- }
386- NetrcMode :: Automatic => match Netrc :: new ( ) {
387- Ok ( netrc) => {
388- debug ! ( "Checking netrc for credentials for {url}" ) ;
389- Credentials :: from_netrc (
390- & netrc,
391- url,
392- credentials
393- . as_ref ( )
394- . and_then ( |credentials| credentials. username ( ) ) ,
395- )
396- }
397- Err ( netrc:: Error :: Io ( err) ) if err. kind ( ) == std:: io:: ErrorKind :: NotFound => {
398- debug ! ( "No netrc file found" ) ;
399- None
400- }
401- Err ( err) => {
402- warn ! ( "Error reading netrc file: {err}" ) ;
403- None
404- }
405- } ,
406- NetrcMode :: Disabled => None ,
407- } {
402+ let credentials = if let Some ( credentials) = self . netrc . get ( ) . and_then ( |netrc| {
403+ debug ! ( "Checking netrc for credentials for {url}" ) ;
404+ Credentials :: from_netrc (
405+ netrc,
406+ url,
407+ credentials
408+ . as_ref ( )
409+ . and_then ( |credentials| credentials. username ( ) ) ,
410+ )
411+ } ) {
408412 debug ! ( "Found credentials in netrc file for {url}" ) ;
409413 Some ( credentials)
410414 // N.B. The keyring provider performs lookups for the exact URL then
0 commit comments