Comment puis-je faire une requête HTTP de Rust?

Comment puis-je faire une requête HTTP depuis Rust? Je ne trouve rien dans la bibliothèque principale.

Je n'ai pas besoin d'analyser la sortie, il suffit de faire une demande et de vérifier le code de réponse HTTP.

des points Bonus si quelqu'un peut me montrer comment encoder les paramètres de la requête sur mon URL!

39
demandé sur Alex Dean 2013-01-04 13:50:32

3 réponses

mise à jour: cette réponse fait référence à une histoire assez ancienne. Pour connaître les pratiques exemplaires actuelles, veuillez consulter réponse D'Isaac Aggrey à la place.


j'ai travaillé sur rouille-http, qui est devenu le de facto bibliothèque HTTP pour Rust (Servo l'utilise); elle est loin d'être complète et très mal documentée à l'heure actuelle. Voici un exemple de faire une demande et faire quelque chose avec le statut code:

extern mod http;
use http::client::RequestWriter;
use http::method::Get;
use http::status;
use std::os;

fn main() {
    let request = RequestWriter::new(Get, FromStr::from_str(os::args()[1]).unwrap());
    let response = match request.read_response() {
        Ok(response) => response,
        Err(_request) => unreachable!(), // Uncaught condition will have failed first
    };
    if response.status == status::Ok {
        println!("Oh goodie, I got me a 200 OK response!");
    } else {
        println!("That URL ain't returning 200 OK, it returned {} instead", response.status);
    }
}

Lancez CE code avec une URL comme seul argument de ligne de commande et il vérifiera le code d'état! (HTTP seulement; Pas De HTTPS.)

Comparez avec src/examples/client/client.rs pour un exemple un peu plus.

rust-http suit la branche principale de rust. à l'heure actuelle, il fonctionnera dans la rouille 0.8, mais il est probable qu'il y aura des changements de rupture bientôt.en fait, aucune version de rust-http fonctionne sur Rust 0.8-il y avait un briser le changement qui ne peut pas être contourné dans les règles de confidentialité juste avant la publication, laissant quelque chose dont rust-http dépend dans extra::url inaccessible. Ceci a depuis été corrigé, mais il laisse rust-http incompatible avec Rust 0.8.


en ce qui concerne la chaîne de requête encodant la matière, à l'heure actuelle cela devrait être fait avec extra::url::Query (un typedef pour ~[(~str, ~str)]). Fonctions appropriées pour conversions:

19
répondu Chris Morgan 2017-09-23 11:36:12

la façon la plus facile de faire HTTP dans Rust est reqwest. C'est un wrapper pour faire Hyper plus facile à utiliser.

Hyper est une bibliothèque HTTP populaire pour Rust et utilise deux bibliothèques: Tokioboucle d'événements pour les non-blocage des demandes et contrats à terme-rs pour les contrats à terme normalisés et des promesses. Hyper - exemple basé est ci-dessous et est largement inspiré par un exemple dans son documentation.

// Rust 1.19, Hyper 0.11, tokio-core 0.1, futures 0.1

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

use futures::{Future};
use hyper::{Client, Uri};
use tokio_core::reactor::Core;

fn main() {
    // Core is the Tokio event loop used for making a non-blocking request
    let mut core = Core::new().unwrap();

    let client = Client::new(&core.handle());

    let url : Uri = "http://httpbin.org/response-headers?foo=bar".parse().unwrap();
    assert_eq!(url.query(), Some("foo=bar"));

    let request = client.get(url)
        .map(|res| {
            assert_eq!(res.status(), hyper::Ok);
        });

    // request is a Future, futures are lazy, so must explicitly run
    core.run(request).unwrap();
}

Cargo.toml:

[dependencies]
hyper = "0.11"
tokio-core = "0.1"
futures = "0.1"

pour la postérité j'ai laissé ma réponse originale ci-dessous, mais voir ci-dessus pour une mise à jour de Rust 1.19 (dernière version stable de cette écriture).

je crois que ce que vous cherchez se trouve dans le bibliothèque standard. maintenant dans rouille-http et la réponse de Chris Morgan est la voie standard dans la rouille actuelle pour le un avenir prévisible. Je ne sais pas jusqu'où je peux vous emmener (et j'espère que je ne vous prends pas dans la mauvaise direction!), mais vous aurez envie de quelque chose de la forme:

// Rust 0.6 -- old code
/*
extern mod std;

use std::net_ip;
use std::uv;

fn main() {
    let iotask = uv::global_loop::get();
    let result = net_ip::get_addr("www.duckduckgo.com", &iotask);

    io::println(fmt!("%?", result));
 }
 */

en ce qui concerne l'encodage, il y a quelques exemples dans les tests unitaires dans src/libstd/net_url.rs.

30
répondu Isaac Aggrey 2017-08-23 08:14:05

en utilisant des reliures bouclées. Coller ceci dans votre Cargo.toml:

[dependencies.curl]
git = "https://github.com/carllerche/curl-rust"

...et ce dans le src/main.rs:

extern crate curl;

use curl::http;

fn main(){
  let resp = http::handle()
    .post("http://localhost:3000/login", "username=dude&password=sikrit")
    .exec().unwrap();

  println!("code={}; headers={}; body={}",
    resp.get_code(), resp.get_headers(), resp.get_body());    

}
9
répondu dvdplm 2014-10-06 09:06:51