0

I'm new to Rust. I'm having a lot of trouble finding a simple example in Rust to make an HTTP POST request. I found this answer but it's using a GET not a POST.

In the end, all I want to do is POST like this:

POST /TENANT/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=MY_CLIENT&scope=https://graph.microsoft.com/.default&client_secret=MY_SECRET&grant_type=client_credentials

This is what I have as code.

[dependencies]
tokio-core = "0.1.17"
futures = "0.1"
reqwest = "0.10.4"
hyper = "0.13.5"
use hyper::{Client, Uri, Request, Body};
use tokio_core::reactor::Core;

pub fn get_access_token() {
    let mut core = Core::new().unwrap();

    let client = Client::new();

    let host = "login.microsoftonline.com";
    let tenant = "TENANT";
    let client_id = "MY_CLIENT";
    let client_secret = "MY_SECRET";
    let scope = "https://graph.microsoft.com/.default";
    let grant_type = "client_credentials";

    let url_string = format!("https://{}/{}/oauth2/v2.0/token",
                             host,
                             tenant,
    );
    let url: Uri = url_string.parse().unwrap();
    let body = format!("client_id={}&client_secret={}&scope={}&grant_type={}",
                       client_id,
                       client_secret,
                       scope,
                       grant_type
    );

    let req = Request::builder()
        .method("POST")
        .uri(url)
        .header("Content-Type", "application/x-www-form-urlencoded")
        .body(Body::from(body))
        .expect("request builder");

    let request_result = core.run(client.request(req))
        .map(|res| {
            println!("Response: {}", res.status());
        })
        .map_err(|err| {
            println!("Error: {}", err);
        });
}

The error I'm getting is:

error[E0277]: the trait bound `hyper::client::ResponseFuture: futures::future::Future` is not satisfied
  --> src/auth.rs:47:35
   |
47 |     let request_result = core.run(client.request(req))
   |                                   ^^^^^^^^^^^^^^^^^^^ the trait `futures::future::Future` is not implemented for `hyper::client::ResponseFuture`

error: aborting due to previous error

I've found many different libraries to make HTTP requests (hyper, reqwest, http) but I am yet to find a working solution, and the Rust documentation isn't helping in that regard.

Also I tried using the onedrive_api::Auth package but I didn't see a way to do a client_credentials grant type.

tom
  • 1,331
  • 1
  • 15
  • 28
  • Read *all* the answers, such as https://stackoverflow.com/a/57770687/155423 – Shepmaster May 27 '20 at 12:51
  • *Can't I just make a synchronous call and be done* — https://docs.rs/reqwest/0.10.4/reqwest/blocking/index.html – Shepmaster May 27 '20 at 12:52
  • 1
    It's hard to answer multiple questions made in one post. Please separate them into multiple questions so that we can help you better and so that your questions will help others in the future that have one of the same questions as you! – Shepmaster May 27 '20 at 12:52
  • It looks like your question might be answered by the answers of [Why is a trait not implemented for a type that clearly has it implemented?](https://stackoverflow.com/q/44437123/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster May 27 '20 at 12:55
  • @Shepmaster my request is asking how to do a POST not a GET. The link you provided (stackoverflow.com/a/57770687/155423) doesn't help me. That's doing Client.get() and I need a post. Thanks – tom May 27 '20 at 13:05
  • I don't know why someone downvoted this.... makes me sad. – tom May 27 '20 at 13:32

0 Answers0