11use conduit:: Request ;
22use flate2:: read:: GzDecoder ;
33use openssl:: hash:: { Hasher , MessageDigest } ;
4+ use reqwest:: header;
45
56use crate :: util:: LimitErrorReader ;
67use crate :: util:: { human, internal, CargoResult , ChainError , Maximums } ;
@@ -13,6 +14,8 @@ use std::sync::Arc;
1314use crate :: middleware:: app:: RequestApp ;
1415use crate :: models:: Crate ;
1516
17+ pub const CACHE_CONTROL_IMMUTABLE : & str = "public,max-age=31536000,immutable" ;
18+
1619#[ derive( Clone , Debug ) ]
1720pub 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