Trait hreq::RequestBuilderExt[][src]

pub trait RequestBuilderExt where
    Self: Sized
{ fn query(self, key: &str, value: &str) -> Self;
fn timeout(self, duration: Duration) -> Self;
fn timeout_millis(self, millis: u64) -> Self;
fn force_http2(self, force: bool) -> Self;
fn charset_encode(self, enable: bool) -> Self;
fn charset_encode_source(self, encoding: &str) -> Self;
fn charset_decode(self, enable: bool) -> Self;
fn charset_decode_target(self, encoding: &str) -> Self;
fn content_encode(self, enabled: bool) -> Self;
fn content_decode(self, enabled: bool) -> Self;
fn redirect_body_buffer(self, size: usize) -> Self;
fn prebuffer_request_body(self, enable: bool) -> Self;
fn with_override(self, host: &str, port: u16, tls: bool) -> Self;
fn tls_disable_server_cert_verify(self, disable: bool) -> Self;
fn with_body<B: Into<Body>>(self, body: B) -> Result<Request<Body>>;
fn send<B>(self, body: B) -> ResponseFuture

Notable traits for ResponseFuture

impl Future for ResponseFuture type Output = Result<Response<Body>, Error>;

    where
        B: Into<Body> + Send
;
fn call(self) -> ResponseFuture

Notable traits for ResponseFuture

impl Future for ResponseFuture type Output = Result<Response<Body>, Error>;
;
fn with_json<B: Serialize + ?Sized>(self, body: &B) -> Result<Request<Body>>;
fn send_json<B: ?Sized>(self, body: &B) -> ResponseFuture

Notable traits for ResponseFuture

impl Future for ResponseFuture type Output = Result<Response<Body>, Error>;

    where
        B: Serialize + Send + Sync
; }

Extends http::request::Builder with ergonomic extras for hreq.

These extensions are part of the primary goal of hreq to provide a “User first API”.

Required methods

fn query(self, key: &str, value: &str) -> Self[src]

Set a query parameter to be appended at the end the request URI.

use hreq::prelude::*;

Request::get("http://my-api/query")
    .query("api-key", "secret sauce")
    .call().block();

Same name query parameters are appended, not replaced. I.e. .query("x", "1").query("x", "2") will result in a uri with ?x=1&x=2.

Due to limitations in the http API, the provided URI is only amended upon calling some variant of hreq .send().

fn timeout(self, duration: Duration) -> Self[src]

Set a timeout for the entire request, including reading the body.

If the timeout is reached, the current operation is aborted with an Error::Io. To easily distinguish the timeout errors, there’s a convenience Error::is_timeout() call.

use hreq::prelude::*;
use std::time::Duration;

let req = Request::get("https://httpbin.org/get/")
    .timeout(Duration::from_nanos(1))
    .call().block();

assert!(req.is_err());
assert!(req.unwrap_err().is_timeout());

fn timeout_millis(self, millis: u64) -> Self[src]

This is an alias for .timeout() without having to construct a Duration.

use hreq::prelude::*;

let req = Request::get("https://httpbin.org/get/")
    .timeout_millis(10_000)
    .call().block();

assert!(req.is_err());
assert!(req.unwrap_err().is_timeout());

fn force_http2(self, force: bool) -> Self[src]

Force the request to use http2.

Normally whether to use http2 is negotiated as part of TLS (https). The TLS feature is called ALPN. In some situations you might want to force the use of http2, such as when there is no TLS involved. The http2 spec calls this having “prior knowledge”.

Forcing http2 when the server only talks http1.1 is doomed to fail.

use hreq::prelude::*;
use std::time::Duration;

let req = Request::get("http://my-insecure-http2-server/")
    .force_http2(true)
    .call().block();

fn charset_encode(self, enable: bool) -> Self[src]

Toggle automatic request body charset encoding. Defaults to true.

hreq encodes the request body of text MIME types according to the charset in the content-type request header:

  • content-type: text/html; charset=iso8859-1

The behavior is triggered for any MIME type starting with text/. Because we’re in rust, there’s an underlying assumption that the source of the request body is in utf-8, but this can be changed using charset_encode_source.

Setting this to false disables any automatic charset encoding of the request body.

Examples

You have plain text in a rust String (which is always utf-8) and you want to POST it as iso8859-1 (aka latin-1) request body. The default assumption is that the source is in utf-8. You only need a content-type header.

use hreq::prelude::*;

// This is a &str in rust default utf-8
let content = "Und in die Bäumen hängen Löwen und Bären";

let req = Request::post("https://my-euro-server/")
    // This header converts the body to iso8859-1
    .header("content-type", "text/plain; charset=iso8859-1")
    .send(content).block();

Or if you have a plain text file in utf-8.

use hreq::prelude::*;
use std::fs::File;

let req = Request::post("https://my-euro-server/")
    // This header converts the body to iso8859-1
    .header("content-type", "text/plain; charset=iso8859-1")
    .send(File::open("my-utf8-file.txt").unwrap()).block();

