Skip to content

Commit 307930e

Browse files
committed
Auto merge of #1871 - jtescher:imutable-s3-uploads, r=smarnach
Upload all content to s3 as public and immutable Adds cache control header with value `public,max-age=31536000,immutable` to all future crate and README uploads. Fixes #1826
2 parents ae7834e + dc3a221 commit 307930e

File tree

5 files changed

+40
-6
lines changed

5 files changed

+40
-6
lines changed

src/bin/render-readmes.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,14 @@ fn main() {
131131
let readme_path = format!("readmes/{0}/{0}-{1}.html", krate_name, version.num);
132132
config
133133
.uploader
134-
.upload(&client, &readme_path, content, content_length, "text/html")
134+
.upload(
135+
&client,
136+
&readme_path,
137+
content,
138+
content_length,
139+
"text/html",
140+
None,
141+
)
135142
.unwrap_or_else(|_| {
136143
panic!(
137144
"[{}-{}] Couldn't upload file to S3",

src/s3/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ impl Bucket {
4545
content: R,
4646
content_length: u64,
4747
content_type: &str,
48+
extra_headers: Option<header::HeaderMap>,
4849
) -> reqwest::Result<reqwest::Response> {
4950
let path = if path.starts_with('/') {
5051
&path[1..]
@@ -60,6 +61,7 @@ impl Bucket {
6061
.header(header::AUTHORIZATION, auth)
6162
.header(header::CONTENT_TYPE, content_type)
6263
.header(header::DATE, date)
64+
.headers(extra_headers.unwrap_or_else(header::HeaderMap::new))
6365
.body(reqwest::Body::sized(content, content_length))
6466
.send()?
6567
.error_for_status()

src/tasks/dump_db.rs

+1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ impl DumpTarball {
157157
tarfile,
158158
content_length,
159159
"application/gzip",
160+
None,
160161
)
161162
.map_err(std_error_no_send)?;
162163
Ok(())

src/tests/record.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ fn replay_http(
272272
mut exchange: Exchange,
273273
stdout: &mut dyn Write,
274274
) -> Box<dyn Future<Item = hyper::Response<hyper::Body>, Error = hyper::Error> + Send> {
275-
static IGNORED_HEADERS: &[&str] = &["authorization", "date", "user-agent"];
275+
static IGNORED_HEADERS: &[&str] = &["authorization", "date", "user-agent", "cache-control"];
276276

277277
assert_eq!(req.uri().to_string(), exchange.request.uri);
278278
assert_eq!(req.method().to_string(), exchange.request.method);

src/uploaders.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use conduit::Request;
22
use flate2::read::GzDecoder;
33
use openssl::hash::{Hasher, MessageDigest};
4+
use reqwest::header;
45

56
use crate::util::LimitErrorReader;
67
use crate::util::{human, internal, CargoResult, ChainError, Maximums};
@@ -13,6 +14,8 @@ use std::sync::Arc;
1314
use crate::middleware::app::RequestApp;
1415
use crate::models::Crate;
1516

17+
pub const CACHE_CONTROL_IMMUTABLE: &str = "public,max-age=31536000,immutable";
18+
1619
#[derive(Clone, Debug)]
1720
pub enum Uploader {
1821
/// For production usage, uploads and redirects to s3.
@@ -70,13 +73,13 @@ impl Uploader {
7073
}
7174
}
7275

73-
/// Returns the interna path of an uploaded crate's version archive.
76+
/// Returns the internal path of an uploaded crate's version archive.
7477
fn crate_path(name: &str, version: &str) -> String {
7578
// No slash in front so we can use join
7679
format!("crates/{}/{}-{}.crate", name, name, version)
7780
}
7881

79-
/// Returns the interna path of an uploaded crate's version readme.
82+
/// Returns the internal path of an uploaded crate's version readme.
8083
fn readme_path(name: &str, version: &str) -> String {
8184
format!("readmes/{}/{}-{}.html", name, name, version)
8285
}
@@ -91,11 +94,19 @@ impl Uploader {
9194
mut content: R,
9295
content_length: u64,
9396
content_type: &str,
97+
extra_headers: Option<header::HeaderMap>,
9498
) -> CargoResult<Option<String>> {
9599
match *self {
96100
Uploader::S3 { ref bucket, .. } => {
97101
bucket
98-
.put(client, path, content, content_length, content_type)
102+
.put(
103+
client,
104+
path,
105+
content,
106+
content_length,
107+
content_type,
108+
extra_headers,
109+
)
99110
.map_err(|e| internal(&format_args!("failed to upload to S3: {}", e)))?;
100111
Ok(Some(String::from(path)))
101112
}
@@ -126,12 +137,18 @@ impl Uploader {
126137
let checksum = hash(&body);
127138
let content_length = body.len() as u64;
128139
let content = Cursor::new(body);
140+
let mut extra_headers = header::HeaderMap::new();
141+
extra_headers.insert(
142+
header::CACHE_CONTROL,
143+
CACHE_CONTROL_IMMUTABLE.parse().unwrap(),
144+
);
129145
self.upload(
130146
app.http_client(),
131147
&path,
132148
content,
133149
content_length,
134150
"application/x-tar",
151+
Some(extra_headers),
135152
)?;
136153
Ok(checksum)
137154
}
@@ -146,7 +163,14 @@ impl Uploader {
146163
let path = Uploader::readme_path(crate_name, vers);
147164
let content_length = readme.len() as u64;
148165
let content = Cursor::new(readme);
149-
self.upload(http_client, &path, content, content_length, "text/html")?;
166+
self.upload(
167+
http_client,
168+
&path,
169+
content,
170+
content_length,
171+
"text/html",
172+
None,
173+
)?;
150174
Ok(())
151175
}
152176
}

0 commit comments

Comments
 (0)