1
1
use conduit:: Request ;
2
2
use flate2:: read:: GzDecoder ;
3
3
use openssl:: hash:: { Hasher , MessageDigest } ;
4
+ use reqwest:: header;
4
5
5
6
use crate :: util:: LimitErrorReader ;
6
7
use crate :: util:: { human, internal, CargoResult , ChainError , Maximums } ;
@@ -13,6 +14,8 @@ use std::sync::Arc;
13
14
use crate :: middleware:: app:: RequestApp ;
14
15
use crate :: models:: Crate ;
15
16
17
+ pub const CACHE_CONTROL_IMMUTABLE : & str = "public,max-age=31536000,immutable" ;
18
+
16
19
#[ derive( Clone , Debug ) ]
17
20
pub enum Uploader {
18
21
/// For production usage, uploads and redirects to s3.
@@ -70,13 +73,13 @@ impl Uploader {
70
73
}
71
74
}
72
75
73
- /// Returns the interna path of an uploaded crate's version archive.
76
+ /// Returns the internal path of an uploaded crate's version archive.
74
77
fn crate_path ( name : & str , version : & str ) -> String {
75
78
// No slash in front so we can use join
76
79
format ! ( "crates/{}/{}-{}.crate" , name, name, version)
77
80
}
78
81
79
- /// Returns the interna path of an uploaded crate's version readme.
82
+ /// Returns the internal path of an uploaded crate's version readme.
80
83
fn readme_path ( name : & str , version : & str ) -> String {
81
84
format ! ( "readmes/{}/{}-{}.html" , name, name, version)
82
85
}
@@ -91,11 +94,19 @@ impl Uploader {
91
94
mut content : R ,
92
95
content_length : u64 ,
93
96
content_type : & str ,
97
+ extra_headers : Option < header:: HeaderMap > ,
94
98
) -> CargoResult < Option < String > > {
95
99
match * self {
96
100
Uploader :: S3 { ref bucket, .. } => {
97
101
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
+ )
99
110
. map_err ( |e| internal ( & format_args ! ( "failed to upload to S3: {}" , e) ) ) ?;
100
111
Ok ( Some ( String :: from ( path) ) )
101
112
}
@@ -126,12 +137,18 @@ impl Uploader {
126
137
let checksum = hash ( & body) ;
127
138
let content_length = body. len ( ) as u64 ;
128
139
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
+ ) ;
129
145
self . upload (
130
146
app. http_client ( ) ,
131
147
& path,
132
148
content,
133
149
content_length,
134
150
"application/x-tar" ,
151
+ Some ( extra_headers) ,
135
152
) ?;
136
153
Ok ( checksum)
137
154
}
@@ -146,7 +163,14 @@ impl Uploader {
146
163
let path = Uploader :: readme_path ( crate_name, vers) ;
147
164
let content_length = readme. len ( ) as u64 ;
148
165
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
+ ) ?;
150
174
Ok ( ( ) )
151
175
}
152
176
}
0 commit comments