@@ -13,6 +13,7 @@ use crate::models::Crate;
1313
1414const CACHE_CONTROL_IMMUTABLE : & str = "public,max-age=31536000,immutable" ;
1515const CACHE_CONTROL_README : & str = "public,max-age=604800" ;
16+ const CACHE_CONTROL_INDEX : & str = "public,max-age=600" ;
1617
1718#[ derive( Clone , Debug ) ]
1819pub enum Uploader {
@@ -82,6 +83,17 @@ impl Uploader {
8283 format ! ( "readmes/{name}/{name}-{version}.html" )
8384 }
8485
86+ /// Returns the internal path of an uploaded crate's index file.
87+ fn index_path ( name : & str ) -> String {
88+ let prefix = match name. len ( ) {
89+ 1 => String :: from ( "1" ) ,
90+ 2 => String :: from ( "2" ) ,
91+ 3 => format ! ( "3/{}" , & name[ ..1 ] ) ,
92+ _ => format ! ( "{}/{}" , & name[ 0 ..2 ] , & name[ 2 ..4 ] ) ,
93+ } ;
94+ format ! ( "index/{prefix}/{name}" )
95+ }
96+
8597 /// Uploads a file using the configured uploader (either `S3`, `Local`).
8698 ///
8799 /// It returns the path of the uploaded file.
@@ -175,4 +187,29 @@ impl Uploader {
175187 ) ?;
176188 Ok ( ( ) )
177189 }
190+
191+ pub ( crate ) fn upload_index (
192+ & self ,
193+ http_client : & Client ,
194+ crate_name : & str ,
195+ index : String ,
196+ ) -> Result < ( ) > {
197+ let path = Uploader :: index_path ( crate_name) ;
198+ let content_length = index. len ( ) as u64 ;
199+ let content = Cursor :: new ( index) ;
200+ let mut extra_headers = header:: HeaderMap :: new ( ) ;
201+ extra_headers. insert (
202+ header:: CACHE_CONTROL ,
203+ header:: HeaderValue :: from_static ( CACHE_CONTROL_INDEX ) ,
204+ ) ;
205+ self . upload (
206+ http_client,
207+ & path,
208+ content,
209+ content_length,
210+ "text/plain" ,
211+ extra_headers,
212+ ) ?;
213+ Ok ( ( ) )
214+ }
178215}
0 commit comments