1
- use std:: sync:: Arc ;
1
+ use std:: sync:: { Arc , LazyLock } ;
2
2
3
3
use http:: { Extensions , StatusCode } ;
4
4
use url:: Url ;
@@ -16,11 +16,38 @@ use tracing::{debug, trace, warn};
16
16
17
17
/// Strategy for loading netrc files.
18
18
enum NetrcMode {
19
- Automatic ,
20
- Enabled ( netrc :: Netrc ) ,
19
+ Automatic ( LazyLock < Option < Netrc > > ) ,
20
+ Enabled ( Netrc ) ,
21
21
Disabled ,
22
22
}
23
23
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
+
24
51
/// A middleware that adds basic authentication to requests.
25
52
///
26
53
/// Uses a cache to propagate credentials from previously seen requests and
@@ -37,7 +64,7 @@ pub struct AuthMiddleware {
37
64
impl AuthMiddleware {
38
65
pub fn new ( ) -> Self {
39
66
Self {
40
- netrc : NetrcMode :: Automatic ,
67
+ netrc : NetrcMode :: default ( ) ,
41
68
keyring : None ,
42
69
cache : None ,
43
70
only_authenticated : false ,
@@ -372,39 +399,16 @@ impl AuthMiddleware {
372
399
}
373
400
374
401
// 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
+ } ) {
408
412
debug ! ( "Found credentials in netrc file for {url}" ) ;
409
413
Some ( credentials)
410
414
// N.B. The keyring provider performs lookups for the exact URL then
0 commit comments