Rust: View entire Command::New command arguement structs as its passed to terminal / correct my arguements - linux

I am not getting the correct response from the server running the following
Command::new("curl")
.args(&["-X",
"POST",
"--header",
&("Authorization: Bearer ".to_owned() + &return_token("auth")),
"--header",
"Content-Type: application/json",
"-d",
parameters,
"https://api.tdameritrade.com/v1/accounts/CORRECT_ACCOUNT_#/orders",
])
.output()
.unwrap()
.stdout;
Command::new("curl")
.arg("-X")
.arg("POST")
.arg("--header")
.arg("Authorization: Bearer ".to_owned() + &return_token("auth"))
.arg("--header")
.arg("Content-Type: application/json")
.arg("-d")
.arg(parameters)
.arg("https://api.tdameritrade.com/v1/accounts/CORRECT_ACCOUNT_#/orders")
.output()
.unwrap()
.stdout;
However.... the following works fine if I run it in terminal. I form the following using let line = "curl -X POST --header \"Authorization: Bearer ".to_owned() + &return_token("auth") + "\" --header \"Content-Type: application/json\" -d " + parameters + " \"https://api.tdameritrade.com/v1/accounts/CORRECT_ACCOUNT_#/orders\"";
curl -X POST --header "Authorization: Bearer LONG_RANDOM_AUTH_TOKEN" --header "Content-Type: application/json" -d "{
\"complexOrderStrategyType\": \"NONE\",
\"orderType\": \"LIMIT\",
\"session\": \"NORMAL\",
\"price\": \"0.01\",
\"duration\": \"DAY\",
\"orderStrategyType\": \"SINGLE\",
\"orderLegCollection\": [
{
\"instruction\": \"BUY_TO_OPEN\",
\"quantity\": 1,
\"instrument\": {
\"symbol\": \"SPY_041621P190\",
\"assetType\": \"OPTION\"
}
}
]
}" "https://api.tdameritrade.com/v1/accounts/CORRECT_ACCOUNT_#/orders"
"parameters" can be seen above in JSON.
How can do I view the formation of the command that Command::New is making or correct my args?
EDIT Ive tried using a single quote around the JSON and not escaping the double quotes, which also works in the terminal.
EDIT Example included. I found this : https://github.com/rust-lang/rust/issues/29494 && https://users.rust-lang.org/t/std-process-is-escaping-a-raw-string-literal-when-i-dont-want-it-to/19441/14
However Im in linux...
fn main() {
// None of the following work
let parameters = r#"{"complexOrderStrategyType":"NONE","orderType":"LIMIT","session":"NORMAL","price":"0.01","duration":"DAY","orderStrategyType":"SINGLE","orderLegCollection":[{"instruction":"BUY_TO_OPEN","quantity":1,"instrument":{"symbol":"SPY_041621P190","assetType":"OPTION"}}]}"#;
// OR
let parameters = "'{\"complexOrderStrategyType\":\"NONE\",\"orderType\": \"LIMIT\",\"session\": \"NORMAL\",\"price\": \"0.01\",\"duration\": \"DAY\",\"orderStrategyType\": \"SINGLE\",\"orderLegCollection\": [{\"instruction\": \"BUY_TO_OPEN\",\"quantity\": 1,\"instrument\": {\"symbol\": \"SPY_041621P190\",\"assetType\": \"OPTION\"}}]}'";
// OR
let parameters = "{\"complexOrderStrategyType\":\"NONE\",\"orderType\": \"LIMIT\",\"session\": \"NORMAL\",\"price\": \"0.01\",\"duration\": \"DAY\",\"orderStrategyType\": \"SINGLE\",\"orderLegCollection\": [{\"instruction\": \"BUY_TO_OPEN\",\"quantity\": 1,\"instrument\": {\"symbol\": \"SPY_041621P190\",\"assetType\": \"OPTION\"}}]}";
// OR
let parameters = "{'complexOrderStrategyType':'NONE','orderType': 'LIMIT','session': 'NORMAL','price': '0.01','duration': 'DAY','orderStrategyType': 'SINGLE','orderLegCollection': [{'instruction': 'BUY_TO_OPEN','quantity': 1,'instrument': {'symbol': 'SPY_041621P190','assetType': 'OPTION'}}]}";
println!("{:?}", str::from_utf8(&curl(parameters, "ORDER")).unwrap());
fn curl(parameters: &str, request_type: &str) -> Vec<u8> {
let mut output = Vec::new();
if request_type == "ORDER" {
output = Command::new("curl")
.args(&[
"-X",
"POST",
"--header",
"Authorization: Bearer AUTH_KEY_NOT_INCLUDED",
"--header",
"Content-Type: application/json",
"-d",
parameters,
"https://api.tdameritrade.com/v1/accounts/ACCOUNT_NUMBER_NOT_INCLUDED/orders",
])
.output()
.unwrap()
.stdout;
}
output
}
}

