7
7
use std:: cmp:: Reverse ;
8
8
use std:: str:: FromStr ;
9
9
10
+ use conduit:: { Body , Response } ;
11
+
10
12
use crate :: controllers:: frontend_prelude:: * ;
11
13
use crate :: controllers:: helpers:: pagination:: PaginationOptions ;
12
14
@@ -15,6 +17,7 @@ use crate::models::{
15
17
TopVersions , User , Version , VersionOwnerAction ,
16
18
} ;
17
19
use crate :: schema:: * ;
20
+ use crate :: util:: errors:: not_found;
18
21
use crate :: views:: {
19
22
EncodableCategory , EncodableCrate , EncodableDependency , EncodableKeyword , EncodableVersion ,
20
23
} ;
@@ -396,3 +399,60 @@ pub fn reverse_dependencies(req: &mut dyn RequestExt) -> EndpointResult {
396
399
"meta" : { "total" : total } ,
397
400
} ) ) )
398
401
}
402
+
403
+ /// Generate the sparse registry config.json file
404
+ pub fn config_json ( req : & mut dyn RequestExt ) -> EndpointResult {
405
+ let headers = req. headers ( ) ;
406
+ let proto = headers
407
+ . get ( "X-Forwarded-Proto" )
408
+ . and_then ( |v| v. to_str ( ) . ok ( ) )
409
+ . unwrap_or_else ( || {
410
+ if req. app ( ) . config . env ( ) == crate :: Env :: Development {
411
+ "http"
412
+ } else {
413
+ "https"
414
+ }
415
+ } ) ;
416
+ let domain_name = headers
417
+ . get ( "X-Forwarded-Host" )
418
+ . or_else ( || headers. get ( http:: header:: HOST ) )
419
+ . and_then ( |v| v. to_str ( ) . ok ( ) )
420
+ . unwrap_or_else ( || & req. app ( ) . config . domain_name ) ;
421
+
422
+ let dl = format ! ( "{proto}://{domain_name}/api/v1/crates" ) ;
423
+ let api = format ! ( "{proto}://{domain_name}/" ) ;
424
+
425
+ #[ derive( Serialize ) ]
426
+ struct R {
427
+ dl : String ,
428
+ api : String ,
429
+ }
430
+ Ok ( req. json ( & R { dl, api } ) )
431
+ }
432
+
433
+ /// Generate a sparse registry index file
434
+ pub fn versions_registry ( req : & mut dyn RequestExt ) -> EndpointResult {
435
+ let crate_name = & req. params ( ) [ "crate_id" ] ;
436
+
437
+ let x1 = req. params ( ) [ "x1" ] . as_str ( ) ;
438
+ let x2 = req. params ( ) . find ( "x2" ) ;
439
+ if ( x1, x2)
440
+ != match crate_name. len ( ) {
441
+ 1 => ( "1" , None ) ,
442
+ 2 => ( "2" , None ) ,
443
+ 3 => ( "3" , Some ( & crate_name[ 0 ..1 ] ) ) ,
444
+ _ => ( & crate_name[ 0 ..2 ] , Some ( & crate_name[ 2 ..4 ] ) ) ,
445
+ }
446
+ {
447
+ return Err ( not_found ( ) ) ;
448
+ }
449
+
450
+ let conn = req. db_read ( ) ?;
451
+ let krate: Crate = Crate :: by_name ( crate_name) . first ( & * conn) ?;
452
+ let body = krate. index_metadata ( & * conn) ?;
453
+
454
+ Ok ( Response :: builder ( )
455
+ . header ( header:: CONTENT_TYPE , "text/plain; charset=utf-8" )
456
+ . body ( Body :: from_vec ( body) )
457
+ . unwrap ( ) ) // Header values are well formed, so should not panic
458
+ }
0 commit comments