Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make an HTTP request from Rust?

Tags:

http

rust

How can I make an HTTP request from Rust? I can't seem to find anything in the core library.

I don't need to parse the output, just make a request and check the HTTP response code.

Bonus marks if someone can show me how to URL encode the query parameters on my URL!

like image 270
Alex Dean Avatar asked Jan 04 '13 09:01

Alex Dean


People also ask

How do I make a request in rust?

Sending a GET request is as simple as this. let client = Client::new(); let res = client. get("http://example.domain").send().unwrap(); assert_eq!

How do I make a Web request?

The most common HTTP request methods have a call shortcut (such as http. get and http. post), but you can make any type of HTTP request by setting the call field to http. request and specifying the type of request using the method field.

What is a HTTP GET request?

A GET request, in simple terms, is a way for you to grab data from a data source with the help of the internet. It's done using the GET request method, which is a very common HTTP request method (like POST, PUT, or DELETE).

What is HTTP request library?

Introduction The HTTP Requests library provides a clean and simplified interface to make HTTP requests. The spirit of this library is to make it trivial to do easy things with HTTP requests. It can accomplish the most common use cases for an HTTP client, but does not aim to be a complete HTTP client implementation.


2 Answers

The easiest way to make HTTP requests in Rust is with the reqwest crate:

use std::error::Error;  fn main() -> Result<(), Box<dyn Error>> {     let resp = reqwest::blocking::get("https://httpbin.org/ip")?.text()?;     println!("{:#?}", resp);     Ok(()) } 

In Cargo.toml:

[dependencies] reqwest = { version = "0.11", features = ["blocking"] } 

Async

Reqwest also supports making asynchronous HTTP requests using Tokio:

use std::error::Error;  #[tokio::main] async fn main() -> Result<(), Box<dyn Error>> {     let resp = reqwest::get("https://httpbin.org/ip")         .await?         .text()         .await?;     println!("{:#?}", resp);     Ok(()) } 

In Cargo.toml:

[dependencies] reqwest = "0.11" tokio = { version = "1", features = ["full"] } 

Hyper

Reqwest is an easy to use wrapper around Hyper, which is a popular HTTP library for Rust. You can use it directly if you need more control over managing connections. A Hyper-based example is below and is largely inspired by an example in its documentation:

use hyper::{body::HttpBody as _, Client, Uri}; use std::error::Error;  #[tokio::main] async fn main() -> Result<(), Box<dyn Error>> {     let client = Client::new();      let res = client         .get(Uri::from_static("http://httpbin.org/ip"))         .await?;      println!("status: {}", res.status());      let buf = hyper::body::to_bytes(res).await?;      println!("body: {:?}", buf); } 

In Cargo.toml:

[dependencies] hyper = { version = "0.14", features = ["full"] } tokio = { version = "1", features = ["full"] } 

Original answer (Rust 0.6)

I believe what you're looking for is in the standard library. now in rust-http and Chris Morgan's answer is the standard way in current Rust for the foreseeable future. I'm not sure how far I can take you (and hope I'm not taking you the wrong direction!), but you'll want something like:

// 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)); } 

As for encoding, there are some examples in the unit tests in src/libstd/net_url.rs.

like image 176
Isaac Aggrey Avatar answered Oct 09 '22 09:10

Isaac Aggrey


Update: This answer refers to fairly ancient history. For the current best practices, please look at Isaac Aggrey's answer instead.


I've been working on rust-http, which has become the de facto HTTP library for Rust (Servo uses it); it's far from complete and very poorly documented at present. Here's an example of making a request and doing something with the status 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);     } } 

Run this code with a URL as the sole command-line argument and it'll check the status code! (HTTP only; no HTTPS.)

Compare with src/examples/client/client.rs for an example that does a little more.

rust-http is tracking the master branch of rust. At present it'll work in the just-released Rust 0.8, but there are likely to be breaking changes soon. Actually, no version of rust-http works on Rust 0.8—there was a breaking change which can't be worked around in privacy rules just before the release, leaving something that rust-http depends on in extra::url inaccessible. This has since been fixed, but it leaves rust-http incompatible with Rust 0.8.


As for the query string encoding matter, at present that should be done with extra::url::Query (a typedef for ~[(~str, ~str)]). Appropriate functions for conversions:

  • extra::url::query_to_str

  • extra::url::query_from_str (sorry, can't use this just at present as it's private. PR to make it public about to come. In the mean time, this link actually shouldn't work, it's only available because of https://github.com/mozilla/rust/issues/7476.)

like image 23
Chris Morgan Avatar answered Oct 09 '22 09:10

Chris Morgan