Search code examples
rustreqwest

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


Solution

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