pca9956b_api/
context.rs

1use futures::Future;
2use hyper;
3use hyper::header::HeaderName;
4use hyper::{Error, Request, Response, StatusCode, service::Service, body::Payload};
5use url::form_urlencoded;
6use std::default::Default;
7use std::io;
8use std::marker::PhantomData;
9use swagger::auth::{AuthData, Authorization, Bearer, Scopes};
10use swagger::context::ContextualPayload;
11use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString};
12use crate::Api;
13
14pub struct MakeAddContext<T, A> {
15    inner: T,
16    marker: PhantomData<A>,
17}
18
19impl<T, A, B, C, D> MakeAddContext<T, A>
20where
21    A: Default + Push<XSpanIdString, Result = B>,
22    B: Push<Option<AuthData>, Result = C>,
23    C: Push<Option<Authorization>, Result = D>,
24{
25    pub fn new(inner: T) -> MakeAddContext<T, A> {
26        MakeAddContext {
27            inner,
28            marker: PhantomData,
29        }
30    }
31}
32
33// Make a service that adds context.
34impl<'a, T, SC, A, B, C, D, E, ME, S, OB, F> hyper::service::MakeService<&'a SC> for
35    MakeAddContext<T, A>
36where
37    A: Default + Push<XSpanIdString, Result = B>,
38    B: Push<Option<AuthData>, Result = C>,
39    C: Push<Option<Authorization>, Result = D>,
40    D: Send + 'static,
41    T: hyper::service::MakeService<
42            &'a SC,
43            Error = E,
44            MakeError = ME,
45            Service = S,
46            ReqBody = ContextualPayload<hyper::Body, D>,
47            ResBody = OB,
48            Future = F
49    >,
50    S: Service<
51            Error = E,
52            ReqBody = ContextualPayload<hyper::Body, D>,
53            ResBody = OB> + 'static,
54    ME: swagger::ErrorBound,
55    E: swagger::ErrorBound,
56    F: Future<Item=S, Error=ME> + Send + 'static,
57    S::Future: Send,
58    OB: Payload,
59{
60    type ReqBody = hyper::Body;
61    type ResBody = OB;
62    type Error = E;
63    type MakeError = ME;
64    type Service = AddContext<S, A>;
65    type Future = Box<dyn Future<Item = Self::Service, Error = ME> + Send + 'static>;
66
67    fn make_service(&mut self, ctx: &'a SC) -> Self::Future {
68        Box::new(self.inner.make_service(ctx).map(|s| AddContext::new(s)))
69    }
70}
71
72/// Middleware to extract authentication data from request
73pub struct AddContext<T, A> {
74    inner: T,
75    marker: PhantomData<A>,
76}
77
78impl<T, A, B, C, D> AddContext<T, A>
79where
80    A: Default + Push<XSpanIdString, Result = B>,
81    B: Push<Option<AuthData>, Result = C>,
82    C: Push<Option<Authorization>, Result = D>,
83    T: Service,
84{
85    pub fn new(inner: T) -> AddContext<T, A> {
86        AddContext {
87            inner,
88            marker: PhantomData,
89        }
90    }
91}
92
93impl<T, A, B, C, D> Service for AddContext<T, A>
94    where
95        A: Default + Push<XSpanIdString, Result=B>,
96        B: Push<Option<AuthData>, Result=C>,
97        C: Push<Option<Authorization>, Result=D>,
98        D: Send + 'static,
99        T: Service<ReqBody = ContextualPayload<hyper::Body, D>>,
100        T::Future: Future<Item=Response<T::ResBody>, Error=T::Error> + Send + 'static
101{
102    type ReqBody = hyper::Body;
103    type ResBody = T::ResBody;
104    type Error = T::Error;
105    type Future = Box<dyn Future<Item=Response<T::ResBody>, Error=T::Error> + Send + 'static>;
106
107    fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future {
108        let context = A::default().push(XSpanIdString::get_or_generate(&req));
109        let (head, body) = req.into_parts();
110        let headers = head.headers.clone();
111
112
113        let context = context.push(None::<AuthData>);
114        let context = context.push(None::<Authorization>);
115        let body = ContextualPayload {
116            inner: body,
117            context: context,
118        };
119
120        Box::new(self.inner.call(hyper::Request::from_parts(head, body)))
121    }
122}