@@ -13,22 +13,18 @@ use std::collections::HashSet;
13
13
use std:: path:: PathBuf ;
14
14
use std:: str;
15
15
use std:: task:: Poll ;
16
- use std:: time:: Duration ;
17
16
18
17
use anyhow:: { bail, format_err, Context as _} ;
19
18
use crates_io:: { self , Registry } ;
20
- use curl:: easy:: { Easy , InfoType , SslOpt , SslVersion } ;
21
- use log:: { log, Level } ;
22
19
23
20
use crate :: core:: source:: Source ;
24
21
use crate :: core:: SourceId ;
25
22
use crate :: sources:: { RegistrySource , SourceConfigMap } ;
26
23
use crate :: util:: auth:: { self , Secret } ;
27
- use crate :: util:: config:: { Config , SslVersionConfig , SslVersionConfigRange } ;
24
+ use crate :: util:: config:: Config ;
28
25
use crate :: util:: errors:: CargoResult ;
29
- use crate :: util:: network;
26
+ use crate :: util:: network:: http :: http_handle ;
30
27
use crate :: util:: IntoUrl ;
31
- use crate :: version;
32
28
33
29
pub use self :: login:: registry_login;
34
30
pub use self :: logout:: registry_logout;
@@ -158,204 +154,6 @@ fn registry(
158
154
) )
159
155
}
160
156
161
- /// Creates a new HTTP handle with appropriate global configuration for cargo.
162
- pub fn http_handle ( config : & Config ) -> CargoResult < Easy > {
163
- let ( mut handle, timeout) = http_handle_and_timeout ( config) ?;
164
- timeout. configure ( & mut handle) ?;
165
- Ok ( handle)
166
- }
167
-
168
- pub fn http_handle_and_timeout ( config : & Config ) -> CargoResult < ( Easy , HttpTimeout ) > {
169
- if config. frozen ( ) {
170
- bail ! (
171
- "attempting to make an HTTP request, but --frozen was \
172
- specified"
173
- )
174
- }
175
- if config. offline ( ) {
176
- bail ! (
177
- "attempting to make an HTTP request, but --offline was \
178
- specified"
179
- )
180
- }
181
-
182
- // The timeout option for libcurl by default times out the entire transfer,
183
- // but we probably don't want this. Instead we only set timeouts for the
184
- // connect phase as well as a "low speed" timeout so if we don't receive
185
- // many bytes in a large-ish period of time then we time out.
186
- let mut handle = Easy :: new ( ) ;
187
- let timeout = configure_http_handle ( config, & mut handle) ?;
188
- Ok ( ( handle, timeout) )
189
- }
190
-
191
- // Only use a custom transport if any HTTP options are specified,
192
- // such as proxies or custom certificate authorities.
193
- //
194
- // The custom transport, however, is not as well battle-tested.
195
- pub fn needs_custom_http_transport ( config : & Config ) -> CargoResult < bool > {
196
- Ok (
197
- network:: proxy:: http_proxy_exists ( config. http_config ( ) ?, config)
198
- || * config. http_config ( ) ? != Default :: default ( )
199
- || config. get_env_os ( "HTTP_TIMEOUT" ) . is_some ( ) ,
200
- )
201
- }
202
-
203
- /// Configure a libcurl http handle with the defaults options for Cargo
204
- pub fn configure_http_handle ( config : & Config , handle : & mut Easy ) -> CargoResult < HttpTimeout > {
205
- let http = config. http_config ( ) ?;
206
- if let Some ( proxy) = network:: proxy:: http_proxy ( http) {
207
- handle. proxy ( & proxy) ?;
208
- }
209
- if let Some ( cainfo) = & http. cainfo {
210
- let cainfo = cainfo. resolve_path ( config) ;
211
- handle. cainfo ( & cainfo) ?;
212
- }
213
- if let Some ( check) = http. check_revoke {
214
- handle. ssl_options ( SslOpt :: new ( ) . no_revoke ( !check) ) ?;
215
- }
216
-
217
- if let Some ( user_agent) = & http. user_agent {
218
- handle. useragent ( user_agent) ?;
219
- } else {
220
- handle. useragent ( & format ! ( "cargo {}" , version( ) ) ) ?;
221
- }
222
-
223
- fn to_ssl_version ( s : & str ) -> CargoResult < SslVersion > {
224
- let version = match s {
225
- "default" => SslVersion :: Default ,
226
- "tlsv1" => SslVersion :: Tlsv1 ,
227
- "tlsv1.0" => SslVersion :: Tlsv10 ,
228
- "tlsv1.1" => SslVersion :: Tlsv11 ,
229
- "tlsv1.2" => SslVersion :: Tlsv12 ,
230
- "tlsv1.3" => SslVersion :: Tlsv13 ,
231
- _ => bail ! (
232
- "Invalid ssl version `{s}`,\
233
- choose from 'default', 'tlsv1', 'tlsv1.0', 'tlsv1.1', 'tlsv1.2', 'tlsv1.3'."
234
- ) ,
235
- } ;
236
- Ok ( version)
237
- }
238
-
239
- // Empty string accept encoding expands to the encodings supported by the current libcurl.
240
- handle. accept_encoding ( "" ) ?;
241
- if let Some ( ssl_version) = & http. ssl_version {
242
- match ssl_version {
243
- SslVersionConfig :: Single ( s) => {
244
- let version = to_ssl_version ( s. as_str ( ) ) ?;
245
- handle. ssl_version ( version) ?;
246
- }
247
- SslVersionConfig :: Range ( SslVersionConfigRange { min, max } ) => {
248
- let min_version = min
249
- . as_ref ( )
250
- . map_or ( Ok ( SslVersion :: Default ) , |s| to_ssl_version ( s) ) ?;
251
- let max_version = max
252
- . as_ref ( )
253
- . map_or ( Ok ( SslVersion :: Default ) , |s| to_ssl_version ( s) ) ?;
254
- handle. ssl_min_max_version ( min_version, max_version) ?;
255
- }
256
- }
257
- } else if cfg ! ( windows) {
258
- // This is a temporary workaround for some bugs with libcurl and
259
- // schannel and TLS 1.3.
260
- //
261
- // Our libcurl on Windows is usually built with schannel.
262
- // On Windows 11 (or Windows Server 2022), libcurl recently (late
263
- // 2022) gained support for TLS 1.3 with schannel, and it now defaults
264
- // to 1.3. Unfortunately there have been some bugs with this.
265
- // https://github.com/curl/curl/issues/9431 is the most recent. Once
266
- // that has been fixed, and some time has passed where we can be more
267
- // confident that the 1.3 support won't cause issues, this can be
268
- // removed.
269
- //
270
- // Windows 10 is unaffected. libcurl does not support TLS 1.3 on
271
- // Windows 10. (Windows 10 sorta had support, but it required enabling
272
- // an advanced option in the registry which was buggy, and libcurl
273
- // does runtime checks to prevent it.)
274
- handle. ssl_min_max_version ( SslVersion :: Default , SslVersion :: Tlsv12 ) ?;
275
- }
276
-
277
- if let Some ( true ) = http. debug {
278
- handle. verbose ( true ) ?;
279
- log:: debug!( "{:#?}" , curl:: Version :: get( ) ) ;
280
- handle. debug_function ( |kind, data| {
281
- let ( prefix, level) = match kind {
282
- InfoType :: Text => ( "*" , Level :: Debug ) ,
283
- InfoType :: HeaderIn => ( "<" , Level :: Debug ) ,
284
- InfoType :: HeaderOut => ( ">" , Level :: Debug ) ,
285
- InfoType :: DataIn => ( "{" , Level :: Trace ) ,
286
- InfoType :: DataOut => ( "}" , Level :: Trace ) ,
287
- InfoType :: SslDataIn | InfoType :: SslDataOut => return ,
288
- _ => return ,
289
- } ;
290
- let starts_with_ignore_case = |line : & str , text : & str | -> bool {
291
- line[ ..line. len ( ) . min ( text. len ( ) ) ] . eq_ignore_ascii_case ( text)
292
- } ;
293
- match str:: from_utf8 ( data) {
294
- Ok ( s) => {
295
- for mut line in s. lines ( ) {
296
- if starts_with_ignore_case ( line, "authorization:" ) {
297
- line = "Authorization: [REDACTED]" ;
298
- } else if starts_with_ignore_case ( line, "h2h3 [authorization:" ) {
299
- line = "h2h3 [Authorization: [REDACTED]]" ;
300
- } else if starts_with_ignore_case ( line, "set-cookie" ) {
301
- line = "set-cookie: [REDACTED]" ;
302
- }
303
- log ! ( level, "http-debug: {} {}" , prefix, line) ;
304
- }
305
- }
306
- Err ( _) => {
307
- log ! (
308
- level,
309
- "http-debug: {} ({} bytes of data)" ,
310
- prefix,
311
- data. len( )
312
- ) ;
313
- }
314
- }
315
- } ) ?;
316
- }
317
-
318
- HttpTimeout :: new ( config)
319
- }
320
-
321
- #[ must_use]
322
- pub struct HttpTimeout {
323
- pub dur : Duration ,
324
- pub low_speed_limit : u32 ,
325
- }
326
-
327
- impl HttpTimeout {
328
- pub fn new ( config : & Config ) -> CargoResult < HttpTimeout > {
329
- let http_config = config. http_config ( ) ?;
330
- let low_speed_limit = http_config. low_speed_limit . unwrap_or ( 10 ) ;
331
- let seconds = http_config
332
- . timeout
333
- . or_else ( || {
334
- config
335
- . get_env ( "HTTP_TIMEOUT" )
336
- . ok ( )
337
- . and_then ( |s| s. parse ( ) . ok ( ) )
338
- } )
339
- . unwrap_or ( 30 ) ;
340
- Ok ( HttpTimeout {
341
- dur : Duration :: new ( seconds, 0 ) ,
342
- low_speed_limit,
343
- } )
344
- }
345
-
346
- pub fn configure ( & self , handle : & mut Easy ) -> CargoResult < ( ) > {
347
- // The timeout option for libcurl by default times out the entire
348
- // transfer, but we probably don't want this. Instead we only set
349
- // timeouts for the connect phase as well as a "low speed" timeout so
350
- // if we don't receive many bytes in a large-ish period of time then we
351
- // time out.
352
- handle. connect_timeout ( self . dur ) ?;
353
- handle. low_speed_time ( self . dur ) ?;
354
- handle. low_speed_limit ( self . low_speed_limit ) ?;
355
- Ok ( ( ) )
356
- }
357
- }
358
-
359
157
/// Gets the SourceId for an index or registry setting.
360
158
///
361
159
/// The `index` and `reg` values are from the command-line or config settings.
0 commit comments