-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #1067 by importing typed headers from hyperx #1535
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
//! Re-exported hyper HTTP library types. | ||
//! Re-exported hyper HTTP library types and hyperx typed headers. | ||
//! | ||
//! All types that are re-exported from Hyper reside inside of this module. | ||
//! These types will, with certainty, be removed with time, but they reside here | ||
|
@@ -21,6 +21,9 @@ | |
|
||
/// Reexported http header types. | ||
pub mod header { | ||
use super::super::header::Header; | ||
pub use hyperx::header::Header as HyperxHeaderTrait; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is needed in order to call |
||
|
||
macro_rules! import_http_headers { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's simply remove these header names re-exported from There are a few places in |
||
($($name:ident),*) => ($( | ||
pub use http::header::$name as $name; | ||
|
@@ -43,4 +46,98 @@ pub mod header { | |
STRICT_TRANSPORT_SECURITY, TE, TRANSFER_ENCODING, UPGRADE, USER_AGENT, | ||
VARY | ||
} | ||
|
||
macro_rules! import_hyperx_items { | ||
($($item:ident),*) => ($(pub use hyperx::header::$item as $item;)*) | ||
} | ||
|
||
macro_rules! import_hyperx_headers { | ||
($($name:ident),*) => ($( | ||
impl ::std::convert::From<self::$name> for Header<'static> { | ||
fn from(header: self::$name) -> Header<'static> { | ||
Header::new($name::header_name(), header.to_string()) | ||
} | ||
} | ||
)*) | ||
} | ||
|
||
macro_rules! import_generic_hyperx_headers { | ||
($($name:ident<$bound:ident>),*) => ($( | ||
impl <T1: 'static + $bound> ::std::convert::From<self::$name<T1>> | ||
for Header<'static> { | ||
fn from(header: self::$name<T1>) -> Header<'static> { | ||
Header::new($name::<T1>::header_name(), header.to_string()) | ||
} | ||
} | ||
)*) | ||
} | ||
|
||
import_hyperx_items! { | ||
Accept, AcceptCharset, AcceptEncoding, AcceptLanguage, AcceptRanges, | ||
AccessControlAllowCredentials, AccessControlAllowHeaders, | ||
AccessControlAllowMethods, AccessControlAllowOrigin, | ||
AccessControlExposeHeaders, AccessControlMaxAge, | ||
AccessControlRequestHeaders, AccessControlRequestMethod, Allow, | ||
Authorization, Basic, Bearer, ByteRangeSpec, CacheControl, | ||
CacheDirective, Charset, Connection, ConnectionOption, | ||
ContentDisposition, ContentEncoding, ContentLanguage, ContentLength, | ||
ContentLocation, ContentRange, ContentRangeSpec, ContentType, Cookie, | ||
Date, DispositionParam, DispositionType, Encoding, EntityTag, ETag, | ||
Expect, Expires, From, Host, HttpDate, IfMatch, IfModifiedSince, | ||
IfNoneMatch, IfRange, IfUnmodifiedSince, LastEventId, LastModified, | ||
Link, LinkValue, Location, Origin, Pragma, Prefer, Preference, | ||
PreferenceApplied, Protocol, ProtocolName, ProxyAuthorization, Quality, | ||
QualityItem, Range, RangeUnit, Referer, ReferrerPolicy, RetryAfter, | ||
Scheme, Server, SetCookie, StrictTransportSecurity, | ||
Te, TransferEncoding, Upgrade, UserAgent, Vary, Warning, q, qitem | ||
} | ||
|
||
import_hyperx_headers! { | ||
Accept, AcceptCharset, AcceptEncoding, AcceptLanguage, AcceptRanges, | ||
AccessControlAllowCredentials, AccessControlAllowHeaders, | ||
AccessControlAllowMethods, AccessControlAllowOrigin, | ||
AccessControlExposeHeaders, AccessControlMaxAge, | ||
AccessControlRequestHeaders, AccessControlRequestMethod, Allow, | ||
CacheControl, Connection, ContentDisposition, ContentEncoding, | ||
ContentLanguage, ContentLength, ContentLocation, ContentRange, | ||
ContentType, Cookie, Date, ETag, Expires, Expect, From, Host, IfMatch, | ||
IfModifiedSince, IfNoneMatch, IfUnmodifiedSince, IfRange, LastEventId, | ||
LastModified, Link, Location, Origin, Pragma, Prefer, PreferenceApplied, | ||
Range, Referer, ReferrerPolicy, RetryAfter, Server, | ||
StrictTransportSecurity, Te, TransferEncoding, Upgrade, UserAgent, Vary, | ||
Warning | ||
} | ||
import_generic_hyperx_headers! { | ||
Authorization<Scheme>, | ||
ProxyAuthorization<Scheme> | ||
} | ||
// Note: SetCookie is missing, since it must be formatted as separate header lines... | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one isn't too bad a loss - |
||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::header::HeaderMap; | ||
use super::header::HyperxHeaderTrait; // Needed for Accept::header_name() below?!?! | ||
|
||
#[test] | ||
fn add_typed_header() { | ||
use super::header::{Accept, QualityItem, q, qitem}; | ||
let mut map = HeaderMap::new(); | ||
map.add(Accept(vec![ | ||
QualityItem::new("audio/*".parse().unwrap(), q(200)), | ||
qitem("audio/basic".parse().unwrap()), | ||
])); | ||
assert_eq!(map.get_one(Accept::header_name()), Some("audio/*; q=0.2, audio/basic")); | ||
} | ||
|
||
#[test] | ||
fn add_typed_header_with_type_params() { | ||
use super::header::{Authorization, Basic}; | ||
let mut map = HeaderMap::new(); | ||
map.add(Authorization(Basic { | ||
username: "admin".to_owned(), | ||
password: Some("12345678".to_owned())})); | ||
assert_eq!(map.get_one("Authorization"), Some("Basic YWRtaW46MTIzNDU2Nzg=")); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use rocket; | ||
|
||
use rocket::{get, routes}; | ||
use rocket::response::Responder; | ||
use rocket::http::hyper::header::{ContentLanguage, qitem}; | ||
use language_tags::langtag; | ||
|
||
#[derive(Responder)] | ||
struct DerivedResponder { | ||
text: &'static str, | ||
lang_header: ContentLanguage, | ||
} | ||
|
||
#[get("/")] | ||
fn index() -> DerivedResponder { | ||
DerivedResponder { | ||
text: "Fyr raketten af!", | ||
lang_header: ContentLanguage(vec![ | ||
qitem(langtag!(da)) | ||
]) | ||
} | ||
} | ||
|
||
#[test] | ||
fn test_derive_reexports() { | ||
use rocket::local::blocking::Client; | ||
|
||
let rocket = rocket::ignite().mount("/", routes![index]); | ||
let client = Client::tracked(rocket).unwrap(); | ||
|
||
let response = client.get("/").dispatch(); | ||
let content_languages = response.headers().get_one("content-language"); | ||
assert_eq!(content_languages, Some("da")); | ||
assert_eq!(response.into_string().unwrap(), "Fyr raketten af!"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is actually a bit weird, now that I'm seeing it. Can we try moving the
headers
parts into e.g.core/http/src/headers.rs
instead?