Hyper post запрос


#1

Здравствуйте,

Подскажите пожалуйста, как делать post запрос используя hyper. Материала много в интернете, но такое впечатление что он только для старых версий hyper. У меня вышло что-то такое, и не работает. Прошу помощи Ссылка на playground

Должно вернуть тело странички, в которой будет ужатый css

Я еще в futures путаюсь(
Раньше пользовался crate reqwest и сложностей не знал

extern crate hyper;

use hyper::{Method, Request};
use hyper::client;
use hyper::Client;
use hyper::rt::{Future, Stream};

fn main() {
    let css = "body{
        margin: 0;
    }";


    let css_min = css_minifier(css);

    println!("css min: {}", css_min);
}


fn css_minifier(css: &str) -> String {
    let uri: hyper::Uri = "https://cssminifier.com/raw".parse().unwrap();

    // Post Params
    let params = [("input", css)];
    let body_string = serde_urlencoded::to_string(&params).unwrap();
    let body = hyper::Body::from(body_string);


    let mut req = Request::new(body);
    *req.method_mut() = Method::POST;
    *req.uri_mut() = uri.clone();

    req.headers_mut().insert(
        hyper::header::CONTENT_TYPE,
        hyper::header::HeaderValue::from_static("application/x-www-form-urlencoded"),
    );


    let client = Client::new();

    let post = client.request(req).and_then(|res| {
        println!("POST: {}", res.status());

        Ok(res.into_body().concat2())
    });


    let res = post.wait().unwrap();
    println!("POST: {:?}", res);

    "test".to_string()
}

Раньше работало вот так: Ссылка на Playground Но сейчас что-то и так не хочет. Видимо hyper обновился.

P. S. я все таки хочу решение через hyper а не reqwest
Большое спасибо


#2

Например, вот так: https://github.com/Pzixel/boyan_detector_bot/blob/master/src/telegram_client.rs#L129

Используя use hyper::{Body, Chunk, Client, Method, Request};


#3

Это конечно вообще сложно для меня… Я первый раз пишу на hyper. И копипаста с документации просто не работает.

Ну и futures. - я не понимаю как их разворачивать, и как оно работает. Я не находил понятную мне документацию

Можно ли вообще без futures ?


#4

Без futures - дождаться стабилизации https://areweasyncyet.rs/, сам hyper ждёт и именно поэтому они пока не особо занимаются своей документацией.


#5

Надо просто взять старую версию hyper, а не последнюю. Там только синхронный режим. Но это было, наверное, год назад :slight_smile:
Либо другой http-клиент - например reqwest. Там это делается в одну строку:

let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .body("the exact body that is sent")
    .send()?;

#6

Человек же спросил “я знаю как через reqwest, а как через hyper сделать?”

use hyper;
use hyper::rt::Future;
use hyper::{Body, Request};
use hyper::{Chunk, Client, Method};
use hyper_tls::HttpsConnector;
use futures::Stream;
use tokio::runtime::Runtime;


fn main() {
    let request = send(Method::GET, "https://jsonplaceholder.typicode.com/todos/1", Body::empty());
    let mut runtime = Runtime::new().unwrap();
    let me = runtime.block_on(request).unwrap();
    println!("{:?}", me);
}

fn send(method: Method, uri: &str, body: Body) -> impl Future<Item = Chunk, Error = String> {
    let https = HttpsConnector::new(1).unwrap();
    let client: Client<_, Body> = Client::builder().build(https);
    let request = Request::builder()
        .method(method)
        .uri(uri)
        .header("Content-Type", "application/json")
        .body(body)
        .unwrap();
    client.request(request)
        .map_err(|_| "Bad error happened".into())
        .and_then(|response| {
            let is_success = response.status().is_success();
            response.into_body().concat2().then(move |result| {
                let chunk = result.map_err(|_| "Deserialization error".to_string())?;
                if is_success {
                    Ok(chunk)
                } else {
                    let bytes = chunk.into_bytes();
                    let text: String = String::from_utf8_lossy(&bytes).into_owned();
                    Err(text)
                }
            })
        })
}
[dependencies]
hyper = "0.12.23"
hyper-tls = "0.3.1"
futures = "0.1.25"
tokio = "0.1.14"

#7

Да, что-то я не дочитал


#8

спасибо больше за ответ!) Все круто, все заработало. теперь буду разбираться почему работает)

Я только поменял "application/json" на "application/x-www-form-urlencoded"