1- use fastly:: http:: { Method , StatusCode , Version } ;
1+ use fastly:: convert:: ToHeaderValue ;
2+ use fastly:: http:: { header, Method , StatusCode , Version } ;
23use fastly:: { Error , Request , Response } ;
34use log:: { info, warn, LevelFilter } ;
45use log_fastly:: Logger ;
@@ -16,6 +17,7 @@ mod log_line;
1617
1718const DATADOG_APP : & str = "crates.io" ;
1819const DATADOG_SERVICE : & str = "static.crates.io" ;
20+ const VERSION_DOWNLOADS : & str = "/archive/version-downloads/" ;
1921
2022#[ fastly:: main]
2123fn main ( request : Request ) -> Result < Response , Error > {
@@ -110,9 +112,17 @@ fn handle_request(config: &Config, mut request: Request) -> Result<Response, Err
110112 return Ok ( response) ;
111113 }
112114
115+ if request. get_url ( ) . path ( ) == "/archive/version-downloads" {
116+ let mut destination = request. get_url ( ) . clone ( ) ;
117+ destination. set_path ( VERSION_DOWNLOADS ) ;
118+
119+ return Ok ( permanent_redirect ( destination) ) ;
120+ }
121+
113122 set_ttl ( config, & mut request) ;
114123 rewrite_urls_with_plus_character ( & mut request) ;
115124 rewrite_download_urls ( & mut request) ;
125+ rewrite_version_downloads_urls ( & mut request) ;
116126
117127 // Database dump is too big to cache on Fastly
118128 if request. get_url_str ( ) . ends_with ( "db-dump.tar.gz" ) {
@@ -124,6 +134,12 @@ fn handle_request(config: &Config, mut request: Request) -> Result<Response, Err
124134 }
125135}
126136
137+ fn permanent_redirect ( destination : impl ToHeaderValue ) -> Response {
138+ Response :: new ( )
139+ . with_status ( StatusCode :: PERMANENT_REDIRECT )
140+ . with_header ( header:: LOCATION , destination)
141+ }
142+
127143/// Limit HTTP methods
128144///
129145/// Clients are only allowed to request resources using GET and HEAD requests. If any other HTTP
@@ -168,6 +184,19 @@ fn rewrite_urls_with_plus_character(request: &mut Request) {
168184 }
169185}
170186
187+ /// Rewrite `/archive/version-downloads/` URLs to `/archive/version-downloads/index.html`
188+ ///
189+ /// In this way, users can see what files are available for download.
190+ fn rewrite_version_downloads_urls ( request : & mut Request ) {
191+ let url = request. get_url_mut ( ) ;
192+ let path = url. path ( ) ;
193+
194+ if path == VERSION_DOWNLOADS {
195+ let new_path = format ! ( "{path}index.html" ) ;
196+ url. set_path ( & new_path) ;
197+ }
198+ }
199+
171200/// Rewrite `/crates/{crate}/{version}/download` URLs to
172201/// `/crates/{crate}/{crate}-{version}.crate`
173202///
0 commit comments