Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Custom HeaderName constants #174

Closed
dekellum opened this issue Feb 21, 2018 · 5 comments
Closed

Custom HeaderName constants #174

dekellum opened this issue Feb 21, 2018 · 5 comments
Labels
A-headers Area: HTTP headers

Comments

@dekellum
Copy link
Contributor

dekellum commented Feb 21, 2018

This is either a feature request or a documentation request. With a terse pointer I might at least be able to offer a PR for the latter.

In an application I have a bunch of custom headers to write, and I'd like these to share the same pre-checked and pre-allocated performance advantages as the const HeaderNames provided in the crate for the standard headers, for example ACCEPT.

Is there any way to do this shy of using, for example, the lazy_static crate? With a quick look at the source, it looks like the HeaderName innards are private. If not, is the lazy_static solution considered adequate and desirable, or is there interest in the possibility of exposing some form of the macro mechanism used internally to statically generate the standard headers?

Hyper has a header! macro, but I don't see any automatic conversion or representation as a http::header::HeaderName.

There are cases where I also could statically declare HeaderValues with similar advantage, but HeaderName is more fundamental.

The only potentially related existing issue I can find is #168.

@seanmonstar
Copy link
Member

I suspect when macros 2.0 are stable, we could provide a header_name! macro that can create a compile-time constant, allowing validation of the string when compiling.

However, I'm not sure of a way to be able to add custom headers into the internal enum table. It's really meant for the most common of headers, but custom headers aren't slow just because they don't have an internal variant.

@dekellum
Copy link
Contributor Author

dekellum commented Feb 22, 2018

A header_name! would be nice if it could create clean public or private const HeaderNames.

The lazy_static! approach can work, but with complications, so I'm not sure if it should be recommended or documented.

#[macro_use] extern crate lazy_static;
extern crate http;

use http::header::{HeaderMap, HeaderName, HeaderValue};

lazy_static! {
    static ref X_FOO: HeaderName = HeaderName::from_lowercase(b"x-foo").unwrap();
    static ref BAR_VAL: HeaderValue = HeaderValue::from_bytes(b"bar").unwrap();
}

fn main() {
  let mut hs = HeaderMap::new();
  hs.append(&*X_FOO, BAR_VAL.clone());
  // See https://stackoverflow.com/a/48115258 for explanation of `&*X_FOO` 
}

@ousado
Copy link

ousado commented Mar 4, 2018

However, I'm not sure of a way to be able to add custom headers into the internal enum table.

One could allow to merge a custom table with the default table, and provide the result in some form - I doubt it's feasible to add single headers with a header_name! macro, since the code generating the table needs to know the full set of headers, and at least AFAIK rust macros don't allow to wait for, collect and process all invocations of a given macro.

@ousado
Copy link

ousado commented Mar 4, 2018

Along those lines, one could also consider the option to limit the set of supported headers and define a policy what to do with unknown/unsupported ones - in a given application that just doesn't know about care about, or handle more than a given set of headers, being able to e.g. ignore all others without further allocations and other unnecessary work, might be beneficial.

@seanmonstar
Copy link
Member

It actually looks like eventually, HeaderName::from_static could be made a const fn... Besides that, there's not much more to do here, so I'm closing for now.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-headers Area: HTTP headers
Projects
None yet
Development

No branches or pull requests

3 participants