]> git.proxmox.com Git - cargo.git/commitdiff
modify to enum/struct and add test for SslVersionConfig
authorGuanqun Lu <guanqun.lu@gmail.com>
Sun, 29 Sep 2019 16:29:15 +0000 (00:29 +0800)
committerGuanqun Lu <guanqun.lu@gmail.com>
Sun, 29 Sep 2019 16:29:15 +0000 (00:29 +0800)
src/cargo/ops/registry.rs
src/cargo/util/config.rs
tests/testsuite/config.rs

index 12b94f27ff9ed5bf3f9a3a2fc9bace4dd0154718..a9c884f06840140c553390116480b946584928c0 100644 (file)
@@ -18,7 +18,7 @@ use crate::core::source::Source;
 use crate::core::{Package, SourceId, Workspace};
 use crate::ops;
 use crate::sources::{RegistrySource, SourceConfigMap, CRATES_IO_REGISTRY};
-use crate::util::config::{self, Config};
+use crate::util::config::{self, Config, SslVersionConfig, SslVersionConfigRange};
 use crate::util::errors::{CargoResult, CargoResultExt};
 use crate::util::important_paths::find_root_manifest_for_wd;
 use crate::util::IntoUrl;
@@ -413,16 +413,14 @@ pub fn needs_custom_http_transport(config: &Config) -> CargoResult<bool> {
     let cainfo = config.get_path("http.cainfo")?;
     let check_revoke = config.get_bool("http.check-revoke")?;
     let user_agent = config.get_string("http.user-agent")?;
-    let has_ssl_version = config.get_string("http.ssl-version")?.is_some()
-        || config.get_string("http.ssl-version.min")?.is_some()
-        || config.get_string("http.ssl-version.max")?.is_some();
+    let ssl_version = config.get::<SslVersionConfig>("http.ssl-version")?;
 
     Ok(proxy_exists
         || timeout
         || cainfo.is_some()
         || check_revoke.is_some()
         || user_agent.is_some()
-        || has_ssl_version)
+        || !ssl_version.is_empty())
 }
 
 /// Configure a libcurl http handle with the defaults options for Cargo
@@ -456,34 +454,18 @@ pub fn configure_http_handle(config: &Config, handle: &mut Easy) -> CargoResult<
         };
         Ok(version)
     }
