diff --git a/crates/nu-command/src/commands/network/fetch.rs b/crates/nu-command/src/commands/network/fetch.rs index ffe89f3b9e..82b5df9898 100644 --- a/crates/nu-command/src/commands/network/fetch.rs +++ b/crates/nu-command/src/commands/network/fetch.rs @@ -36,6 +36,7 @@ impl WholeStreamCommand for Command { Some('p'), ) .switch("raw", "fetch contents as text rather than a table", Some('r')) + .switch("insecure", "allow insecure server connections when using SSL", Some('k')) .filter() } @@ -78,6 +79,7 @@ fn run_fetch(args: CommandArgs) -> Result { ) })?, fetch_helper.has_raw, + fetch_helper.has_insecure, fetch_helper.user.clone(), fetch_helper.password, ))] @@ -92,6 +94,7 @@ pub struct Fetch { pub path: Option, pub tag: Tag, pub has_raw: bool, + pub has_insecure: bool, pub user: Option, pub password: Option, } @@ -102,6 +105,7 @@ impl Fetch { path: None, tag: Tag::unknown(), has_raw: false, + has_insecure: false, user: None, password: None, } @@ -121,6 +125,8 @@ impl Fetch { self.has_raw = args.has_flag("raw"); + self.has_insecure = args.has_flag("insecure"); + self.user = args.get_flag("user")?; self.password = args.get_flag("password")?; @@ -132,13 +138,14 @@ impl Fetch { pub async fn fetch( path: &Value, has_raw: bool, + has_insecure: bool, user: Option, password: Option, ) -> ReturnValue { let path_str = path.as_string()?; let path_span = path.tag.span; - let result = helper(&path_str, path_span, has_raw, user, password).await; + let result = helper(&path_str, path_span, has_raw, has_insecure, user, password).await; if let Err(e) = result { return Err(e); @@ -168,6 +175,7 @@ async fn helper( location: &str, span: Span, has_raw: bool, + has_insecure: bool, user: Option, password: Option, ) -> std::result::Result<(Option, Value), ShellError> { @@ -188,7 +196,7 @@ async fn helper( _ => None, }; - let client = http_client(); + let client = http_client(has_insecure); let mut request = client.get(url); if let Some(login) = login { @@ -360,10 +368,10 @@ async fn helper( // Only panics if the user agent is invalid but we define it statically so either // it always or never fails -#[allow(clippy::unwrap_used)] -fn http_client() -> reqwest::Client { +fn http_client(allow_insecure: bool) -> reqwest::Client { reqwest::Client::builder() .user_agent("nushell") + .danger_accept_invalid_certs(allow_insecure) .build() - .unwrap() + .expect("Failed to build reqwest client") } diff --git a/crates/nu-command/src/commands/network/post.rs b/crates/nu-command/src/commands/network/post.rs index a3417bfa87..be472d4baa 100644 --- a/crates/nu-command/src/commands/network/post.rs +++ b/crates/nu-command/src/commands/network/post.rs @@ -53,6 +53,11 @@ impl WholeStreamCommand for Command { "return values as a string instead of a table", Some('r'), ) + .switch( + "insecure", + "allow insecure server connections when using SSL", + Some('k'), + ) .filter() } @@ -91,6 +96,7 @@ fn run_post(args: CommandArgs) -> Result { ShellError::labeled_error("expected a 'path'", "expected a 'path'", &helper.tag) })?, helper.has_raw, + helper.has_insecure, &helper.body.clone().ok_or_else(|| { ShellError::labeled_error("expected a 'body'", "expected a 'body'", &helper.tag) })?, @@ -114,6 +120,7 @@ pub enum HeaderKind { pub struct Post { pub path: Option, pub has_raw: bool, + pub has_insecure: bool, pub body: Option, pub user: Option, pub password: Option, @@ -126,6 +133,7 @@ impl Post { Post { path: None, has_raw: false, + has_insecure: false, body: None, user: None, password: None, @@ -156,6 +164,8 @@ impl Post { self.has_raw = args.has_flag("raw"); + self.has_insecure = args.has_flag("insecure"); + self.user = args.get_flag("user")?; self.password = args.get_flag("password")?; @@ -169,6 +179,7 @@ impl Post { pub async fn post_helper( path: &Value, has_raw: bool, + has_insecure: bool, body: &Value, user: Option, password: Option, @@ -177,8 +188,16 @@ pub async fn post_helper( let path_tag = path.tag.clone(); let path_str = path.as_string()?; - let (file_extension, contents, contents_tag) = - post(&path_str, body, user, password, headers, path_tag.clone()).await?; + let (file_extension, contents, contents_tag) = post( + &path_str, + has_insecure, + body, + user, + password, + headers, + path_tag.clone(), + ) + .await?; let file_extension = if has_raw { None @@ -202,6 +221,7 @@ pub async fn post_helper( pub async fn post( location: &str, + allow_insecure: bool, body: &Value, user: Option, password: Option, @@ -219,7 +239,9 @@ pub async fn post( value: UntaggedValue::Primitive(Primitive::String(body_str)), .. } => { - let mut s = http_client().post(location).body(body_str.to_string()); + let mut s = http_client(allow_insecure) + .post(location) + .body(body_str.to_string()); if let Some(login) = login { s = s.header("Authorization", format!("Basic {}", login)); } @@ -237,7 +259,9 @@ pub async fn post( value: UntaggedValue::Primitive(Primitive::Binary(b)), .. } => { - let mut s = http_client().post(location).body(Vec::from(&b[..])); + let mut s = http_client(allow_insecure) + .post(location) + .body(Vec::from(&b[..])); if let Some(login) = login { s = s.header("Authorization", format!("Basic {}", login)); } @@ -247,7 +271,9 @@ pub async fn post( match value_to_json_value(&value.clone().into_untagged_value()) { Ok(json_value) => match serde_json::to_string(&json_value) { Ok(result_string) => { - let mut s = http_client().post(location).body(result_string); + let mut s = http_client(allow_insecure) + .post(location) + .body(result_string); if let Some(login) = login { s = s.header("Authorization", format!("Basic {}", login)); @@ -611,10 +637,10 @@ fn extract_header_value(args: &CommandArgs, key: &str) -> Result, // Only panics if the user agent is invalid but we define it statically so either // it always or never fails -#[allow(clippy::unwrap_used)] -fn http_client() -> reqwest::Client { +fn http_client(allow_insecure: bool) -> reqwest::Client { reqwest::Client::builder() .user_agent("nushell") + .danger_accept_invalid_certs(allow_insecure) .build() - .unwrap() + .expect("Failed to build reqwest client") }