77use std:: cmp:: Reverse ;
88use std:: str:: FromStr ;
99
10+ use conduit:: { Body , Response } ;
11+
1012use crate :: controllers:: frontend_prelude:: * ;
1113use crate :: controllers:: helpers:: pagination:: PaginationOptions ;
1214
@@ -15,6 +17,7 @@ use crate::models::{
1517 TopVersions , User , Version , VersionOwnerAction ,
1618} ;
1719use crate :: schema:: * ;
20+ use crate :: util:: errors:: not_found;
1821use crate :: views:: {
1922 EncodableCategory , EncodableCrate , EncodableDependency , EncodableKeyword , EncodableVersion ,
2023} ;
@@ -396,3 +399,60 @@ pub fn reverse_dependencies(req: &mut dyn RequestExt) -> EndpointResult {
396399 "meta" : { "total" : total } ,
397400 } ) ) )
398401}
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