Follow or stop at redirects

For Rust developers who need control over where a request ends up

You follow a chain of three redirects, put a limit on how many a client will follow and turn redirects off so you can read the Location header yourself.

Before you start

You need Rust with Cargo. fibre_http comes from crates.io:

fibre_http = "0"

Set up the project#

Start a new binary crate.

cargo new redirects
cd redirects

Put this in the [dependencies] section of Cargo.toml:

Cargo.toml
[dependencies]
fibre_http = "0"

The program#

httpbin.org's /redirect/3 sends you through three redirects before it answers. Replace src/main.rs with this:

src/main.rs
use fibre_http::{Error, SyncClient};

fn main() -> Result<(), Error> {
    let follow = SyncClient::new();
    let response = follow.get("https://httpbin.org/redirect/3").send()?;
    println!("default client: {} after following the redirects", response.status());

    let two = SyncClient::builder().redirects(2).build_sync()?;
    match two.get("https://httpbin.org/redirect/3").send() {
        Ok(response) => println!("limit 2: {}", response.status()),
        Err(Error::TooManyRedirects) => println!("limit 2: too many redirects"),
        Err(e) => println!("limit 2 failed: {e}"),
    }

    let none = SyncClient::builder().redirects(0).build_sync()?;
    let response = none.get("https://httpbin.org/redirect/3").send()?;
    println!("no redirects: {} pointing at {:?}", response.status(), response.headers().get("location"));
    Ok(())
}

Run it:

$ cargo run
default client: 200 OK after following the redirects
limit 2: too many redirects
no redirects: 302 Found pointing at Some("/relative-redirect/2")

What each part does#

A new client follows up to 10 redirects, so the first request ends on the final page.

redirects(2) lowers the limit. Three redirects is one too many, so send returns Error::TooManyRedirects.

redirects(0) turns following off. You get the first redirect back as a normal response and can decide what to do with its Location header.

When the client follows a redirect it behaves the way a browser does. A 301 or 302 turns a POST into a GET, while a 307 or 308 keeps the method and the body. A redirect to a different site drops the Authorization and Cookie headers, so your credentials are never sent somewhere you did not ask for.

Where to go next#

The usage guide has the full redirect rules: https://github.com/excsn/fibre/blob/main/http/README.USAGE.md