@@ -149,12 +149,7 @@ impl Thing {
149149 Ok ( resp)
150150 }
151151
152- async fn guess_redirect (
153- & self ,
154- req : & Request < Body > ,
155- mut krate : Option < & str > ,
156- mut version : Option < & str > ,
157- ) -> anyhow:: Result < Response < Body > > {
152+ fn cookies ( & self , req : & Request < Body > ) -> HashMap < String , String > {
158153 // Parse cookies
159154 let mut cookies = HashMap :: new ( ) ;
160155 if let Some ( h) = req. headers ( ) . get ( "Cookie" ) {
@@ -164,6 +159,16 @@ impl Thing {
164159 }
165160 }
166161 }
162+ cookies
163+ }
164+
165+ async fn guess_redirect (
166+ & self ,
167+ req : & Request < Body > ,
168+ mut krate : Option < & str > ,
169+ mut version : Option < & str > ,
170+ ) -> anyhow:: Result < Response < Body > > {
171+ let cookies = self . cookies ( req) ;
167172
168173 // Crate
169174 let krates = self . list_crates ( ) ?;
@@ -246,7 +251,33 @@ impl Thing {
246251 let mut zup_path = vec ! [ "flavors" ] ;
247252 zup_path. extend_from_slice ( & path[ 2 ..] ) ;
248253 let mut data = match zup. read ( & zup_path) {
249- Err ( e) if e. kind ( ) == ErrorKind :: NotFound => return self . resp_404 ( ) ,
254+ Err ( e) if e. kind ( ) == ErrorKind :: NotFound => {
255+ // check if it's due to incorrect flavor.
256+ if zup. open ( & [ "flavors" , path[ 3 ] ] ) . is_ok ( ) {
257+ // if flavor exists, path is wrong, so do 404.
258+ return self . resp_404 ( ) ;
259+ } else {
260+ // flavor doesn't exist, redirect to the default flavor.
261+ let cookies = self . cookies ( & req) ;
262+
263+ let flavors = self . list_flavors ( krate, version) ?;
264+ let flavor = cookies
265+ . get ( & format ! ( "crate-{}-flavor" , krate) )
266+ . map ( |s| s. as_str ( ) ) ;
267+ let mut flavor = flavor. unwrap_or ( & flavors[ 0 ] ) ;
268+ if flavors. iter ( ) . find ( |s| * s == flavor) . is_none ( ) {
269+ flavor = & flavors[ 0 ] ;
270+ }
271+
272+ return self . resp_redirect ( & format ! (
273+ "/{}/{}/{}/{}" ,
274+ krate,
275+ version,
276+ flavor,
277+ path[ 3 ..] . join( "/" )
278+ ) ) ;
279+ }
280+ }
250281 x => x?,
251282 }
252283 . into_owned ( ) ;
@@ -285,6 +316,14 @@ impl Thing {
285316 . into ( ) ;
286317 }
287318
319+ if link. starts_with ( b"/__DOCSERVER_DEPLINK/" ) {
320+ let link_path = std:: str:: from_utf8 ( & link[ 21 ..] ) . unwrap ( ) ;
321+ let ( krate, link_path) = link_path. split_once ( '/' ) . unwrap ( ) ;
322+ let ( _, link_path) = link_path. split_once ( '/' ) . unwrap ( ) ;
323+
324+ link = format ! ( "/{krate}/git/{flavor}/{link_path}" ) . into ( ) ;
325+ }
326+
288327 let mut res = Vec :: new ( ) ;
289328 res. extend_from_slice ( attr) ;
290329 res. extend_from_slice ( b"=" ) ;
0 commit comments