Skip to content

Commit d1a2592

Browse files
committed
Auto merge of #11069 - arlosi:retry, r=Eh2406
Add retry support to sparse registries Sparse (HTTP) registries currently do not respect Cargo's retry policy for http requests. This change makes sparse registries use the same retry system as package downloads.
2 parents 3cdf1ab + dcc512b commit d1a2592

File tree

10 files changed

+196
-103
lines changed

10 files changed

+196
-103
lines changed

crates/cargo-test-support/src/registry.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub struct RegistryBuilder {
7272
/// Write the registry in configuration.
7373
configure_registry: bool,
7474
/// API responders.
75-
custom_responders: HashMap<&'static str, Box<dyn Send + Fn(&Request) -> Response>>,
75+
custom_responders: HashMap<&'static str, Box<dyn Send + Fn(&Request, &HttpServer) -> Response>>,
7676
}
7777

7878
pub struct TestRegistry {
@@ -117,7 +117,7 @@ impl RegistryBuilder {
117117

118118
/// Adds a custom HTTP response for a specific url
119119
#[must_use]
120-
pub fn add_responder<R: 'static + Send + Fn(&Request) -> Response>(
120+
pub fn add_responder<R: 'static + Send + Fn(&Request, &HttpServer) -> Response>(
121121
mut self,
122122
url: &'static str,
123123
responder: R,
@@ -497,20 +497,23 @@ pub struct Response {
497497
pub body: Vec<u8>,
498498
}
499499

500-
struct HttpServer {
500+
pub struct HttpServer {
501501
listener: TcpListener,
502502
registry_path: PathBuf,
503503
dl_path: PathBuf,
504504
token: Option<String>,
505-
custom_responders: HashMap<&'static str, Box<dyn Send + Fn(&Request) -> Response>>,
505+
custom_responders: HashMap<&'static str, Box<dyn Send + Fn(&Request, &HttpServer) -> Response>>,
506506
}
507507

508508
impl HttpServer {
509509
pub fn new(
510510
registry_path: PathBuf,
511511
dl_path: PathBuf,
512512
token: Option<String>,
513-
api_responders: HashMap<&'static str, Box<dyn Send + Fn(&Request) -> Response>>,
513+
api_responders: HashMap<
514+
&'static str,
515+
Box<dyn Send + Fn(&Request, &HttpServer) -> Response>,
516+
>,
514517
) -> HttpServerHandle {
515518
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
516519
let addr = listener.local_addr().unwrap();
@@ -620,7 +623,7 @@ impl HttpServer {
620623

621624
// Check for custom responder
622625
if let Some(responder) = self.custom_responders.get(req.url.path()) {
623-
return responder(&req);
626+
return responder(&req, self);
624627
}
625628
let path: Vec<_> = req.url.path()[1..].split('/').collect();
626629
match (req.method.as_str(), path.as_slice()) {
@@ -668,7 +671,7 @@ impl HttpServer {
668671
}
669672

670673
/// Unauthorized response
671-
fn unauthorized(&self, _req: &Request) -> Response {
674+
pub fn unauthorized(&self, _req: &Request) -> Response {
672675
Response {
673676
code: 401,
674677
headers: vec![],
@@ -677,7 +680,7 @@ impl HttpServer {
677680
}
678681

679682
/// Not found response
680-
fn not_found(&self, _req: &Request) -> Response {
683+
pub fn not_found(&self, _req: &Request) -> Response {
681684
Response {
682685
code: 404,
683686
headers: vec![],
@@ -686,16 +689,25 @@ impl HttpServer {
686689
}
687690

688691
/// Respond OK without doing anything
689-
fn ok(&self, _req: &Request) -> Response {
692+
pub fn ok(&self, _req: &Request) -> Response {
690693
Response {
691694
code: 200,
692695
headers: vec![],
693696
body: br#"{"ok": true, "msg": "completed!"}"#.to_vec(),
694697
}
695698
}
696699

700+
/// Return an internal server error (HTTP 500)
701+
pub fn internal_server_error(&self, _req: &Request) -> Response {
702+
Response {
703+
code: 500,
704+
headers: vec![],
705+
body: br#"internal server error"#.to_vec(),
706+
}
707+
}
708+
697709
/// Serve the download endpoint
698-
fn dl(&self, req: &Request) -> Response {
710+
pub fn dl(&self, req: &Request) -> Response {
699711
let file = self
700712
.dl_path
701713
.join(req.url.path().strip_prefix("/dl/").unwrap());
@@ -711,7 +723,7 @@ impl HttpServer {
711723
}
712724

713725
/// Serve the registry index
714-
fn index(&self, req: &Request) -> Response {
726+
pub fn index(&self, req: &Request) -> Response {
715727
let file = self
716728
.registry_path
717729
.join(req.url.path().strip_prefix("/index/").unwrap());
@@ -761,7 +773,7 @@ impl HttpServer {
761773
}
762774
}
763775

764-
fn publish(&self, req: &Request) -> Response {
776+
pub fn publish(&self, req: &Request) -> Response {
765777
if let Some(body) = &req.body {
766778
// Get the metadata of the package
767779
let (len, remaining) = body.split_at(4);

src/cargo/core/package.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::core::{Dependency, Manifest, PackageId, SourceId, Target};
2727
use crate::core::{SourceMap, Summary, Workspace};
2828
use crate::ops;
2929
use crate::util::config::PackageCacheLock;
30-
use crate::util::errors::{CargoResult, HttpNot200};
30+
use crate::util::errors::{CargoResult, HttpNotSuccessful};
3131
use crate::util::interning::InternedString;
3232
use crate::util::network::Retry;
3333
use crate::util::{self, internal, Config, Progress, ProgressStyle};
@@ -868,18 +868,19 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
868868
let code = handle.response_code()?;
869869
if code != 200 && code != 0 {
870870
let url = handle.effective_url()?.unwrap_or(url);
871-
return Err(HttpNot200 {
871+
return Err(HttpNotSuccessful {
872872
code,
873873
url: url.to_string(),
874+
body: data,
874875
}
875876
.into());
876877
}
877-
Ok(())
878+
Ok(data)
878879
})
879880
.with_context(|| format!("failed to download from `{}`", dl.url))?
880881
};
881882
match ret {
882-
Some(()) => break (dl, data),
883+
Some(data) => break (dl, data),
883884
None => {
884885
self.pending_ids.insert(dl.id);
885886
self.enqueue(dl, handle)?

src/cargo/ops/registry.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::sources::{RegistrySource, SourceConfigMap, CRATES_IO_DOMAIN, CRATES_I
2828
use crate::util::config::{self, Config, SslVersionConfig, SslVersionConfigRange};
2929
use crate::util::errors::CargoResult;
3030
use crate::util::important_paths::find_root_manifest_for_wd;
31-
use crate::util::IntoUrl;
31+
use crate::util::{truncate_with_ellipsis, IntoUrl};
3232
use crate::{drop_print, drop_println, version};
3333

3434
mod auth;
@@ -963,18 +963,6 @@ pub fn search(
963963
limit: u32,
964964
reg: Option<String>,
965965
) -> CargoResult<()> {
966-
fn truncate_with_ellipsis(s: &str, max_width: usize) -> String {
967-
// We should truncate at grapheme-boundary and compute character-widths,
968-
// yet the dependencies on unicode-segmentation and unicode-width are
969-
// not worth it.
970-
let mut chars = s.chars();
971-
let mut prefix = (&mut chars).take(max_width - 1).collect::<String>();
972-
if chars.next().is_some() {
973-
prefix.push('…');
974-
}
975-
prefix
976-
}
977-
978966
let (mut registry, _, source_id) =
979967
registry(config, None, index.as_deref(), reg.as_deref(), false, false)?;
980968
let (crates, total_crates) = registry.search(query, limit).with_context(|| {

0 commit comments

Comments
 (0)