0

I've been using reqwest for a few months now; solid features, reuse of types defined in http (and the like) and documentation.

I have the following http post request that works in Postman and curl that for reasons I can't figure out, generates a http::StatusCode "400 Bad Request".

Staring at and comparing the debug output of the request (below) over the past couple of days hasn't helped (ok, and a solid amount of reading the docs and playing with code too :)); thus the post.

The request spec that works with other clients

POST /2/files/list_folder HTTP/1.1
Host: api.dropboxapi.com
Authorization: Bearer <secret>
Content-Type: application/json
Content-Length: 65

{

    "path": "",
    "include_non_downloadable_files": false

}

The failing reqwest request code

  let client = reqwest::Client::new();
  let request = client
      .request(
          http::Method::from_str(method).unwrap(),
          format!(
              "{host}{endpoint}{query}",
              host = &drive_server,
              endpoint = &endpoint,
              query = &query_ls
          ),
      )
      .header(AUTHORIZATION, format!("Bearer {}", access_token.secret()))
      .header(CONTENT_TYPE, "application/json") // redundant when setting body with .json
      .header(ACCEPT, "application/json")
      .version(Version::HTTP_11)
      .json(&req_body);

... and the code that builds the req_body:

// dropbox WIP
let json = r#"
    {
       "path": "",
       "include_non_downloadable_files": false
    }
"#;

#[derive(Deserialize, Serialize)]
struct ReqBody {
    path: String,
    include_non_downloadable_files: bool,
}
let req_body = serde_json::from_str::<ReqBody>(json)
    .map_err(|err| AuthError::JsonParsingError(err.into()))?;

Debug output of the request

RequestBuilder {
   method: POST,
   url: Url {
       scheme: "https",
       cannot_be_a_base: false,
       username: "",
       password: None,
       host: Some(
           Domain(
               "api.dropboxapi.com",
           ),
       ),
       port: None,
       path: "/2/files/list_folder",
       query: None,
       fragment: None,
   },
   headers: {
       "authorization": "Bearer <secret>",
       "content-type": "application/json",
       "accept": "application/json",
   },
}

Aside but to know what to expect from the diagnostic: Is the output expected to exclude the request body when present? I have not found a way to echo the request body once "theoretically" set :))

A bit more context

Finally, a bit more background, the explicit call to the version is a failed attempt on my part to override google drive forcing a switch to http 2 when it sees a request body (a separate use of this client). I'll have to figure out another way that includes some sort of conditional call to .json(<body>) without violating ownership issues, when services like dropbox require the body but not google. When I disable the .json on the reqwest RequestBuilder for a service such as google, the request works as expected.

Plainly put, the question

How do I build the http post request described at the top of this post using reqwest?

Edmund's Echo
  • 766
  • 8
  • 15
  • Can you check if you still get code 400 if you paste in the literal API token instead of calling `access_token.secret()`? The request debug output looks correct, which suggests the problem might be with how the token is passed. – Brian Bowman Jun 02 '22 at 12:39
  • @BrianBowman Thank you for the follow-up. Good thought. Would you ask the same question if I told you that "it works" using the same codebase when I hit the Google drive and MSGraph endpoints? I ask because is there something special or different in how DropBox expects to read-in the Bearer token? The approach, including acquiring the token, use the same codebases. – Edmund's Echo Jun 03 '22 at 17:24
  • can you try like https://github.com/ozkanpakdil/libfrizz/blob/aca6877be85dc0a85e969b8304e53591bff78f5c/src/lib.rs#L87 ? and if you put a reproducer to github it will help more to solve. – ozkanpakdil Jun 21 '22 at 10:07

0 Answers0