Reqwest Static Key as a Header

Hi,

Why reqwest wants us to use static header field. I know how to solve if I need it dynamically thanks to this: Add dynamic custom headers with reqwest
but just curious. Why this design choice ?

Looks like it uses Bytes, which has no lifetime parameter but can store &'static [u8] without copying.

I don't know if I'd say "wants"; from_bytes and from_lowercase are provided after all.

1 Like

Sorry couldn't understand your answer. Can you explain it in a little more detailed way?

Sure, I'll walk through it.

I went here and clicked source. Near the end of the function I see that this is an http crate implementation that's calling ByteStr::from_static. Looking for the import of ByteStr, I find it's coming from the http::byte_str module. Clicking on that file on the left, we can see that it is a newtype around Bytes from the bytes crate.

So ultimately you can trace the design decision back to the bytes crate.

Why did bytes::Bytes make that choice? Presumably because it fits well into their goals, and requiring &'static _ doesn't require putting a lifetime everywhere.

from_bytes (and from_lowercase) don't require 'statics so you're not forced to use &'static str.

I didn't try to track down why some of the APIs take &str and some take &[u8]. At a guess the logic is that &'static str is most commonly a literal which is more ergonomic to program than a byte slice. whereas a non-'static byte slice may have come from something like a file, and requiring a &str would require double validation at runtime, or unsafe. (UTF8 validation to get the &str, and another validation pass because valid header bytes are a subset of ASCII.)

3 Likes

HeaderName is designed the way it is to optimise standard http header fields, while still allowing you the flexibility to add your own headers, even dynamically at runtime. From the docs:

The internal representation is optimized to efficiently handle the cases most commonly encountered when working with HTTP. Standard header names are special cased and are represented internally as an enum. Short custom headers will be stored directly in the HeaderName struct and will not incur any allocation overhead, however longer strings will require an allocation for storage.

5 Likes

@quinedot @jofas Thanks!

1 Like