1
0
Fork 0
mirror of https://gitlab.com/msrd0/gotham-restful.git synced 2025-04-20 06:54:46 +00:00

update to gotham 0.5 and start using rustfmt

This commit is contained in:
Dominic 2020-09-15 15:10:41 +02:00
parent 5317e50961
commit d55b0897e9
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
39 changed files with 1798 additions and 2095 deletions

View file

@ -4,22 +4,19 @@ use gotham::{
helpers::http::response::create_empty_response,
hyper::{
header::{
ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS,
ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_MAX_AGE, ACCESS_CONTROL_REQUEST_METHOD, ORIGIN, VARY,
HeaderMap, HeaderName, HeaderValue
HeaderMap, HeaderName, HeaderValue, ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS,
ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_MAX_AGE,
ACCESS_CONTROL_REQUEST_METHOD, ORIGIN, VARY
},
Body, Method, Response, StatusCode
},
middleware::Middleware,
pipeline::chain::PipelineHandleChain,
router::builder::*,
state::{FromState, State},
state::{FromState, State}
};
use itertools::Itertools;
use std::{
panic::RefUnwindSafe,
pin::Pin
};
use std::{panic::RefUnwindSafe, pin::Pin};
/**
Specify the allowed origins of the request. It is up to the browser to check the validity of the
@ -27,8 +24,7 @@ origin. This, when sent to the browser, will indicate whether or not the request
allowed to make the request.
*/
#[derive(Clone, Debug)]
pub enum Origin
{
pub enum Origin {
/// Do not send any `Access-Control-Allow-Origin` headers.
None,
/// Send `Access-Control-Allow-Origin: *`. Note that browser will not send credentials.
@ -39,19 +35,15 @@ pub enum Origin
Copy
}
impl Default for Origin
{
fn default() -> Self
{
impl Default for Origin {
fn default() -> Self {
Self::None
}
}
impl Origin
{
impl Origin {
/// Get the header value for the `Access-Control-Allow-Origin` header.
fn header_value(&self, state : &State) -> Option<HeaderValue>
{
fn header_value(&self, state: &State) -> Option<HeaderValue> {
match self {
Self::None => None,
Self::Star => Some("*".parse().unwrap()),
@ -126,23 +118,21 @@ gotham::start("127.0.0.1:8080", build_router((), pipeline_set, |route| {
[`State`]: ../gotham/state/struct.State.html
*/
#[derive(Clone, Debug, Default, NewMiddleware, StateData)]
pub struct CorsConfig
{
pub struct CorsConfig {
/// The allowed origins.
pub origin : Origin,
pub origin: Origin,
/// The allowed headers.
pub headers : Vec<HeaderName>,
pub headers: Vec<HeaderName>,
/// The amount of seconds that the preflight request can be cached.
pub max_age : u64,
pub max_age: u64,
/// Whether or not the request may be made with supplying credentials.
pub credentials : bool
pub credentials: bool
}
impl Middleware for CorsConfig
{
fn call<Chain>(self, mut state : State, chain : Chain) -> Pin<Box<HandlerFuture>>
impl Middleware for CorsConfig {
fn call<Chain>(self, mut state: State, chain: Chain) -> Pin<Box<HandlerFuture>>
where
Chain : FnOnce(State) -> Pin<Box<HandlerFuture>>
Chain: FnOnce(State) -> Pin<Box<HandlerFuture>>
{
state.put(self);
chain(state)
@ -161,35 +151,31 @@ For further information on CORS, read https://developer.mozilla.org/en-US/docs/W
[`CorsConfig`]: ./struct.CorsConfig.html
*/
pub fn handle_cors(state : &State, res : &mut Response<Body>)
{
pub fn handle_cors(state: &State, res: &mut Response<Body>) {
let config = CorsConfig::try_borrow_from(state);
let headers = res.headers_mut();
// non-preflight requests require the Access-Control-Allow-Origin header
if let Some(header) = config.and_then(|cfg| cfg.origin.header_value(state))
{
if let Some(header) = config.and_then(|cfg| cfg.origin.header_value(state)) {
headers.insert(ACCESS_CONTROL_ALLOW_ORIGIN, header);
}
// if the origin is copied over, we should tell the browser by specifying the Vary header
if matches!(config.map(|cfg| &cfg.origin), Some(Origin::Copy))
{
if matches!(config.map(|cfg| &cfg.origin), Some(Origin::Copy)) {
let vary = headers.get(VARY).map(|vary| format!("{},Origin", vary.to_str().unwrap()));
headers.insert(VARY, vary.as_deref().unwrap_or("Origin").parse().unwrap());
}
// if we allow credentials, tell the browser
if config.map(|cfg| cfg.credentials).unwrap_or(false)
{
if config.map(|cfg| cfg.credentials).unwrap_or(false) {
headers.insert(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true".parse().unwrap());
}
}
/// Add CORS routing for your path. This is required for handling preflight requests.
///
///
/// Example:
///
///
/// ```rust,no_run
/// # use gotham::{hyper::{Body, Method, Response}, router::builder::*};
/// # use gotham_restful::*;
@ -206,16 +192,15 @@ pub fn handle_cors(state : &State, res : &mut Response<Body>)
/// ```
pub trait CorsRoute<C, P>
where
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P : RefUnwindSafe + Send + Sync + 'static
C: PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P: RefUnwindSafe + Send + Sync + 'static
{
/// Handle a preflight request on `path` for `method`. To configure the behaviour, use
/// [`CorsConfig`](struct.CorsConfig.html).
fn cors(&mut self, path : &str, method : Method);
fn cors(&mut self, path: &str, method: Method);
}
fn cors_preflight_handler(state : State) -> (State, Response<Body>)
{
fn cors_preflight_handler(state: State) -> (State, Response<Body>) {
let config = CorsConfig::try_borrow_from(&state);
// prepare the response
@ -223,43 +208,40 @@ fn cors_preflight_handler(state : State) -> (State, Response<Body>)
let headers = res.headers_mut();
// copy the request method over to the response
let method = HeaderMap::borrow_from(&state).get(ACCESS_CONTROL_REQUEST_METHOD).unwrap().clone();
let method = HeaderMap::borrow_from(&state)
.get(ACCESS_CONTROL_REQUEST_METHOD)
.unwrap()
.clone();
headers.insert(ACCESS_CONTROL_ALLOW_METHODS, method);
// if we allow any headers, put them in
if let Some(hdrs) = config.map(|cfg| &cfg.headers)
{
if hdrs.len() > 0
{
if let Some(hdrs) = config.map(|cfg| &cfg.headers) {
if hdrs.len() > 0 {
// TODO do we want to return all headers or just those asked by the browser?
headers.insert(ACCESS_CONTROL_ALLOW_HEADERS, hdrs.iter().join(",").parse().unwrap());
}
}
// set the max age for the preflight cache
if let Some(age) = config.map(|cfg| cfg.max_age)
{
if let Some(age) = config.map(|cfg| cfg.max_age) {
headers.insert(ACCESS_CONTROL_MAX_AGE, age.into());
}
// make sure the browser knows that this request was based on the method
headers.insert(VARY, "Access-Control-Request-Method".parse().unwrap());
handle_cors(&state, &mut res);
(state, res)
}
impl<D, C, P> CorsRoute<C, P> for D
where
D : DrawRoutes<C, P>,
C : PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P : RefUnwindSafe + Send + Sync + 'static
D: DrawRoutes<C, P>,
C: PipelineHandleChain<P> + Copy + Send + Sync + 'static,
P: RefUnwindSafe + Send + Sync + 'static
{
fn cors(&mut self, path : &str, method : Method)
{
fn cors(&mut self, path: &str, method: Method) {
let matcher = AccessControlRequestMethodMatcher::new(method);
self.options(path)
.extend_route_matcher(matcher)
.to(cors_preflight_handler);
self.options(path).extend_route_matcher(matcher).to(cors_preflight_handler);
}
}