1

I want use to Hyper for crafting HTTP requests. Calling Client::get works fine but other methods such as Client::post and Client::head cause an compilation error.

extern crate futures;
extern crate hyper;
extern crate tokio_core;

use std::io::{self, Write};
use futures::{Future, Stream};
use hyper::Client;
use tokio_core::reactor::Core;

fn main() {
    let mut core = Core::new().unwrap();
    let client = Client::new(&core.handle());

    let uri = "http://httpbin.org/ip".parse().unwrap();
    let work = client.post(uri).and_then(|res| {
        // if post changed to get it will work correctly
        println!("Response: {}", res.status());

        res.body("x=z")
            .for_each(|chunk| io::stdout().write_all(&chunk).map_err(From::from))
    });
    core.run(work).unwrap();
}

error:

error[E0599]: no method named `post` found for type `hyper::Client<hyper::client::HttpConnector>` in the current scope
  --> src/main.rs:15:23
   |
15 |     let work = client.post(uri).and_then(|res| {
   |                       ^^^^

error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied
  --> src/main.rs:20:24
   |
20 |             .for_each(|chunk| io::stdout().write_all(&chunk).map_err(From::from))
   |                        ^^^^^ `[u8]` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `[u8]`
   = note: all local variables must have a statically known size
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 2
    `hyper::Client` does not have a post method! See: https://docs.rs/hyper/0.11.16/hyper/client/struct.Client.html#impl-2. It only has `get()` and `request()`. `client.request(Request::new(Method::Post, uri))` is appropriate. – daboross Feb 01 '18 at 23:18
  • @daboross Looks like this is an answer. You should post it as an answer, not a comment. – Boiethios Feb 02 '18 at 09:43
  • @Boiethios I would, but it's largely redundant with Shepmaster's answer now. – daboross Feb 08 '18 at 07:54

1 Answers1

7

There's no secret trickery to the error message. You are getting the error "no method named post found for type hyper::Client" because there's no such method.

If you review the documentation for Client, you can see all the methods it has. None of them are post.

Instead, you need to use Client::request and pass in a Request value. The constructor for Request accepts a Method which denotes the HTTP method to use.

use hyper::{Client, Request, Method};

fn main() {
    // ...

    let uri = "http://httpbin.org/ip".parse().unwrap();
    let req = Request::new(Method::Post, uri);

    let work = client.request(req).and_then(|res| {
        // ...
    });
}

The crate documentation says:

If just starting out, check out the Guides first.

There is a guide for exactly your case: Advanced Client Usage.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I have been unable implement POST using that Advanced Client Usage guide. Out of nowhere it states: "Remember, the work in post won’t actually do anything until we give the future to the core." – Steve3p0 Aug 17 '18 at 10:39
  • @SteveB make sure you read preceding guides as well; presumably and *advanced* guide builds on simpler guides that come before it. Also note that this Q&A is about Hyper 0.11 while the current version of Hyper is 0.12, which is greatly changed to accommodate futures. – Shepmaster Aug 17 '18 at 12:44