summaryrefslogtreecommitdiff
path: root/vendor/hyper/src/service
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/hyper/src/service')
-rw-r--r--vendor/hyper/src/service/http.rs52
-rw-r--r--vendor/hyper/src/service/mod.rs30
-rw-r--r--vendor/hyper/src/service/service.rs100
-rw-r--r--vendor/hyper/src/service/util.rs82
4 files changed, 264 insertions, 0 deletions
diff --git a/vendor/hyper/src/service/http.rs b/vendor/hyper/src/service/http.rs
new file mode 100644
index 00000000..dd174316
--- /dev/null
+++ b/vendor/hyper/src/service/http.rs
@@ -0,0 +1,52 @@
+use std::error::Error as StdError;
+use std::future::Future;
+
+use crate::body::Body;
+use crate::service::service::Service;
+use crate::{Request, Response};
+
+/// An asynchronous function from `Request` to `Response`.
+pub trait HttpService<ReqBody>: sealed::Sealed<ReqBody> {
+ /// The `Body` body of the `http::Response`.
+ type ResBody: Body;
+
+ /// The error type that can occur within this `Service`.
+ ///
+ /// Note: Returning an `Error` to a hyper server will cause the connection
+ /// to be abruptly aborted. In most cases, it is better to return a `Response`
+ /// with a 4xx or 5xx status code.
+ type Error: Into<Box<dyn StdError + Send + Sync>>;
+
+ /// The `Future` returned by this `Service`.
+ type Future: Future<Output = Result<Response<Self::ResBody>, Self::Error>>;
+
+ #[doc(hidden)]
+ fn call(&mut self, req: Request<ReqBody>) -> Self::Future;
+}
+
+impl<T, B1, B2> HttpService<B1> for T
+where
+ T: Service<Request<B1>, Response = Response<B2>>,
+ B2: Body,
+ T::Error: Into<Box<dyn StdError + Send + Sync>>,
+{
+ type ResBody = B2;
+
+ type Error = T::Error;
+ type Future = T::Future;
+
+ fn call(&mut self, req: Request<B1>) -> Self::Future {
+ Service::call(self, req)
+ }
+}
+
+impl<T, B1, B2> sealed::Sealed<B1> for T
+where
+ T: Service<Request<B1>, Response = Response<B2>>,
+ B2: Body,
+{
+}
+
+mod sealed {
+ pub trait Sealed<T> {}
+}
diff --git a/vendor/hyper/src/service/mod.rs b/vendor/hyper/src/service/mod.rs
new file mode 100644
index 00000000..28ffaddb
--- /dev/null
+++ b/vendor/hyper/src/service/mod.rs
@@ -0,0 +1,30 @@
+//! Asynchronous Services
+//!
+//! A [`Service`] is a trait representing an asynchronous
+//! function of a request to a response. It's similar to
+//! `async fn(Request) -> Result<Response, Error>`.
+//!
+//! The argument and return value isn't strictly required to be for HTTP.
+//! Therefore, hyper uses several "trait aliases" to reduce clutter around
+//! bounds. These are:
+//!
+//! - `HttpService`: This is blanketly implemented for all types that
+//! implement `Service<http::Request<B1>, Response = http::Response<B2>>`.
+//!
+//! # HttpService
+//!
+//! In hyper, especially in the server setting, a `Service` is usually bound
+//! to a single connection. It defines how to respond to **all** requests that
+//! connection will receive.
+//!
+//! The helper [`service_fn`] should be sufficient for most cases, but
+//! if you need to implement `Service` for a type manually, you can follow the example
+//! in `service_struct_impl.rs`.
+
+mod http;
+mod service;
+mod util;
+
+pub use self::http::HttpService;
+pub use self::service::Service;
+pub use self::util::service_fn;
diff --git a/vendor/hyper/src/service/service.rs b/vendor/hyper/src/service/service.rs
new file mode 100644
index 00000000..42c18e72
--- /dev/null
+++ b/vendor/hyper/src/service/service.rs
@@ -0,0 +1,100 @@
+use std::future::Future;
+
+/// An asynchronous function from a `Request` to a `Response`.
+///
+/// The `Service` trait is a simplified interface making it easy to write
+/// network applications in a modular and reusable way, decoupled from the
+/// underlying protocol.
+///
+/// # Functional
+///
+/// A `Service` is a function of a `Request`. It immediately returns a
+/// `Future` representing the eventual completion of processing the
+/// request. The actual request processing may happen at any time in the
+/// future, on any thread or executor. The processing may depend on calling
+/// other services. At some point in the future, the processing will complete,
+/// and the `Future` will resolve to a response or error.
+///
+/// At a high level, the `Service::call` function represents an RPC request. The
+/// `Service` value can be a server or a client.
+pub trait Service<Request> {
+ /// Responses given by the service.
+ type Response;
+
+ /// Errors produced by the service.
+ ///
+ /// Note: Returning an `Error` to a hyper server, the behavior depends on the
+ /// protocol. In most cases, hyper will cause the connection to be abruptly aborted.
+ /// It will abort the request however the protocol allows, either with some sort of RST_STREAM,
+ /// or killing the connection if that doesn't exist.
+ type Error;
+
+ /// The future response value.
+ type Future: Future<Output = Result<Self::Response, Self::Error>>;
+
+ /// Process the request and return the response asynchronously.
+ /// `call` takes `&self` instead of `mut &self` because:
+ /// - It prepares the way for async fn,
+ /// since then the future only borrows `&self`, and thus a Service can concurrently handle
+ /// multiple outstanding requests at once.
+ /// - It's clearer that Services can likely be cloned
+ /// - To share state across clones, you generally need `Arc<Mutex<_>>`
+ /// That means you're not really using the `&mut self` and could do with a `&self`.
+ /// The discussion on this is here: <https://github.com/hyperium/hyper/issues/3040>
+ fn call(&self, req: Request) -> Self::Future;
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ S {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ mut S {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for Box<S> {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::rc::Rc<S> {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::sync::Arc<S> {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}
diff --git a/vendor/hyper/src/service/util.rs b/vendor/hyper/src/service/util.rs
new file mode 100644
index 00000000..3e017a78
--- /dev/null
+++ b/vendor/hyper/src/service/util.rs
@@ -0,0 +1,82 @@
+use std::error::Error as StdError;
+use std::fmt;
+use std::future::Future;
+use std::marker::PhantomData;
+
+use crate::body::Body;
+use crate::service::service::Service;
+use crate::{Request, Response};
+
+/// Create a `Service` from a function.
+///
+/// # Example
+///
+/// ```
+/// use bytes::Bytes;
+/// use hyper::{body, Request, Response, Version};
+/// use http_body_util::Full;
+/// use hyper::service::service_fn;
+///
+/// let service = service_fn(|req: Request<body::Incoming>| async move {
+/// if req.version() == Version::HTTP_11 {
+/// Ok(Response::new(Full::<Bytes>::from("Hello World")))
+/// } else {
+/// // Note: it's usually better to return a Response
+/// // with an appropriate StatusCode instead of an Err.
+/// Err("not HTTP/1.1, abort connection")
+/// }
+/// });
+/// ```
+pub fn service_fn<F, R, S>(f: F) -> ServiceFn<F, R>
+where
+ F: Fn(Request<R>) -> S,
+ S: Future,
+{
+ ServiceFn {
+ f,
+ _req: PhantomData,
+ }
+}
+
+/// Service returned by [`service_fn`]
+pub struct ServiceFn<F, R> {
+ f: F,
+ _req: PhantomData<fn(R)>,
+}
+
+impl<F, ReqBody, Ret, ResBody, E> Service<Request<ReqBody>> for ServiceFn<F, ReqBody>
+where
+ F: Fn(Request<ReqBody>) -> Ret,
+ ReqBody: Body,
+ Ret: Future<Output = Result<Response<ResBody>, E>>,
+ E: Into<Box<dyn StdError + Send + Sync>>,
+ ResBody: Body,
+{
+ type Response = crate::Response<ResBody>;
+ type Error = E;
+ type Future = Ret;
+
+ fn call(&self, req: Request<ReqBody>) -> Self::Future {
+ (self.f)(req)
+ }
+}
+
+impl<F, R> fmt::Debug for ServiceFn<F, R> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("impl Service").finish()
+ }
+}
+
+impl<F, R> Clone for ServiceFn<F, R>
+where
+ F: Clone,
+{
+ fn clone(&self) -> Self {
+ ServiceFn {
+ f: self.f.clone(),
+ _req: PhantomData,
+ }
+ }
+}
+
+impl<F, R> Copy for ServiceFn<F, R> where F: Copy {}