Skip to content

Commit 3ba3754

Browse files
j178MtkN1
authored andcommitted
Log netrc parsing error (astral-sh#8364)
## Summary Resolves astral-sh#7685 ## Test Plan ```console $ echo "this is an invalid netrc" > .netrc $ NETRC=.netrc cargo run -- pip install anyio --index-url https://pypi-proxy.fly.dev/basic-auth/simple --strict -v DEBUG uv 0.4.24 (f4d5fba 2024-10-19) DEBUG Searching for default Python interpreter in system path or `py` launcher DEBUG Found `cpython-3.11.2-windows-x86_64-none` at `D:\Projects\Rust\uv\.venv\Scripts\python.exe` (virtual environment) DEBUG Using Python 3.11.2 environment at .venv DEBUG Acquired lock for `.venv` DEBUG At least one requirement is not satisfied: anyio DEBUG Using request timeout of 30s DEBUG Solving with installed Python version: 3.11.2 DEBUG Solving with target Python version: >=3.11.2 DEBUG Adding direct dependency: anyio* DEBUG No cache entry for: https://pypi-proxy.fly.dev/basic-auth/simple/anyio/ WARN Error reading netrc file: parsing error: bad toplevel token 'this' (line 1) in the file '.netrc' DEBUG Searching for a compatible version of anyio (*) DEBUG No compatible version found for: anyio × No solution found when resolving dependencies: ╰─▶ Because anyio was not found in the package registry and you require anyio, we can conclude that your requirements are unsatisfiable. hint: An index URL (https://pypi-proxy.fly.dev/basic-auth/simple) could not be queried due to a lack of valid authentication credentials (401 Unauthorized). DEBUG Released lock at `D:\Projects\Rust\uv\.venv\.lock` error: process didn't exit successfully: `target\debug\uv.exe pip install anyio --index-url https://pypi-proxy.fly.dev/basic-auth/simple --strict -v` (exit code: 1) ```
1 parent e17026d commit 3ba3754

File tree

1 file changed

+46
-8
lines changed

1 file changed

+46
-8
lines changed

crates/uv-auth/src/middleware.rs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::sync::Arc;
1+
use std::sync::{Arc, LazyLock};
22

33
use http::{Extensions, StatusCode};
44
use url::Url;
@@ -12,14 +12,48 @@ use anyhow::{anyhow, format_err};
1212
use netrc::Netrc;
1313
use reqwest::{Request, Response};
1414
use reqwest_middleware::{Error, Middleware, Next};
15-
use tracing::{debug, trace};
15+
use tracing::{debug, trace, warn};
16+
17+
/// Strategy for loading netrc files.
18+
enum NetrcMode {
19+
Automatic(LazyLock<Option<Netrc>>),
20+
Enabled(Netrc),
21+
Disabled,
22+
}
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+
}
1650

1751
/// A middleware that adds basic authentication to requests.
1852
///
1953
/// Uses a cache to propagate credentials from previously seen requests and
2054
/// fetches credentials from a netrc file and the keyring.
2155
pub struct AuthMiddleware {
22-
netrc: Option<Netrc>,
56+
netrc: NetrcMode,
2357
keyring: Option<KeyringProvider>,
2458
cache: Option<CredentialsCache>,
2559
/// We know that the endpoint needs authentication, so we don't try to send an unauthenticated
@@ -30,19 +64,23 @@ pub struct AuthMiddleware {
3064
impl AuthMiddleware {
3165
pub fn new() -> Self {
3266
Self {
33-
netrc: Netrc::new().ok(),
67+
netrc: NetrcMode::default(),
3468
keyring: None,
3569
cache: None,
3670
only_authenticated: false,
3771
}
3872
}
3973

40-
/// Configure the [`Netrc`] credential file to use.
74+
/// Configure the [`netrc::Netrc`] credential file to use.
4175
///
4276
/// `None` disables authentication via netrc.
4377
#[must_use]
44-
pub fn with_netrc(mut self, netrc: Option<Netrc>) -> Self {
45-
self.netrc = netrc;
78+
pub fn with_netrc(mut self, netrc: Option<netrc::Netrc>) -> Self {
79+
self.netrc = if let Some(netrc) = netrc {
80+
NetrcMode::Enabled(netrc)
81+
} else {
82+
NetrcMode::Disabled
83+
};
4684
self
4785
}
4886

@@ -361,7 +399,7 @@ impl AuthMiddleware {
361399
}
362400

363401
// Netrc support based on: <https://github.com/gribouille/netrc>.
364-
let credentials = if let Some(credentials) = self.netrc.as_ref().and_then(|netrc| {
402+
let credentials = if let Some(credentials) = self.netrc.get().and_then(|netrc| {
365403
debug!("Checking netrc for credentials for {url}");
366404
Credentials::from_netrc(
367405
netrc,

0 commit comments

Comments
 (0)