diff --git a/crates/nu-command/src/network/http/client.rs b/crates/nu-command/src/network/http/client.rs index 7afd114024..3729b37a43 100644 --- a/crates/nu-command/src/network/http/client.rs +++ b/crates/nu-command/src/network/http/client.rs @@ -7,6 +7,7 @@ use base64::{ use multipart_rs::MultipartWriter; use nu_engine::command_prelude::*; use nu_protocol::{ByteStream, LabeledError, Signals}; +use serde_json::Value as JsonValue; use std::{ collections::HashMap, io::Cursor, @@ -257,24 +258,37 @@ fn send_json_request( span: Span, signals: &Signals, ) -> Result { - let data = match body { + match body { Value::Int { .. } | Value::List { .. } | Value::Record { .. } => { - value_to_json_value(&body)? + let data = value_to_json_value(&body)?; + send_cancellable_request(request_url, Box::new(|| req.send_json(data)), span, signals) } // If the body type is string, assume it is string json content. // If parsing fails, just send the raw string Value::String { val: s, .. } => { - serde_json::from_str(&s).unwrap_or_else(|_| nu_json::Value::String(s)) + if let Ok(jvalue) = serde_json::from_str::(&s) { + send_cancellable_request( + request_url, + Box::new(|| req.send_json(jvalue)), + span, + signals, + ) + } else { + let data = serde_json::from_str(&s).unwrap_or_else(|_| nu_json::Value::String(s)); + send_cancellable_request( + request_url, + Box::new(|| req.send_json(data)), + span, + signals, + ) + } } - _ => { - return Err(ShellErrorOrRequestError::ShellError( - ShellError::UnsupportedHttpBody { - msg: format!("Accepted types: [Int, List, String, Record]. Check: {HTTP_DOCS}"), - }, - )) - } - }; - send_cancellable_request(request_url, Box::new(|| req.send_json(data)), span, signals) + _ => Err(ShellErrorOrRequestError::ShellError( + ShellError::UnsupportedHttpBody { + msg: format!("Accepted types: [Int, List, String, Record]. Check: {HTTP_DOCS}"), + }, + )), + } } fn send_form_request( diff --git a/crates/nu-command/src/network/http/patch.rs b/crates/nu-command/src/network/http/patch.rs index 09741c7492..eeebaf55a8 100644 --- a/crates/nu-command/src/network/http/patch.rs +++ b/crates/nu-command/src/network/http/patch.rs @@ -126,7 +126,7 @@ impl Command for SubCommand { }, Example { description: "Patch JSON content from a pipeline to example.com", - example: "open foo.json | http patch https://www.example.com", + example: "open --raw foo.json | http patch https://www.example.com", result: None, }, ] diff --git a/crates/nu-command/src/network/http/post.rs b/crates/nu-command/src/network/http/post.rs index f57953ea42..f38f7aeed3 100644 --- a/crates/nu-command/src/network/http/post.rs +++ b/crates/nu-command/src/network/http/post.rs @@ -124,7 +124,7 @@ impl Command for SubCommand { }, Example { description: "Post JSON content from a pipeline to example.com", - example: "open foo.json | http post https://www.example.com", + example: "open --raw foo.json | http post https://www.example.com", result: None, }, Example { diff --git a/crates/nu-command/src/network/http/put.rs b/crates/nu-command/src/network/http/put.rs index ea7c722c4c..0494f5ea0e 100644 --- a/crates/nu-command/src/network/http/put.rs +++ b/crates/nu-command/src/network/http/put.rs @@ -124,7 +124,7 @@ impl Command for SubCommand { }, Example { description: "Put JSON content from a pipeline to example.com", - example: "open foo.json | http put https://www.example.com", + example: "open --raw foo.json | http put https://www.example.com", result: None, }, ] diff --git a/crates/nu-command/tests/commands/network/http/post.rs b/crates/nu-command/tests/commands/network/http/post.rs index 6fbcb03b69..44dde270c1 100644 --- a/crates/nu-command/tests/commands/network/http/post.rs +++ b/crates/nu-command/tests/commands/network/http/post.rs @@ -115,6 +115,24 @@ fn http_post_json_is_success() { assert!(actual.out.is_empty()) } +#[test] +fn http_post_json_string_is_success() { + let mut server = Server::new(); + + let mock = server + .mock("POST", "/") + .match_body(r#"{"foo":"bar"}"#) + .create(); + + let actual = nu!(format!( + r#"http post -t 'application/json' {url} '{{"foo":"bar"}}'"#, + url = server.url() + )); + + mock.assert(); + assert!(actual.out.is_empty()) +} + #[test] fn http_post_json_list_is_success() { let mut server = Server::new(); @@ -149,7 +167,7 @@ fn http_post_json_int_is_success() { } #[test] -fn http_post_json_string_is_success() { +fn http_post_json_raw_string_is_success() { let mut server = Server::new(); let mock = server.mock("POST", "/").match_body(r#""test""#).create();