If you want to disable automatic conversion of the request body.

use hreq::prelude::*;
use std::fs::File;

let req = Request::post("https://my-euro-server/")
    // Disable outgoing charset encoding.
    .charset_encode(false)
    // This header has no effect now.
    .header("content-type", "text/plain; charset=iso8859-1")
    .send(File::open("my-iso8859-1-file.txt").unwrap()).block();

fn charset_encode_source(self, encoding: &str) -> Self[src]

Sets how to interpret request body source. Defaults to utf-8.

When doing charset conversion of the request body, this set how to interpret the source of the body.

The setting works together with the mechanic described in charset_encode, i.e. it is triggered by the presence of a charset part in a content-type request header with a text MIME.

  • content-type: text/html; charset=iso8859-1

Notice if the Body is a rust String or &str, this setting is ignored since the internal represenation is always utf-8.

use hreq::prelude::*;

// おはよう世界 in EUC-JP.
let euc_jp = [164_u8, 170, 164, 207, 164, 232, 164, 166, 192, 164, 179, 166];

let req = Request::post("https://my-japan-server/")
    // This header converts the body from EUC-JP to Shift-JIS
    .charset_encode_source("EUC-JP")
    .header("content-type", "text/plain; charset=Shift_JIS")
    .send(&euc_jp[..]).block();

fn charset_decode(self, enable: bool) -> Self[src]

Toggle automatic response body charset decoding. Defaults to true.

hreq decodes the response body of text MIME types according to the charset in the content-type response header:

  • content-type: text/html; charset=iso8859-1

The behavior is triggered for any MIME type starting with text/. Because we’re in rust, there’s an underlying assumption that the wanted encoding is utf-8, but this can be changed using charset_decode_target.

use hreq::prelude::*;

let mut resp = Request::get("https://my-euro-server/")
    .call().block().unwrap();

assert_eq!(resp.header("content-type"), Some("text/html; charset=iso8859-1"));

// this is now automatically converted to utf-8.
let string = resp.body_mut().read_to_string().block().unwrap();

fn charset_decode_target(self, encoding: &str) -> Self[src]

Sets how to output the response body. Defaults to utf-8.

When doing charset conversion of the response body, this sets how to output the the response body.

The setting works together with the mechanic described in charset_decode, i.e. it is triggered by the presence of a charset part in a content-type response header with a text MIME.

  • content-type: text/html; charset=iso8859-1

Notice if you use the Body.read_to_string() method, this setting is ignored since rust’s internal representation is always utf-8.

use hreq::prelude::*;

// Originating server sends content in Shift_JIS
let mut resp = Request::get("https://my-shift-jis-server/")
     // I want content in EUC-JP
    .charset_decode_target("EUC-JP")
    .call().block().unwrap();

assert_eq!(resp.header("content-type"), Some("text/html; charset=Shift_JIS"));

// this is now converted to EUC_JP
let vec = resp.body_mut().read_to_vec().block().unwrap();

fn content_encode(self, enabled: bool) -> Self[src]

Whether to use the content-encoding request header. Defaults to true.

By default hreq encodes compressed body data automatically. The behavior is triggered by setting the request header content-encoding: gzip.

If the body data provided to hreq is already compressed we might need turn off the default behavior.

use hreq::prelude::*;

// imagine we got some already gzip compressed data
let already_compressed: Vec<u8> = vec![];

let mut resp = Request::post("https://server-for-compressed/")
    .header("content-encoding", "gzip")
    .content_encode(false) // do not do extra encoding
    .send(already_compressed).block().unwrap();

fn content_decode(self, enabled: bool) -> Self[src]

Whether to use the content-encoding response header. Defaults to true.

By default hreq decodes compressed body data automatically. The behavior is triggered by when hreq encounters the response header content-encoding: gzip.

If we want to keep the body data compressed, we can turn off the default behavior.

use hreq::prelude::*;

let mut resp = Request::get("https://server-for-compressed/")
    .header("accept-encoding", "gzip")
    .content_decode(false) // do not do decompress
    .call().block().unwrap();

// this content is still compressed
let compressed = resp.body_mut().read_to_vec();

fn redirect_body_buffer(self, size: usize) -> Self[src]

Buffer size to enable resending body on 307 and 308 redirects.

A POST/PUT request encountering 301 and 302 redirects will by de-facto standard follow the redirect with GET + empty body instead of the original method.

The 307 and 308 responses are explicitly for preserving the original request method and they should also re-send the original body to the redirected location.

For body re-send hreq must be able to repeat the body data sent when encountering a 307/308. However hreq can’t hold on to indefinitely large amounts of body data just in case it gets one of these redirect codes.

This parameter sets how much body data we should retain in memory in case of a re-send before “letting go” and not being able to respond with a body to 307/308.

The default value is 0 because solutions relying on 307/308 are not the norm and we don’t want the extra memory footprint for all cases where it is not used.

