From 220bc4664305067dad4e121c2db292e2844389b3 Mon Sep 17 00:00:00 2001 From: Olivier Le Floch Date: Mon, 19 Feb 2024 12:40:25 -0800 Subject: [PATCH] is_http_range_requests_unsupported should return true on Method Not Allowed (#1713) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Azure Artifacts does not allow HEAD requests when attempting to download packages. This expands error handling in `is_http_range_requests_unsupported` to identify HTTP 405 (Method Not Allowed) error codes, and return `true` (i.e. Range requests will not be supported). This partially addresses #1458 – after this change, Azure Artifacts downloads still fail, but due to 401 Not Authorized instead of 405 Method Not Allowed. ## Test Plan I ran something akin to ``` RUST_LOG=trace cargo run -- pip install --index-url=https://REDACTED:REDACTED@pkgs.dev.azure.com/REDACTED/_packaging/REDACTED/pypi/simple/ --upgrade --verbose private-package ``` without this code, and got a 405 failure: ``` error: Failed to download: private-package==1.2.3 Caused by: HTTP status client error (405 Method Not Allowed) for url (https://pkgs.dev.azure.com/REDACTED/_packaging/REDACTED/pypi/download/private-package/1.2.3/private_package-1.2.3-py3-none-any.whl#sha256=REDACTED) ``` with this code, I get a 401 failure: ``` error: Failed to download: private-package==1.2.3 Caused by: HTTP status client error (401 Unauthorized) for url (https://pkgs.dev.azure.com/REDACTED/_packaging/REDACTED/pypi/download/private-package/1.2.3/private_package-1.2.3-py3-none-any.whl#sha256=REDACTED) ``` ## Caveats I'm not seeing a non HEAD request being reported as being fired, so I'm not sure I'm doing this correctly! --- crates/uv-client/src/error.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/uv-client/src/error.rs b/crates/uv-client/src/error.rs index 70bffaf53..6658c2a44 100644 --- a/crates/uv-client/src/error.rs +++ b/crates/uv-client/src/error.rs @@ -166,6 +166,16 @@ impl ErrorKind { return true; } + // The server returned a "Method Not Allowed" error, indicating it doesn't support + // HEAD requests, so we can't check for range requests. + ErrorKind::RequestError(err) => { + if let Some(status) = err.status() { + if status == reqwest::StatusCode::METHOD_NOT_ALLOWED { + return true; + } + } + } + // The server doesn't support range requests, but we only discovered this while // unzipping due to erroneous server behavior. ErrorKind::Zip(_, ZipError::UpstreamReadError(err)) => {