-    if config.get_string("http.ssl-version")?.is_some()
-        || config.get_string("http.ssl-version.min")?.is_some()
-        || config.get_string("http.ssl-version.max")?.is_some() {
-
-        let mut min_version = SslVersion::Default;
-        let mut max_version = SslVersion::Default;
-
-        // There are two ways to configure `ssl-version`:
-        //   1. set single `ssl-version`
-        //      [http]
-        //      ssl-version = "tlsv1.3"
-        if let Some(ssl_version) = config.get_string("http.ssl-version")? {
-            min_version = to_ssl_version(ssl_version.val.as_str())?;
-            max_version = min_version;
-        }
-
-        //   2. set min and max of ssl version respectively
-        //      [http]
-        //      ssl-version.min = "tlsv1.2"
-        //      ssl-version.max = "tlsv1.3"
-        if let Some(ssl_version) = config.get_string("http.ssl-version.min")? {
-            min_version = to_ssl_version(ssl_version.val.as_str())?;
-        }
-        if let Some(ssl_version) = config.get_string("http.ssl-version.max")? {
-            max_version = to_ssl_version(ssl_version.val.as_str())?;
+    if let Some(ssl_version) = config.get::<Option<SslVersionConfig>>("http.ssl-version")? {
+        match ssl_version {
+            SslVersionConfig::Exactly(s) => {
+                let version = to_ssl_version(s.as_str())?;
+                handle.ssl_version(version)?;
+            },
+            SslVersionConfig::Range(SslVersionConfigRange{ min, max}) => {
+                let min_version = min.map_or(Ok(SslVersion::Default), |s| to_ssl_version(s.as_str()))?;
+                let max_version = max.map_or(Ok(SslVersion::Default), |s| to_ssl_version(s.as_str()))?;
+                handle.ssl_min_max_version(min_version, max_version)?;
+            }
         }
-
-        handle.ssl_min_max_version(min_version, max_version)?;
     }
 
     if let Some(true) = config.get::<Option<bool>>("http.debug")? {
index 5b69c1d123ae325876e920e1671a2ace93e657ee..85e3d721eea13d9f951323e66e5fb38fdbc4268e 100644 (file)
@@ -1854,3 +1854,40 @@ pub fn clippy_driver() -> PathBuf {
         .unwrap_or_else(|_| "clippy-driver".into())
         .into()
 }
+
+/// Configuration for `ssl-version` in `http` section
+/// There are two ways to configure:
+///
+/// ```text
+/// [http]
+/// ssl-version = "tlsv.13"
+/// ```
+///
+/// ```text
+/// [http]
+/// ssl-version.min = "tlsv1.2"
+/// ssl-version.max = "tlsv1.3"
+/// ```
+#[derive(Clone, Debug, Deserialize)]
+#[serde(untagged)]
+pub enum SslVersionConfig {
+    Exactly(String),
+    Range(SslVersionConfigRange),
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct SslVersionConfigRange {
+    pub min: Option<String>,
+    pub max: Option<String>,
+}
+
+impl SslVersionConfig {
+    pub fn is_empty(&self) -> bool {
+        match self {
+            SslVersionConfig::Exactly(_) => false,
+            SslVersionConfig::Range(SslVersionConfigRange{ min, max}) =>
+                min.is_none() && max.is_none(),
+        }
+    }
+}
+
index d65fe7a9af0325542fe2fb6ec9ecab88e0ca2359..3f51742ed8682902676f78945f39edc96425d444 100644 (file)
@@ -6,7 +6,7 @@ use std::os;
 use std::path::Path;
 
 use cargo::core::{enable_nightly_features, Shell};
-use cargo::util::config::{self, Config};
+use cargo::util::config::{self, Config, SslVersionConfig};
 use cargo::util::toml::{self, VecStringOrBool as VSOB};
 use cargo_test_support::{paths, project, t};
 use serde::Deserialize;
@@ -833,3 +833,79 @@ i64max = 9223372036854775807
          invalid value: integer `123456789`, expected i8",
     );
 }
+
+#[cargo_test]
+fn config_get_ssl_version_missing() {
+    write_config(
+        "\
+[http]
+hello = 'world'
+",
+    );
+
+    let config = new_config(&[]);
+
+    assert!(config.get::<Option<SslVersionConfig>>("http.ssl-version").unwrap().is_none());
+
+    let b =  config.get_string("http.ssl-version").unwrap();
+    println!("b: {:?}", if b.is_some() { "some" } else { "none" });
+}
+
+#[cargo_test]
+fn config_get_ssl_version_exact() {
+    write_config(
+        "\
+[http]
+ssl-version = 'tlsv1.2'
+",
+    );
+
+    let config = new_config(&[]);
+
+    let a = config.get::<Option<SslVersionConfig>>("http.ssl-version").unwrap().unwrap();
+    match a {
+        SslVersionConfig::Exactly(v) => assert_eq!(&v, "tlsv1.2"),
+        SslVersionConfig::Range(_) => panic!("Did not expect ssl version min/max."),
+    };
+}
+
+#[cargo_test]
+fn config_get_ssl_version_min_max() {
+    write_config(
+        "\
+[http]
+ssl-version.min = 'tlsv1.2'
+ssl-version.max = 'tlsv1.3'
+",
+    );
+
+    let config = new_config(&[]);
+
+    let a = config.get::<Option<SslVersionConfig>>("http.ssl-version").unwrap().unwrap();
+    match a {
+        SslVersionConfig::Exactly(_) => panic!("Did not expect exact ssl version."),
+        SslVersionConfig::Range(range) => {
+            assert_eq!(range.min, Some(String::from("tlsv1.2")));
+            assert_eq!(range.max, Some(String::from("tlsv1.3")));
+        }
+    };
+}
+
+#[cargo_test]
+fn config_get_ssl_version_both_forms_configured() {
+    // this is not allowed
+    write_config(
+        "\
+[http]
+ssl-version = 'tlsv1.1'
+ssl-version.min = 'tlsv1.2'
+ssl-version.max = 'tlsv1.3'
+",
+    );
+
+    let config = new_config(&[]);
+
+    assert!(config.get::<SslVersionConfig>("http.ssl-version").is_err());
+    assert!(config.get::<Option<SslVersionConfig>>("http.ssl-version").unwrap().is_none());
+}
+