use hreq::prelude::*;

Request::post("https://my-redirect-server/")
    .redirect_body_buffer(1024) // up to 1kb buffer for resend
    .send("This body will be re-sent on 307")
    .block().unwrap();

hreq does a “best effort” in not using up the entire buffer. Imagine sending a 2GB large file, the remote server would most likely respond with 307/308 long before the entire body has been uploaded.

This can further be improved using by setting a Expect: 100-continue header, which would build in a small delay before sending the body letting the server respond with the redirect first.

use hreq::prelude::*;

let file = std::fs::File::open("my-big-movie.m4v").unwrap();

Request::post("https://my-redirect-server/")
    .redirect_body_buffer(1024 * 1024) // up to 1mb buffer for resend
    .header("expect", "100-continue")  // delay for 100-continue or redirect
    .send(file)
    .block().unwrap();

fn prebuffer_request_body(self, enable: bool) -> Self[src]

Toggle ability to read the request body into memory.

When sending a request body, it’s usually a good idea to read the entire body (up to some limit) into memory. Doing so avoids using transfer-encoding chunked when the content length can be determined.

By default, hreq will attempt to prebuffer up to 256kb request body.

Use this toggle to turn this behavior off.

fn with_override(self, host: &str, port: u16, tls: bool) -> Self[src]

Override the host, port and TLS setting of where to connect to.

This is mostly used for testing.

With this, hreq will ignore the scheme, host and port provided in the Uri when opening the TCP connection. The rest of the request handling will still use the Uri (cookies etc).

The override is only used for connections to the host/port found in Uri, and not when following redirects to other host/ports.

The override host name is also used for TLS certificate matching.

fn tls_disable_server_cert_verify(self, disable: bool) -> Self[src]

Disables verification of server certificate.

This is generally a bad idea. With verification turned off, anyone can intercept the TLS traffic, present a random certificate and pretend to be the server. In today’s world, no production code should disable this.

However it might be appropriate to use in some localhost developer scenarios, unit tests, etc.

fn with_body<B: Into<Body>>(self, body: B) -> Result<Request<Body>>[src]

Finish building the request by providing something as Body.

Body implements a number of conventient From traits. We can trivially construct a body from a String, &str, Vec<u8>, &[u8], File and more (see the From traits in the body doc).

with_body is just a shorthand. The following ways the construct a Request ends up with exactly the same result.

use hreq::prelude::*;
use hreq::Body;

let req1 = Request::post("http://foo")
  .with_body("Hello world");

let body2 = Body::from_str("Hello world");

let req2 = Request::post("http://foo")
  .body(body2);

let body3: Body = "Hello world".into();

let req3 = Request::post("http://foo")
  .body(body3);

fn send<B>(self, body: B) -> ResponseFuture

Notable traits for ResponseFuture

impl Future for ResponseFuture type Output = Result<Response<Body>, Error>;
where
    B: Into<Body> + Send
[src]

Send the built request with provided Body.

This is a shortcut to both provide a body and send the request. The following statements are roughly equivalent.

use hreq::prelude::*;

let res1 = Request::get("https://httpbin.org/get")
    .call().block();

let res2 = Request::get("https://httpbin.org/get")
    .with_body(()) // constructs the Request
    .unwrap()
    .send().block();

Creates a default configured Agent used for this request only. The agent will follow redirects and provide some retry-logic for idempotent request methods.

If you need connection pooling over several requests or finer grained control over retries or redirects, instantiate an Agent and send the request through it.

fn call(self) -> ResponseFuture

Notable traits for ResponseFuture

impl Future for ResponseFuture type Output = Result<Response<Body>, Error>;
[src]

Alias for sending an empty body and is the same as doing .call().

Typically used for get requests.

use hreq::prelude::*;

let res = Request::get("https://httpbin.org/get")
    .call().block();

fn with_json<B: Serialize + ?Sized>(self, body: &B) -> Result<Request<Body>>[src]

Finish building the request by providing an object serializable to JSON.

Objects made serializable with serde_derive can be automatically turned into bodies. This sets both content-type and content-length.

Example

use serde_derive::Serialize;
use hreq::prelude::*;
use hreq::Body;

#[derive(Serialize)]
struct MyJsonThing {
  name: String,
  age: String,
}

let json = MyJsonThing {
  name: "Karl Kajal".into(),
  age: "32".into(),
};

let req = http::Request::post("http://foo")
  .with_json(&json);

fn send_json<B: ?Sized>(self, body: &B) -> ResponseFuture

Notable traits for ResponseFuture

impl Future for ResponseFuture type Output = Result<Response<Body>, Error>;
where
    B: Serialize + Send + Sync
[src]

Send the built request with provided JSON object serialized to a body.

This is a shortcut to both provide a JSON body and send the request.

Loading content...

Implementations on Foreign Types

impl RequestBuilderExt for Builder[src]

Loading content...

Implementors

Loading content...