@@ -7,19 +7,15 @@ use prefix::InstallPrefix;
7
7
use manifest:: Component ;
8
8
use manifest:: Manifest as ManifestV2 ;
9
9
use manifestation:: { Manifestation , UpdateStatus , Changes } ;
10
+ use download:: { DownloadCfg } ;
10
11
11
- use std:: path:: { Path , PathBuf } ;
12
- use std:: ops;
13
- use url:: Url ;
12
+ use std:: path:: Path ;
14
13
use std:: fmt;
15
14
use std:: env;
16
- use std:: fs;
17
15
18
16
use regex:: Regex ;
19
- use sha2:: { Sha256 , Digest } ;
20
17
21
18
pub const DEFAULT_DIST_SERVER : & ' static str = "https://static.rust-lang.org" ;
22
- pub const UPDATE_HASH_LEN : usize = 20 ;
23
19
24
20
// Deprecated
25
21
pub const DEFAULT_DIST_ROOT : & ' static str = "https://static.rust-lang.org/dist" ;
@@ -440,168 +436,6 @@ impl fmt::Display for ToolchainDesc {
440
436
}
441
437
}
442
438
443
- pub fn download_and_check < ' a > ( url_str : & str ,
444
- update_hash : Option < & Path > ,
445
- ext : & str ,
446
- cfg : DownloadCfg < ' a > )
447
- -> Result < Option < ( temp:: File < ' a > , String ) > > {
448
- let hash = try!( download_hash ( url_str, cfg) ) ;
449
- let partial_hash: String = hash. chars ( ) . take ( UPDATE_HASH_LEN ) . collect ( ) ;
450
-
451
- if let Some ( hash_file) = update_hash {
452
- if utils:: is_file ( hash_file) {
453
- if let Ok ( contents) = utils:: read_file ( "update hash" , hash_file) {
454
- if contents == partial_hash {
455
- // Skip download, update hash matches
456
- return Ok ( None ) ;
457
- }
458
- } else {
459
- ( cfg. notify_handler ) ( Notification :: CantReadUpdateHash ( hash_file) ) ;
460
- }
461
- } else {
462
- ( cfg. notify_handler ) ( Notification :: NoUpdateHash ( hash_file) ) ;
463
- }
464
- }
465
-
466
- let url = try!( utils:: parse_url ( url_str) ) ;
467
- let file = try!( cfg. temp_cfg . new_file_with_ext ( "" , ext) ) ;
468
-
469
- let mut hasher = Sha256 :: new ( ) ;
470
- try!( utils:: download_file ( & url,
471
- & file,
472
- Some ( & mut hasher) ,
473
- & |n| ( cfg. notify_handler ) ( n. into ( ) ) ) ) ;
474
- let actual_hash = hasher. result_str ( ) ;
475
-
476
- if hash != actual_hash {
477
- // Incorrect hash
478
- return Err ( ErrorKind :: ChecksumFailed {
479
- url : url_str. to_owned ( ) ,
480
- expected : hash,
481
- calculated : actual_hash,
482
- }
483
- . into ( ) ) ;
484
- } else {
485
- ( cfg. notify_handler ) ( Notification :: ChecksumValid ( url_str) ) ;
486
- }
487
-
488
- // TODO: Check the signature of the file
489
-
490
- Ok ( Some ( ( file, partial_hash) ) )
491
- }
492
-
493
- #[ derive( Copy , Clone ) ]
494
- pub struct DownloadCfg < ' a > {
495
- pub dist_root : & ' a str ,
496
- pub temp_cfg : & ' a temp:: Cfg ,
497
- pub download_dir : & ' a PathBuf ,
498
- pub notify_handler : & ' a Fn ( Notification ) ,
499
- }
500
-
501
-
502
- pub struct File {
503
- path : PathBuf ,
504
- }
505
-
506
- impl ops:: Deref for File {
507
- type Target = Path ;
508
-
509
- fn deref ( & self ) -> & Path {
510
- ops:: Deref :: deref ( & self . path )
511
- }
512
- }
513
-
514
- fn file_hash ( path : & Path ) -> Result < String > {
515
- let mut hasher = Sha256 :: new ( ) ;
516
- use std:: io:: Read ;
517
- let mut downloaded = try!( fs:: File :: open ( & path) . chain_err ( || "opening already downloaded file" ) ) ;
518
- let mut buf = vec ! [ 0 ; 32768 ] ;
519
- loop {
520
- if let Ok ( n) = downloaded. read ( & mut buf) {
521
- if n == 0 { break ; }
522
- hasher. input ( & buf[ ..n] ) ;
523
- } else {
524
- break ;
525
- }
526
- }
527
-
528
- Ok ( hasher. result_str ( ) )
529
- }
530
-
531
- impl < ' a > DownloadCfg < ' a > {
532
-
533
- pub fn download ( & self , url : & Url , hash : & str , notify_handler : & ' a Fn ( Notification ) ) -> Result < File > {
534
-
535
- try!( utils:: ensure_dir_exists ( "Download Directory" , & self . download_dir , & |n| notify_handler ( n. into ( ) ) ) ) ;
536
- let target_file = self . download_dir . join ( Path :: new ( hash) ) ;
537
-
538
- if target_file. exists ( ) {
539
- let cached_result = try!( file_hash ( & target_file) ) ;
540
- if hash == cached_result {
541
- notify_handler ( Notification :: FileAlreadyDownloaded ) ;
542
- notify_handler ( Notification :: ChecksumValid ( & url. to_string ( ) ) ) ;
543
- return Ok ( File { path : target_file, } ) ;
544
- } else {
545
- notify_handler ( Notification :: CachedFileChecksumFailed ) ;
546
- try!( fs:: remove_file ( & target_file) . chain_err ( || "cleaning up previous download" ) ) ;
547
- }
548
- }
549
-
550
-
551
- let partial_file_path =
552
- target_file. with_file_name (
553
- target_file. file_name ( ) . map ( |s| {
554
- s. to_str ( ) . unwrap_or ( "_" ) } )
555
- . unwrap_or ( "_" )
556
- . to_owned ( )
557
- + ".partial" ) ;
558
-
559
- let mut hasher = Sha256 :: new ( ) ;
560
-
561
- try!( utils:: download_file_with_resume ( & url,
562
- & partial_file_path,
563
- Some ( & mut hasher) ,
564
- true ,
565
- & |n| notify_handler ( n. into ( ) ) ) ) ;
566
-
567
- let actual_hash = hasher. result_str ( ) ;
568
-
569
- if hash != actual_hash {
570
- // Incorrect hash
571
- return Err ( ErrorKind :: ChecksumFailed {
572
- url : url. to_string ( ) ,
573
- expected : hash. to_string ( ) ,
574
- calculated : actual_hash,
575
- } . into ( ) ) ;
576
- } else {
577
- notify_handler ( Notification :: ChecksumValid ( & url. to_string ( ) ) ) ;
578
- try!( fs:: rename ( & partial_file_path, & target_file) ) ;
579
- return Ok ( File { path : target_file } ) ;
580
- }
581
- }
582
-
583
- pub fn clean ( & self , hashes : & Vec < String > ) -> Result < ( ) > {
584
- for hash in hashes. iter ( ) {
585
- let used_file = self . download_dir . join ( hash) ;
586
- if self . download_dir . join ( & used_file) . exists ( ) {
587
- try!( fs:: remove_file ( used_file) . chain_err ( || "cleaning up cached downloads" ) ) ;
588
- }
589
- }
590
- Ok ( ( ) )
591
- }
592
- }
593
-
594
- pub fn download_hash ( url : & str , cfg : DownloadCfg ) -> Result < String > {
595
- let hash_url = try!( utils:: parse_url ( & ( url. to_owned ( ) + ".sha256" ) ) ) ;
596
- let hash_file = try!( cfg. temp_cfg . new_file ( ) ) ;
597
-
598
- try!( utils:: download_file ( & hash_url,
599
- & hash_file,
600
- None ,
601
- & |n| ( cfg. notify_handler ) ( n. into ( ) ) ) ) ;
602
-
603
- Ok ( try!( utils:: read_file ( "hash" , & hash_file) . map ( |s| s[ 0 ..64 ] . to_owned ( ) ) ) )
604
- }
605
439
606
440
// Installs or updates a toolchain from a dist server. If an initial
607
441
// install then it will be installed with the default components. If
@@ -711,7 +545,7 @@ fn dl_v2_manifest<'a>(download: DownloadCfg<'a>,
711
545
toolchain : & ToolchainDesc )
712
546
-> Result < Option < ( ManifestV2 , String ) > > {
713
547
let manifest_url = toolchain. manifest_v2_url ( download. dist_root ) ;
714
- let manifest_dl_res = download_and_check ( & manifest_url, update_hash, ".toml" , download ) ;
548
+ let manifest_dl_res = download . download_and_check ( & manifest_url, update_hash, ".toml" ) ;
715
549
716
550
if let Ok ( manifest_dl) = manifest_dl_res {
717
551
// Downloaded ok!
@@ -751,7 +585,7 @@ fn dl_v1_manifest<'a>(download: DownloadCfg<'a>, toolchain: &ToolchainDesc) -> R
751
585
}
752
586
753
587
let manifest_url = toolchain. manifest_v1_url ( download. dist_root ) ;
754
- let manifest_dl = try!( download_and_check ( & manifest_url, None , "" , download ) ) ;
588
+ let manifest_dl = try!( download . download_and_check ( & manifest_url, None , "" ) ) ;
755
589
let ( manifest_file, _) = manifest_dl. unwrap ( ) ;
756
590
let manifest_str = try!( utils:: read_file ( "manifest" , & manifest_file) ) ;
757
591
let urls = manifest_str. lines ( ) . map ( |s| format ! ( "{}/{}" , root_url, s) ) . collect ( ) ;
0 commit comments