From 44f3c9fe84717a38385826627f88a38755712877 Mon Sep 17 00:00:00 2001 From: Dominic Date: Thu, 14 Jan 2021 18:37:51 +0100 Subject: [PATCH] add headers to the response (#27) --- derive/src/resource_error.rs | 10 +++++----- src/response.rs | 30 ++++++++++++++++++++++++------ src/result/mod.rs | 2 ++ src/result/no_content.rs | 1 + src/result/raw.rs | 1 + src/result/result.rs | 1 + src/result/success.rs | 1 + src/routing.rs | 13 ++++++++++++- tests/resource_error.rs | 1 + 9 files changed, 48 insertions(+), 12 deletions(-) diff --git a/derive/src/resource_error.rs b/derive/src/resource_error.rs index e2b78d0..a2b0955 100644 --- a/derive/src/resource_error.rs +++ b/derive/src/resource_error.rs @@ -196,11 +196,11 @@ impl ErrorVariant { quote!(#from_field.into_response_error()) }, (Some(_), Some(_)) => return Err(Error::new(ident.span(), "When #[from] is used, #[status] must not be used!")), - (None, Some(status)) => quote!(Ok(#krate::Response { - status: { #status }.into(), - body: #krate::gotham::hyper::Body::empty(), - mime: None - })), + (None, Some(status)) => quote!(Ok(#krate::Response::new( + { #status }.into(), + #krate::gotham::hyper::Body::empty(), + None + ))), (None, None) => return Err(Error::new(ident.span(), "Missing #[status(code)] for this variant")) }; diff --git a/src/response.rs b/src/response.rs index cc50325..b29aa4e 100644 --- a/src/response.rs +++ b/src/response.rs @@ -1,14 +1,23 @@ -use gotham::hyper::{Body, StatusCode}; +use gotham::hyper::{ + header::{HeaderMap, HeaderName, HeaderValue}, + Body, StatusCode +}; use mime::{Mime, APPLICATION_JSON}; /// A response, used to create the final gotham response from. #[derive(Debug)] pub struct Response { + #[deprecated(since = "0.1.2", note = "This field will be private in an upcomming release")] pub status: StatusCode, + #[deprecated(since = "0.1.2", note = "This field will be private in an upcomming release")] pub body: Body, - pub mime: Option + #[deprecated(since = "0.1.2", note = "This field will be private in an upcomming release")] + pub mime: Option, + #[deprecated(since = "0.1.2", note = "This field will be private in an upcomming release")] + pub headers: HeaderMap } +#[allow(deprecated)] impl Response { /// Create a new [Response] from raw data. #[must_use = "Creating a response is pointless if you don't use it"] @@ -16,7 +25,8 @@ impl Response { Self { status, body: body.into(), - mime + mime, + headers: Default::default() } } @@ -26,7 +36,8 @@ impl Response { Self { status, body: body.into(), - mime: Some(APPLICATION_JSON) + mime: Some(APPLICATION_JSON), + headers: Default::default() } } @@ -36,7 +47,8 @@ impl Response { Self { status: StatusCode::NO_CONTENT, body: Body::empty(), - mime: None + mime: None, + headers: Default::default() } } @@ -46,10 +58,16 @@ impl Response { Self { status: StatusCode::FORBIDDEN, body: Body::empty(), - mime: None + mime: None, + headers: Default::default() } } + /// Add an HTTP header to the [Response]. + pub fn add_header(&mut self, name: HeaderName, value: HeaderValue) { + self.headers.insert(name, value); + } + #[cfg(test)] pub(crate) fn full_body(mut self) -> Result, ::Error> { use futures_executor::block_on; diff --git a/src/result/mod.rs b/src/result/mod.rs index 526af33..7531dd1 100644 --- a/src/result/mod.rs +++ b/src/result/mod.rs @@ -99,6 +99,7 @@ fn errorlog(e: E) { #[cfg(not(feature = "errorlog"))] fn errorlog(_e: E) {} +#[allow(deprecated)] fn handle_error(e: E) -> Pin> + Send>> where E: Display + IntoResponseError @@ -160,6 +161,7 @@ mod test { struct MsgError; #[test] + #[allow(deprecated)] fn result_from_future() { let nc = NoContent::default(); let res = block_on(nc.into_response()).unwrap(); diff --git a/src/result/no_content.rs b/src/result/no_content.rs index 0c4fe05..e4ab932 100644 --- a/src/result/no_content.rs +++ b/src/result/no_content.rs @@ -92,6 +92,7 @@ where } #[cfg(test)] +#[allow(deprecated)] mod test { use super::*; use futures_executor::block_on; diff --git a/src/result/raw.rs b/src/result/raw.rs index 6b3b520..27d59c0 100644 --- a/src/result/raw.rs +++ b/src/result/raw.rs @@ -131,6 +131,7 @@ mod test { use mime::TEXT_PLAIN; #[test] + #[allow(deprecated)] fn raw_response() { let msg = "Test"; let raw = Raw::new(msg, TEXT_PLAIN); diff --git a/src/result/result.rs b/src/result/result.rs index f22d756..971689b 100644 --- a/src/result/result.rs +++ b/src/result/result.rs @@ -49,6 +49,7 @@ where } #[cfg(test)] +#[allow(deprecated)] mod test { use super::*; use crate::result::OrAllTypes; diff --git a/src/result/success.rs b/src/result/success.rs index a3816ea..40922a3 100644 --- a/src/result/success.rs +++ b/src/result/success.rs @@ -124,6 +124,7 @@ mod test { } #[test] + #[allow(deprecated)] fn success_always_successfull() { let success: Success = Msg::default().into(); let res = block_on(success.into_response()).expect("didn't expect error response"); diff --git a/src/routing.rs b/src/routing.rs index 940a51b..9076b2c 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -81,10 +81,21 @@ pub trait DrawResourceRoutes { fn remove(&mut self); } +#[allow(deprecated)] fn response_from(res: Response, state: &State) -> gotham::hyper::Response { let mut r = create_empty_response(state, res.status); + let headers = r.headers_mut(); if let Some(mime) = res.mime { - r.headers_mut().insert(CONTENT_TYPE, mime.as_ref().parse().unwrap()); + headers.insert(CONTENT_TYPE, mime.as_ref().parse().unwrap()); + } + let mut last_name = None; + for (name, value) in res.headers { + if name.is_some() { + last_name = name; + } + // this unwrap is safe: the first item will always be Some + let name = last_name.clone().unwrap(); + headers.insert(name, value); } let method = Method::borrow_from(state); diff --git a/tests/resource_error.rs b/tests/resource_error.rs index a00b08a..c850175 100644 --- a/tests/resource_error.rs +++ b/tests/resource_error.rs @@ -10,6 +10,7 @@ enum Error { InternalServerError(String) } +#[allow(deprecated)] mod resource_error { use super::Error; use gotham::hyper::StatusCode;