1
1
use curl;
2
2
use git2;
3
+ use url:: Url ;
3
4
4
5
use failure:: Error ;
5
6
@@ -33,6 +34,35 @@ fn maybe_spurious(err: &Error) -> bool {
33
34
false
34
35
}
35
36
37
+
38
+ /// Suggest the user to update their windows 7 to support modern TLS versions.
39
+ /// See https://github.com/rust-lang/cargo/issues/5066 for details.
40
+ #[ cfg( windows) ]
41
+ fn should_warn_about_old_tls_for_win7 ( url : & Url , err : & Error ) -> bool {
42
+ let is_github = url. host_str ( ) == Some ( "github.com" ) ;
43
+ let is_cert_error = err. causes ( )
44
+ . filter_map ( |e| e. downcast_ref :: < git2:: Error > ( ) )
45
+ . find ( |e| e. class ( ) == git2:: ErrorClass :: Net && e. code ( ) == git2:: ErrorCode :: Certificate )
46
+ . is_some ( ) ;
47
+ is_github && is_cert_error
48
+ }
49
+
50
+ #[ cfg( not( windows) ) ]
51
+ fn should_warn_about_old_tls_for_win7 ( _url : & Url , _err : & Error ) -> bool {
52
+ false
53
+ }
54
+
55
+ const WIN7_TLS_WARNING : & str = "\
56
+ Certificate check failure might be caused by outdated TLS on older versions of Windows.
57
+ If you are using Windows 7, Windows Server 2008 R2 or Windows Server 2012,
58
+ please follow these instructions to enable more secure TLS:
59
+
60
+ https://support.microsoft.com/en-us/help/3140245/
61
+
62
+ See https://github.com/rust-lang/cargo/issues/5066 for details.
63
+ " ;
64
+
65
+
36
66
/// Wrapper method for network call retry logic.
37
67
///
38
68
/// Retry counts provided by Config object `net.retry`. Config shell outputs
@@ -44,19 +74,24 @@ fn maybe_spurious(err: &Error) -> bool {
44
74
///
45
75
/// ```ignore
46
76
/// use util::network;
47
- /// cargo_result = network. with_retry(&config, || something.download());
77
+ /// cargo_result = network:: with_retry(&config, || something.download());
48
78
/// ```
49
- pub fn with_retry < T , F > ( config : & Config , mut callback : F ) -> CargoResult < T >
79
+ pub fn with_retry < T , F > ( config : & Config , url : & Url , mut callback : F ) -> CargoResult < T >
50
80
where F : FnMut ( ) -> CargoResult < T >
51
81
{
52
82
let mut remaining = config. net_retry ( ) ?;
53
83
loop {
54
84
match callback ( ) {
55
85
Ok ( ret) => return Ok ( ret) ,
56
86
Err ( ref e) if maybe_spurious ( e) && remaining > 0 => {
57
- let msg = format ! ( "spurious network error ({} tries \
58
- remaining): {}", remaining, e) ;
59
- config. shell ( ) . warn ( msg) ?;
87
+ config. shell ( ) . warn (
88
+ format ! ( "spurious network error ({} tries remaining): {}" , remaining, e)
89
+ ) ?;
90
+
91
+ if should_warn_about_old_tls_for_win7 ( url, e) {
92
+ config. shell ( ) . warn ( WIN7_TLS_WARNING ) ?;
93
+ }
94
+
60
95
remaining -= 1 ;
61
96
}
62
97
//todo impl from
@@ -71,7 +106,8 @@ fn with_retry_repeats_the_call_then_works() {
71
106
let error2 = HttpNot200 { code : 502 , url : "Uri" . to_string ( ) } . into ( ) ;
72
107
let mut results: Vec < CargoResult < ( ) > > = vec ! [ Ok ( ( ) ) , Err ( error1) , Err ( error2) ] ;
73
108
let config = Config :: default ( ) . unwrap ( ) ;
74
- let result = with_retry ( & config, || results. pop ( ) . unwrap ( ) ) ;
109
+ let url = "http://example.com" . parse ( ) . unwrap ( ) ;
110
+ let result = with_retry ( & config, & url, || results. pop ( ) . unwrap ( ) ) ;
75
111
assert_eq ! ( result. unwrap( ) , ( ) )
76
112
}
77
113
@@ -87,6 +123,7 @@ fn with_retry_finds_nested_spurious_errors() {
87
123
let error2 = CargoError :: from ( error2. context ( "A second chained error" ) ) ;
88
124
let mut results: Vec < CargoResult < ( ) > > = vec ! [ Ok ( ( ) ) , Err ( error1) , Err ( error2) ] ;
89
125
let config = Config :: default ( ) . unwrap ( ) ;
90
- let result = with_retry ( & config, || results. pop ( ) . unwrap ( ) ) ;
126
+ let url = "http://example.com" . parse ( ) . unwrap ( ) ;
127
+ let result = with_retry ( & config, & url, || results. pop ( ) . unwrap ( ) ) ;
91
128
assert_eq ! ( result. unwrap( ) , ( ) )
92
129
}
0 commit comments