diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f490a1798..6046a75754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added +- Add `SafeHeaders` to work around Hyper 0.11 panic handling differently type headers with the same name - e.g. Authorization +- Fix warnings present on Rust 1.39 ### Changed diff --git a/src/base64_format.rs b/src/base64_format.rs index b00f1e875a..df4ee4e6ef 100644 --- a/src/base64_format.rs +++ b/src/base64_format.rs @@ -29,7 +29,7 @@ impl<'de> Deserialize<'de> for ByteArray { where D: Deserializer<'de>, { - let s = try!(String::deserialize(deserializer)); + let s = String::deserialize(deserializer)?; match decode(&s) { Ok(bin) => Ok(ByteArray(bin)), _ => Err(D::Error::custom("invalid base64")), diff --git a/src/composites.rs b/src/composites.rs index a32bf9981a..7b9582727c 100644 --- a/src/composites.rs +++ b/src/composites.rs @@ -41,10 +41,10 @@ impl NotFound for Response { } } -type BoxedFuture = Box>; -type CompositeNewServiceVec = Vec<(&'static str, Box>)>; +type BoxedFuture = Box>; +type CompositeNewServiceVec = Vec<(&'static str, Box>)>; type BoxedService = - Box>>; + Box>>; /// Trait for wrapping hyper `NewService`s to make the return type of `new_service` uniform. /// This is necessary in order for the `NewService`s with different `Instance` types to @@ -185,7 +185,7 @@ where type Request = U; type Response = V; type Error = W; - type Future = Box>; + type Future = Box>; fn call(&self, req: Self::Request) -> Self::Future { let mut result = None; diff --git a/src/connector.rs b/src/connector.rs index 968803079e..c1e901b3e7 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -13,7 +13,7 @@ use hyper; /// Returns a function which creates an http-connector. Used for instantiating /// clients with custom connectors -pub fn http_connector() -> Box hyper::client::HttpConnector + Send + Sync> { +pub fn http_connector() -> Box hyper::client::HttpConnector + Send + Sync> { Box::new(move |handle: &Handle| hyper::client::HttpConnector::new(4, handle)) } @@ -25,7 +25,7 @@ pub fn http_connector() -> Box hyper::client::HttpConnector + Sen #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn https_connector( ca_certificate: CA, -) -> Box hyper_tls::HttpsConnector + Send + Sync> +) -> Box hyper_tls::HttpsConnector + Send + Sync> where CA: AsRef, { @@ -53,7 +53,7 @@ where #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] pub fn https_connector( _ca_certificate: CA, -) -> Box hyper_tls::HttpsConnector + Send + Sync> +) -> Box hyper_tls::HttpsConnector + Send + Sync> where CA: AsRef, { @@ -71,7 +71,7 @@ pub fn https_mutual_connector( ca_certificate: CA, client_key: K, client_certificate: C, -) -> Box hyper_tls::HttpsConnector + Send + Sync> +) -> Box hyper_tls::HttpsConnector + Send + Sync> where CA: AsRef, K: AsRef, @@ -112,7 +112,7 @@ pub fn https_mutual_connector( _ca_certificate: CA, _client_key: K, _client_certificate: C, -) -> Box hyper_tls::HttpsConnector + Send + Sync> +) -> Box hyper_tls::HttpsConnector + Send + Sync> where CA: AsRef, K: AsRef, diff --git a/src/context.rs b/src/context.rs index 2c10be567a..b8faddee2c 100644 --- a/src/context.rs +++ b/src/context.rs @@ -38,7 +38,7 @@ use std::marker::Sized; /// type Request = (hyper::Request, C); /// type Response = hyper::Response; /// type Error = hyper::Error; -/// type Future = Box>; +/// type Future = Box>; /// fn call(&self, (req, context) : Self::Request) -> Self::Future { /// do_something_with_my_item(Has::::get(&context)); /// Box::new(ok(hyper::Response::new())) @@ -546,7 +546,7 @@ pub trait SwaggerService: Request = (hyper::server::Request, C), Response = hyper::server::Response, Error = hyper::Error, - Future = Box>, + Future = Box>, > where C: Has> + Has> + Has + Clone + 'static, @@ -560,7 +560,7 @@ where Request = (hyper::server::Request, C), Response = hyper::server::Response, Error = hyper::Error, - Future = Box>, + Future = Box>, >, C: Has> + Has> + Has + Clone + 'static, { @@ -603,7 +603,7 @@ mod context_tests { type Request = (Request, C); type Response = Response; type Error = Error; - type Future = Box>; + type Future = Box>; fn call(&self, (_, context): Self::Request) -> Self::Future { use_item_2(Has::::get(&context)); diff --git a/src/headers.rs b/src/headers.rs new file mode 100644 index 0000000000..e6348186b5 --- /dev/null +++ b/src/headers.rs @@ -0,0 +1,39 @@ +//! Support library for handling headers in a safe manner + +use hyper::header::{Header, Headers}; + +/// Trait to add a mechanism to safely retrieve a header. +/// +/// In Hyper 0.11, if you add an Authorization header, +/// and then attempt get an Authorization header, the code +/// will panic, as the type ID doesn't match. +pub trait SafeHeaders { + /// Safely get a header from a hyper::header::Headers + fn safe_get(&self) -> Option; +} + +impl SafeHeaders for Headers { + fn safe_get(&self) -> Option { + self.get_raw(H::header_name()) + .map(H::parse_header) + .map(Result::ok) + .unwrap_or(None) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use hyper::header::{Authorization, Basic, Bearer}; + + #[test] + fn test() { + let mut headers = Headers::default(); + let basic = Basic { + username: "richard".to_string(), + password: None, + }; + headers.set::>(Authorization(basic)); + println!("Auth: {:?}", headers.safe_get::>()); + } +} diff --git a/src/lib.rs b/src/lib.rs index 16b8e56dd0..49e7a07ec0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,8 @@ pub use drop_context::DropContext; pub mod request_parser; pub use request_parser::RequestParser; +pub mod headers; + header! { /// `X-Span-ID` header, used to track a request through a chain of microservices. (XSpanId, "X-Span-ID") => [String] @@ -91,7 +93,7 @@ pub struct ApiError(pub String); impl fmt::Display for ApiError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let debug: &fmt::Debug = self; + let debug: &dyn fmt::Debug = self; debug.fmt(f) } }