Skip to content

Commit b5d6f06

Browse files
authored
Merge pull request #405 from integer32llc/remove-download-restriction
Remove restriction that a crate must be in the database to get a download URL
2 parents 442c439 + 4a7d270 commit b5d6f06

File tree

6 files changed

+34
-14
lines changed

6 files changed

+34
-14
lines changed

.env.sample

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
# `postgres://postgres:@localhost/cargo_registry`.
44
export DATABASE_URL=""
55

6+
# If you are running a mirror of crates.io, uncomment this line.
7+
# export MIRROR=1
8+
69
# Key to sign and encrypt cookies with. Change this to a long, random string
710
# for production.
811
export SESSION_KEY="badkey"

src/bin/fill-in-user-id.rs

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ fn main() {
3333
db_url: env("DATABASE_URL"),
3434
env: cargo_registry::Env::Production,
3535
max_upload_size: 0,
36+
mirror: false,
3637
};
3738
let app = cargo_registry::App::new(&config);
3839
{

src/bin/server.rs

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ fn main() {
5757
db_url: env("DATABASE_URL"),
5858
env: cargo_env,
5959
max_upload_size: 10 * 1024 * 1024,
60+
mirror: env::var("MIRROR").is_ok(),
6061
};
6162
let app = cargo_registry::App::new(&config);
6263
let app = cargo_registry::middleware(Arc::new(app));

src/config.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct Config {
1414
pub db_url: String,
1515
pub env: ::Env,
1616
pub max_upload_size: u64,
17+
pub mirror: bool,
1718
}
1819

1920
impl Config {

src/krate.rs

+27-14
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,31 @@ fn read_fill<R: Read + ?Sized>(r: &mut R, mut slice: &mut [u8])
827827
pub fn download(req: &mut Request) -> CargoResult<Response> {
828828
let crate_name = &req.params()["crate_id"];
829829
let version = &req.params()["version"];
830+
831+
// If we are a mirror, ignore failure to update download counts.
832+
// API-only mirrors won't have any crates in their database, and
833+
// incrementing the download count will look up the crate in the
834+
// database. Mirrors just want to pass along a redirect URL.
835+
if req.app().config.mirror {
836+
let _ = increment_download_counts(req, crate_name, version);
837+
} else {
838+
try!(increment_download_counts(req, crate_name, version));
839+
}
840+
841+
let redirect_url = format!("https://{}/crates/{}/{}-{}.crate",
842+
req.app().bucket.host(),
843+
crate_name, crate_name, version);
844+
845+
if req.wants_json() {
846+
#[derive(RustcEncodable)]
847+
struct R { url: String }
848+
Ok(req.json(&R{ url: redirect_url }))
849+
} else {
850+
Ok(req.redirect(redirect_url))
851+
}
852+
}
853+
854+
fn increment_download_counts(req: &Request, crate_name: &str, version: &str) -> CargoResult<()> {
830855
let tx = try!(req.tx());
831856
let stmt = try!(tx.prepare("SELECT versions.id as version_id
832857
FROM crates
@@ -836,7 +861,7 @@ pub fn download(req: &mut Request) -> CargoResult<Response> {
836861
canon_crate_name($1)
837862
AND versions.num = $2
838863
LIMIT 1"));
839-
let rows = try!(stmt.query(&[crate_name, version]));
864+
let rows = try!(stmt.query(&[&crate_name, &version]));
840865
let row = try!(rows.iter().next().chain_error(|| {
841866
human("crate or version not found")
842867
}));
@@ -862,19 +887,7 @@ pub fn download(req: &mut Request) -> CargoResult<Response> {
862887
try!(tx.execute("INSERT INTO version_downloads
863888
(version_id) VALUES ($1)", &[&version_id]));
864889
}
865-
866-
// Now that we've done our business, redirect to the actual data.
867-
let redirect_url = format!("https://{}/crates/{}/{}-{}.crate",
868-
req.app().bucket.host(),
869-
crate_name, crate_name, version);
870-
871-
if req.wants_json() {
872-
#[derive(RustcEncodable)]
873-
struct R { url: String }
874-
Ok(req.json(&R{ url: redirect_url }))
875-
} else {
876-
Ok(req.redirect(redirect_url))
877-
}
890+
Ok(())
878891
}
879892

880893
/// Handles the `GET /crates/:crate_id/downloads` route.

src/tests/all.rs

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ fn app() -> (record::Bomb, Arc<App>, conduit_middleware::MiddlewareBuilder) {
9090
db_url: env("TEST_DATABASE_URL"),
9191
env: cargo_registry::Env::Test,
9292
max_upload_size: 1000,
93+
mirror: false,
9394
};
9495
INIT.call_once(|| db_setup(&config.db_url));
9596
let app = App::new(&config);

0 commit comments

Comments
 (0)