For reasons unknown... changing the --header switch / flag to -H solved the problem. As shown in the following. Spoke with a friend and apparently the shortened form may take different parameters.
let parameters = "{
\"complexOrderStrategyType\": \"NONE\",
\"orderType\": \"LIMIT\",
\"session\": \"NORMAL\",
\"price\": \"0.01\",
\"duration\": \"DAY\",
\"orderStrategyType\": \"SINGLE\",
\"orderLegCollection\": [
{
\"instruction\": \"BUY_TO_OPEN\",
\"quantity\": 1,
\"instrument\": {
\"symbol\": \"SPY_041621P190\",
\"assetType\": \"OPTION\"
}
}
]
}";
Command::new("curl")
.args(&["-X",
"POST",
"-H",
&("Authorization: Bearer ".to_owned() + &return_token("auth")),
"-H",
"Content-Type: application/json",
"-d",
parameters,
"https://api.tdameritrade.com/v1/accounts/ACCOUNT/orders",
])
.output()
.unwrap()
.stdout;

Related

Unable to get data using requests.get while it works with curl

Im trying to get response using RESTCONF. When i use CURL as:
curl -X GET -H "Accept: application/yang-data+json" -H "Content-Type: application/yang-data+json" -k https://user:pass#IP/api/data/switch:opm/port={1,2}
I get output perfectly as
"switch:port": {
"port-id": 1,
"wavelength": "0000.0",
"offset": "0.0",
"averaging-time": 4 } } { "switch:port": {
"port-id": 2,
"wavelength": "0000.0",
"offset": "0.0",
"averaging-time": 0 } }
But when i use requests.get in python as:
url ="""https://IP/api/data/switch:opm/port={1,2}"""
response = requests.get(url,headers=self.header,auth =(self.username1,self.password1),verify=False)
I get response 404.
I tried port=1 and it works fine in python too. Facing issues when i use port={1,2}.

Reqwest May Not Be Detecting My URL, Request Not Sending Request

