Skip to content

Commit

Permalink
Include the IP address in HTTP errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
ehuss committed Apr 12, 2023
1 parent c7c9b8f commit 4702fa3
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 32 deletions.
11 changes: 5 additions & 6 deletions src/cargo/core/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,13 +880,12 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {

let code = handle.response_code()?;
if code != 200 && code != 0 {
let url = handle.effective_url()?.unwrap_or(url);
return Err(HttpNotSuccessful {
code,
url: url.to_string(),
body: data,
return Err(HttpNotSuccessful::new_from_handle(
&mut handle,
&url,
data,
headers,
}
)
.into());
}
Ok(data)
Expand Down
16 changes: 8 additions & 8 deletions src/cargo/sources/registry/http_remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,14 +288,13 @@ impl<'cfg> HttpRegistry<'cfg> {
304 => StatusCode::NotModified,
401 => StatusCode::Unauthorized,
404 | 410 | 451 => StatusCode::NotFound,
code => {
let url = handle.effective_url()?.unwrap_or(&url);
return Err(HttpNotSuccessful {
code,
url: url.to_owned(),
body: data,
headers: download.header_map.take().others,
}
_ => {
return Err(HttpNotSuccessful::new_from_handle(
&mut handle,
&url,
data,
download.header_map.take().others,
)
.into());
}
};
Expand Down Expand Up @@ -548,6 +547,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
code: 401,
body: result.data,
url: self.full_url(path),
ip: None,
headers: result.header_map.others,
}
.into());
Expand Down
34 changes: 32 additions & 2 deletions src/cargo/util/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![allow(unknown_lints)]

use anyhow::Error;
use curl::easy::Easy;
use std::fmt;
use std::path::PathBuf;

Expand All @@ -22,10 +23,35 @@ pub const DEBUG_HEADERS: &[&str] = &[
pub struct HttpNotSuccessful {
pub code: u32,
pub url: String,
pub ip: Option<String>,
pub body: Vec<u8>,
pub headers: Vec<String>,
}

impl HttpNotSuccessful {
pub fn new_from_handle(
handle: &mut Easy,
initial_url: &str,
body: Vec<u8>,
headers: Vec<String>,
) -> HttpNotSuccessful {
let ip = handle.primary_ip().ok().flatten().map(|s| s.to_string());
let url = handle
.effective_url()
.ok()
.flatten()
.unwrap_or(initial_url)
.to_string();
HttpNotSuccessful {
code: handle.response_code().unwrap_or(0),
url,
ip,
body,
headers,
}
}
}

impl fmt::Display for HttpNotSuccessful {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let body = std::str::from_utf8(&self.body)
Expand All @@ -34,9 +60,13 @@ impl fmt::Display for HttpNotSuccessful {

write!(
f,
"failed to get successful HTTP response from `{}`, got {}\n",
self.url, self.code,
"failed to get successful HTTP response from `{}`",
self.url
)?;
if let Some(ip) = &self.ip {
write!(f, " ({ip})")?;
}
write!(f, ", got {}\n", self.code,)?;
if !self.headers.is_empty() {
write!(f, "debug headers:\n{}\n", self.headers.join("\n"))?;
}
Expand Down
5 changes: 5 additions & 0 deletions src/cargo/util/network/retry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,15 @@ fn with_retry_repeats_the_call_then_works() {
let error1 = HttpNotSuccessful {
code: 501,
url: "Uri".to_string(),
ip: None,
body: Vec::new(),
headers: Vec::new(),
}
.into();
let error2 = HttpNotSuccessful {
code: 502,
url: "Uri".to_string(),
ip: None,
body: Vec::new(),
headers: Vec::new(),
}
Expand All @@ -177,13 +179,15 @@ fn with_retry_finds_nested_spurious_errors() {
let error1 = anyhow::Error::from(HttpNotSuccessful {
code: 501,
url: "Uri".to_string(),
ip: None,
body: Vec::new(),
headers: Vec::new(),
});
let error1 = anyhow::Error::from(error1.context("A non-spurious wrapping err"));
let error2 = anyhow::Error::from(HttpNotSuccessful {
code: 502,
url: "Uri".to_string(),
ip: None,
body: Vec::new(),
headers: Vec::new(),
});
Expand All @@ -203,6 +207,7 @@ fn default_retry_schedule() {
Err(anyhow::Error::from(HttpNotSuccessful {
code: 500,
url: "Uri".to_string(),
ip: None,
body: Vec::new(),
headers: Vec::new(),
}))
Expand Down
36 changes: 22 additions & 14 deletions tests/testsuite/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2743,10 +2743,10 @@ fn sparse_retry_single() {
.with_stderr(
"\
[UPDATING] `dummy-registry` index
warning: spurious network error (3 tries remaining): failed to get successful HTTP response from `[..]`, got 500
warning: spurious network error (3 tries remaining): failed to get successful HTTP response from `[..]` (127.0.0.1), got 500
body:
internal server error
warning: spurious network error (2 tries remaining): failed to get successful HTTP response from `[..]`, got 500
warning: spurious network error (2 tries remaining): failed to get successful HTTP response from `[..]` (127.0.0.1), got 500
body:
internal server error
[DOWNLOADING] crates ...
Expand Down Expand Up @@ -2816,7 +2816,7 @@ fn sparse_retry_multiple() {
&mut expected,
"warning: spurious network error ({remain} tries remaining): \
failed to get successful HTTP response from \
`http://127.0.0.1:[..]/{ab}/{cd}/{name}`, got 500\n\
`http://127.0.0.1:[..]/{ab}/{cd}/{name}` (127.0.0.1), got 500\n\
body:\n\
internal server error\n"
)
Expand Down Expand Up @@ -2876,10 +2876,12 @@ fn dl_retry_single() {
.with_stderr("\
[UPDATING] `dummy-registry` index
[DOWNLOADING] crates ...
warning: spurious network error (3 tries remaining): failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download`, got 500
warning: spurious network error (3 tries remaining): \
failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 500
body:
internal server error
warning: spurious network error (2 tries remaining): failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download`, got 500
warning: spurious network error (2 tries remaining): \
failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 500
body:
internal server error
[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`)
Expand Down Expand Up @@ -2954,7 +2956,7 @@ fn dl_retry_multiple() {
&mut expected,
"warning: spurious network error ({remain} tries remaining): \
failed to get successful HTTP response from \
`http://127.0.0.1:[..]/dl/{name}/1.0.0/download`, got 500\n\
`http://127.0.0.1:[..]/dl/{name}/1.0.0/download` (127.0.0.1), got 500\n\
body:\n\
internal server error\n"
)
Expand Down Expand Up @@ -3315,21 +3317,24 @@ fn debug_header_message_index() {
.build();
p.cargo("fetch").with_status(101).with_stderr("\
[UPDATING] `dummy-registry` index
warning: spurious network error (3 tries remaining): failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar`, got 503
warning: spurious network error (3 tries remaining): \
failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar` (127.0.0.1), got 503
debug headers:
x-amz-cf-pop: SFO53-P2
x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
x-cache: Hit from cloudfront
body:
Please slow down
warning: spurious network error (2 tries remaining): failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar`, got 503
warning: spurious network error (2 tries remaining): \
failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar` (127.0.0.1), got 503
debug headers:
x-amz-cf-pop: SFO53-P2
x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
x-cache: Hit from cloudfront
body:
Please slow down
warning: spurious network error (1 tries remaining): failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar`, got 503
warning: spurious network error (1 tries remaining): \
failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar` (127.0.0.1), got 503
debug headers:
x-amz-cf-pop: SFO53-P2
x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
Expand All @@ -3345,7 +3350,7 @@ Caused by:
download of 3/b/bar failed
Caused by:
failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar`, got 503
failed to get successful HTTP response from `http://127.0.0.1:[..]/index/3/b/bar` (127.0.0.1), got 503
debug headers:
x-amz-cf-pop: SFO53-P2
x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
Expand Down Expand Up @@ -3386,21 +3391,24 @@ fn debug_header_message_dl() {
p.cargo("fetch").with_status(101).with_stderr("\
[UPDATING] `dummy-registry` index
[DOWNLOADING] crates ...
warning: spurious network error (3 tries remaining): failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download`, got 503
warning: spurious network error (3 tries remaining): \
failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 503
debug headers:
x-amz-cf-pop: SFO53-P2
x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
x-cache: Hit from cloudfront
body:
Please slow down
warning: spurious network error (2 tries remaining): failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download`, got 503
warning: spurious network error (2 tries remaining): \
failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 503
debug headers:
x-amz-cf-pop: SFO53-P2
x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
x-cache: Hit from cloudfront
body:
Please slow down
warning: spurious network error (1 tries remaining): failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download`, got 503
warning: spurious network error (1 tries remaining): \
failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 503
debug headers:
x-amz-cf-pop: SFO53-P2
x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
Expand All @@ -3410,7 +3418,7 @@ Please slow down
error: failed to download from `http://127.0.0.1:[..]/dl/bar/1.0.0/download`
Caused by:
failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download`, got 503
failed to get successful HTTP response from `http://127.0.0.1:[..]/dl/bar/1.0.0/download` (127.0.0.1), got 503
debug headers:
x-amz-cf-pop: SFO53-P2
x-amz-cf-id: vEc3osJrCAXVaciNnF4Vev-hZFgnYwmNZtxMKRJ5bF6h9FTOtbTMnA==
Expand Down
4 changes: 2 additions & 2 deletions tests/testsuite/registry_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn requires_nightly() {
error: failed to download from `[..]/dl/bar/0.0.1/download`
Caused by:
failed to get successful HTTP response from `[..]`, got 401
failed to get successful HTTP response from `[..]` (127.0.0.1), got 401
body:
Unauthorized message from server.
"#,
Expand Down Expand Up @@ -415,7 +415,7 @@ fn incorrect_token_git() {
[ERROR] failed to download from `http://[..]/dl/bar/0.0.1/download`
Caused by:
failed to get successful HTTP response from `http://[..]/dl/bar/0.0.1/download`, got 401
failed to get successful HTTP response from `http://[..]/dl/bar/0.0.1/download` (127.0.0.1), got 401
body:
Unauthorized message from server.",
)
Expand Down

0 comments on commit 4702fa3

Please sign in to comment.