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

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>
"#);

Related

I am getting "TypeError: openai.createEdit is not a function" while trying to use the Create edit function, can anyone point if there's a mistake?

I tried the the same in a node.js web app and in postman, I have added the code and curl for respectively below:
Node JS:
const response = await openai.createEdit("text-davinci-002", {
input: "What day of the wek is it?",
instruction: "Fix the spelling mistakes" });
CURL:
curl --location --request POST 'https://api.openai.com/v1/engines/text-davinci-002/edits'
--header 'Content-Type: application/json'
--header 'Authorization: Bearer API_KEY'
--data-raw '{
"input": "What day of the wek is it?",
"instruction": "Fix the spelling mistakes"
}'

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

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;

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...

Convert curl command into a working script

I am using an API from check-host.net to ping an website.
My issue is right now that I have no ideea how I could transform the curl command api into an working python script. I tried different approaches which I found on here but sadly none has give me the ouput I am looking for.
Working curl command:
curl -H "Accept: application/json" \ https://check-host.net/check-tcp?host=smtp://gmail.com&max_nodes=1
the respons looks something like that:
{ "ok": 1, "request_id": "29", "permanent_link":
"https://check-host.net/check-report/29", "nodes": {
"7f000001": ["it","Italy", "Marco"] } }
You have to send a Accept: application/json header in your request. You can also use the builtin json decoder in requests.
import requests
headers={
'Accept': 'application/json'
}
r=requests.get('https://check-host.net/check-tcp?host=smtp://gmail.com&max_nodes=1',headers=headers)
print(r.json())
Output
{'nodes': {'us2.node.check-host.net': ['us', 'USA', 'New Jersey', '199.38.245.218', 'AS394625', 'OK']}, 'ok': 1, 'permanent_link': 'https://check-host.net/check-report/a462c3ck399', 'request_id': 'a462c3ck399'}

Reqwest's Client.post() returning 400 bad request for File.io API

I'm learning Rust, and thought it would be handy to build a CLI to share files with the File.io API.
To do so, I am trying to use reqwest to send a request as described in the File.io docs:
# from file.io doc -> works fine
$ curl --data "text=this is a secret pw" https://file.io
> {"success":true,"key":"zX0Vko","link":"https://file.io/zX0Vko","expiry":"14 days"}
When I run the below code, I get a 400 response. Perhaps there's an issue with the headers? I've tried looking at the curl docs to find out what I could be missing, but I'm stumped.
Any help would be appreciated.
My code:
extern crate reqwest;
fn main() {
let client = reqwest::Client::new();
let res = client.post("https://file.io/")
.body("text=this is a practice run")
.send();
println!("{:?}", res);
}
Expected Response:
{"success":true,"key":"SOME_KEY","link":"SOME_LINK","expiry":"14 days"}
Actual Response:
Ok(Response { url: "https://file.io/", status: 400, headers: {"date": "Wed, 06 Feb 2019 03:40:35 GMT", "content-type": "application/json; charset=utf-8", "content-length": "64", "connection": "keep-alive", "x-powered-by": "Express", "x-ratelimit-limit": "5", "x-ratelimit-remaining": "4", "access-control-allow-origin": "*", "access-control-allow-headers": "Cache-Control,X-reqed-With,x-requested-with", "etag": "W/\"40-SEaBd3tIA9c06hg3p17dhWTvFz0\""} })
Your requests are not equivalent. curl --data means you're trying to send a HTML form with content type "x-www-form-urlencoded" or similar, whereas this line in your code
.body("text=this is a practice run")
means "just a text". You should use ReqwestBuilder::form as described here

Resources