reqwest gives me the following error when trying to send a post request:
Error: Response { url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("eastus.tts.speech.microsoft.com")), port: None, path: "/cognitiveservices/v1", query: None, fragment: None }, status: 400, headers: {"date": "Thu, 18 Aug 2022 21:48:56 GMT", "transfer-encoding": "chunked", "connection": "keep-alive", "strict-transport-security": "max-age=15724800; includeSubDomains"} }
With the following code:
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let url: String = "https://eastus.tts.speech.microsoft.com/cognitiveservices/v1".to_string();
let body: String = format!(r#"
<speak version='\''1.0'\'' xml:lang='\''en-US'\''>
<voice xml:lang='\''en-US'\'' xml:gender='\''Female'\'' name='\''en-US-SaraNeural'\''>
my voice is my passport verify me
</voice>
</speak>
"#);
let res = Client::new()
.post(url)
.header( "Ocp-Apim-Subscription-Key", "mySecretKeyIAmWritingThisHereForSecurity")
.header(CONTENT_TYPE, "application/ssml+xml")
.header("X-Microsoft-OutputFormat","audio-16khz-128kbitrate-mono-mp3")
.header(USER_AGENT, "curl")
.body(body)
.send().await?;
println!("Status Code: {:?}", res.status());
Ok(())
}
It is weird because it says cannot_be_a_base: false, username: "" but I don't need/have such things... also, this data being sent to Azure works if sent via the command line with CURL.
What I am trying to achieve, my situation:
curl --location --request POST "https://eastus.tts.speech.microsoft.com/cognitiveservices/v1" \
--header "Ocp-Apim-Subscription-Key: myKEYgoesHERE" \
--header 'Content-Type: application/ssml+xml' \
--header 'X-Microsoft-OutputFormat: audio-16khz-128kbitrate-mono-mp3' \
--header 'User-Agent: curl' \
--data-raw '<speak version='\''1.0'\'' xml:lang='\''en-US'\''>
<voice xml:lang='\''en-US'\'' xml:gender='\''Female'\'' name='\''en-US-SaraNeural'\''>
stop it
</voice>
</speak>' > output.mp3
I wanna turn that curl into a rust reqwest... so
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let url: String = "https://eastus.tts.speech.microsoft.com/cognitiveservices/v1".to_string();
let body: String = format!(r#"
<speak version='\''1.0'\'' xml:lang='\''en-US'\''>
<voice xml:lang='\''en-US'\'' xml:gender='\''Female'\'' name='\''en-US-SaraNeural'\''>
my voice is my passport verify me
</voice>
</speak>
"#);
let res = Client::new()
.post(url)
.header( "Ocp-Apim-Subscription-Key", "MYkey")
.header(CONTENT_TYPE, "application/ssml+xml")
.header("X-Microsoft-OutputFormat","audio-16khz-128kbitrate-mono-mp3")
.header(USER_AGENT, "curl")
.body(body)
.send().await?;
println!("OOO {:?}", res);
Ok(())
}
I believe I am missing maybe the --location flag here yet I do not believe that is the issue
You are using the same string escape syntax that you used in the curl example, but Rust and shell strings are different things, different syntax. The end result of the curl command is that each '\'' simply encodes a single '. You don't need to escape 's in a Rust raw literal like r#""#, just include them directly as you want it sent:
let body = format!(r#"
<speak version='1.0' xml:lang='en-US'>
<voice xml:lang='en-US' xml:gender='Female' name='en-US-SaraNeural'>
my voice is my passport verify me
</voice>
</speak>
"#);

how to use the simple-oauth2 library to make request application/x-www-form-urlencoded?

i have some code which perfectly work through mac terminal and giving me token from website
curl -XPOST "https://link.com/oauth/access_token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: 1.0" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_id=myawesomeapp" \
--data-urlencode "client_secret=abc123" \
--data-urlencode "scope=read write"
I want to do request through nodejs without curl request. website giving link on npm library simple-oauth2, but my code does not work.
my not working version of this
const credentials = {
client: {
id: 'myawesomeapp',
secret: 'abc123'
},
auth: {
tokenHost: 'https://link.com',
tokenPath: '/oauth/access_token'
},
http: {
'headers.authorization': 'headers.Accept = application/x-www-form-urlencoded'
}
};
oauth2 = oauth2.create(credentials);
oauth2.accessToken.create()
If it's an x-www-form-urlencoded content type, you'll probably need to also update the authorisation method in your options to form (its default is header). I.e.
const credentials = {
/*
your existing config
*/
options: {
authorizationMethod: 'body'
}
}
Hopefully that should do the trick...

Passing variables to curl command in child_process.exec fails

I was trying to use child_process.exec to call curl with a long command in order to send some data to an API. Something similar to the following example:
exec('git log --oneline | wc -l', function(error, stdin, stderr) {
if (stdin > 1) {
exec('curl -H "Content-Type: application/json" -X POST -d \'{"value1": "\'"$arg"\'"}\' https://https://maker.ifttt.com/trigger/{event}/with/key/<my-key>', { "env" : {"arg": stdin } });
}
})
So if a git repo includes more than one line in its git log output, then you execute a POST request to some API (here, a simple webhook in ifttt.com), in which you're passing some variable (arg) in the process.
Notice that this is the best attempt, but in general, I was struggling quite a bit to escape single and double quotes. In this particular case, the HTTP request was not sent correctly because the body includes a line break:
POST / HTTP/1.1
Host: <some-host>
User-Agent: curl/7.50.1
Accept: */*
Content-Type: application/json
Content-Length: 16
{"value1": "2
"}
At the end, I had to use an external bash script:
exec('./send_request.sh $arg', { "env": {"arg": stdin } });
but I'm still very curious on how to make it work within the same js file.
If it helps, I'm running node 6.11.0 and curl 7.52.1.
Try:
exec('git log --oneline | wc -l', function(error, stdin, stderr) {
if (stdin > 1) {
exec('curl -H "Content-Type: application/json" -X POST -d \'{"value1": "\'"$arg"\'"}\' https://https://maker.ifttt.com/trigger/{event}/with/key/<my-key>', { "env" : {"arg": stdin.replace(/\n/g, '') } });
}
})
What is happening is that your variable 'stdin' (you should rename it to 'stdout') has a \n at the end of it.

Windows curl string formatting

I am trying to use curl to make an HTTP POST request.
The request contains some environment variables. Here is the command:
curl -X POST -u username:pass -H "Content-Type: application/json" -d "{ \"fields\": { \"project\": { \"key\": \"myproject\" }, \"summary\": \"${var1.name} - ${var2.name}\", \"description\": \"Testing testing!:\n${url}\", \"issuetype\": { \"name\": \"Task\" }}}" http://myurl.com/rest
The information is sent, but the ${var1.name} and ${var2.name} are being sent as literal strings and not as their actual values.
The command is run on windows so that is why I am escaping the quotes. Could that be a problem as to why they're being sent as strings?
Windows environment variables are deferenced as %var1% and %var2%. This works:
C:\>set var1.name=test1
C:\>set var2.name=test2
C:\>set var
var1.name=test1
var2.name=test2
curl.exe -X POST -u username:pass -H "Content-Type: application/json" -d "{ \"fields\": { \"project\": { \"key\": \"myproject\" }, \"summary\": \"%var1.name% - %var2.name%\", \"description\": \"Testing testing!:\n${url}\", \"issuetype\": { \"name\": \"Task\" }}}" http://myurl.com/rest

Resources