Ran the tests using cargo test before I proceeded any further and they all reported green.

The first step here is to figure out if the redirect was happening between two different domains (or hosts). At this place in the source we have access to both the previous and current URLs.

Was initially dreading that I might have to manually parse the host portion of the URLs but then figured out that the variables I had access to were of type hyper::Url which has this method fn host(&self) -> Option<Host<&str>> that gives me what I needed.

What type are you?

Figuring out the type of a value you have should be one of the easiest things in Rust. But since I’m rather new to Rust and the reqwest project, I found it a little difficult to figure out what type the url value was. They had used some generics as well which did not help me comprehend quickly.

So I let the compiler tell me what I needed. How? Simply call a random function on the value, url.foo() for instance! And the compiler will gladly tell you the type you’re dealing with.

This is a handy trick that we can use when you’re in the middle of a large project trying to figure out types! :)

The Meat

I had the current and previous hosts now. All I had to do then was compare them and if they’re different, remove some of the headers before following the redirect. Here’s how I did it —

A nice benefit of having types

I’ve always thought having a static type system would not be fun at all. But Rust is slowly changing my opinion.

The hyper crate has taken an approach of creating types for almost all HTTP headers. This has let them specify exactly the values each header can take and their format, and the way they would be serialised in the HTTP packet.

This provides a lot of safety and reduces a whole class of problems all together.

They also have a way to create use headers that do not have a type using the set_raw() and other such functions.

The turbofish

This weird syntax you see, ::<Cookie> , you see up there used on the headers.remove() function is called turbofish in Rust.

Like I described before, the hyper crate has typed headers. The crate has a struct Headers which is a wrapper around a HashMap — basically a collection of Header values.

This struct has a function remove() , but when you call headers.remove() , the compiler has no way of knowing which type of Header you’re trying to remove from the map.

From the source, we see that this — pub fn remove<H: Header + HeaderFormat>(&mut self) -> bool is the signature of the function. We can see that they’ve used a generic type H in there. But it does not take any arguments that clarify what type H takes.

In such cases, there is an ambiguity and we need to help the compiler along. And that’s where the turbofish comes in. So, when you do something like — headers.remove::<Cookie>() , you’re basically specialising the generic type H as Cookie .

Had a tough time understanding this and huge thanks to user kmc on #rust-beginners for the help! ❤

Tests & Wrap up

The project has a lot of integration tests and unit tests. For integration tests, they use a custom mock server which was pretty interesting and intuitive to use. But in our case we needed to test a situation where the redirect was happening between two different hosts. It looked like I had to make some changes to the server for this. I checked with the maintainer and he was okay with writing unit tests for the moment.

So that’s what I did. And btw, these were my very first tests in Rust. Yay! :D

That’s the story of how I got my very first open source contribution done in Rust. Looking forward to contributing more.

Preethi Kumar and I have been looking at crates.io lately and hoping to get involved in that effort soon!