feat(service): rename Service to HttpService, re-export tower::Service`
The only important trait for a user is the `tower::Service` trait, which is now available also at `hyper::service::Service`. The other "trait aliases" are no longer publicly exported, as people thought they had to implement them. Also removes dependency on `tower-make`, which is trivial but otherwise shouldn't affect anyone. Closes #1959
This commit is contained in:
@@ -34,7 +34,6 @@ log = "0.4"
|
|||||||
pin-project = "0.4"
|
pin-project = "0.4"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
tower-service = "=0.3.0-alpha.2"
|
tower-service = "=0.3.0-alpha.2"
|
||||||
tower-make = { version = "=0.3.0-alpha.2a", features = ['io'] }
|
|
||||||
tokio-executor = "=0.2.0-alpha.6"
|
tokio-executor = "=0.2.0-alpha.6"
|
||||||
tokio-io = "=0.2.0-alpha.6"
|
tokio-io = "=0.2.0-alpha.6"
|
||||||
tokio-sync = "=0.2.0-alpha.6"
|
tokio-sync = "=0.2.0-alpha.6"
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
#![deny(warnings)]
|
||||||
|
|
||||||
use hyper::client::service::{Connect, Service, MakeService};
|
use hyper::client::service::Connect;
|
||||||
use hyper::client::conn::Builder;
|
use hyper::client::conn::Builder;
|
||||||
use hyper::client::connect::HttpConnector;
|
use hyper::client::connect::HttpConnector;
|
||||||
|
use hyper::service::Service;
|
||||||
use hyper::{Body, Request};
|
use hyper::{Body, Request};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
@@ -13,7 +15,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let uri = "http://127.0.0.1:8080".parse::<http::Uri>()?;
|
let uri = "http://127.0.0.1:8080".parse::<http::Uri>()?;
|
||||||
|
|
||||||
|
|
||||||
let mut svc = mk_svc.make_service(uri.clone()).await?;
|
let mut svc = mk_svc.call(uri.clone()).await?;
|
||||||
|
|
||||||
let body = Body::empty();
|
let body = Body::empty();
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
|
||||||
use hyper::{Body, Request, Response, Server};
|
|
||||||
use tower_service::Service;
|
|
||||||
use futures_util::future;
|
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
|
use futures_util::future;
|
||||||
|
use hyper::{Body, Request, Response, Server};
|
||||||
|
use hyper::service::Service;
|
||||||
|
|
||||||
const ROOT: &'static str = "/";
|
const ROOT: &'static str = "/";
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
//! Utilities used to interact with the Tower ecosystem.
|
//! Utilities used to interact with the Tower ecosystem.
|
||||||
//!
|
//!
|
||||||
//! This module provides exports of `Service`, `MakeService` and `Connect` which
|
//! This module provides `Connect` which hook-ins into the Tower ecosystem.
|
||||||
//! all provide hook-ins into the Tower ecosystem.
|
|
||||||
|
|
||||||
use super::conn::{SendRequest, Builder};
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use crate::{common::{Poll, task, Pin}, body::Payload};
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use tower_make::MakeConnection;
|
|
||||||
|
|
||||||
pub use tower_service::Service;
|
use crate::{common::{Poll, task, Pin}, body::Payload, service::{MakeConnection, Service}};
|
||||||
pub use tower_make::MakeService;
|
use super::conn::{SendRequest, Builder};
|
||||||
|
|
||||||
/// Creates a connection via `SendRequest`.
|
/// Creates a connection via `SendRequest`.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ use tokio_executor::{SpawnError, TypedExecutor};
|
|||||||
use crate::body::{Payload, Body};
|
use crate::body::{Payload, Body};
|
||||||
use crate::proto::h2::server::H2Stream;
|
use crate::proto::h2::server::H2Stream;
|
||||||
use crate::server::conn::spawn_all::{NewSvcTask, Watcher};
|
use crate::server::conn::spawn_all::{NewSvcTask, Watcher};
|
||||||
use crate::service::Service;
|
use crate::service::HttpService;
|
||||||
|
|
||||||
pub trait H2Exec<F, B: Payload>: Clone {
|
pub trait H2Exec<F, B: Payload>: Clone {
|
||||||
fn execute_h2stream(&mut self, fut: H2Stream<F, B>) -> crate::Result<()>;
|
fn execute_h2stream(&mut self, fut: H2Stream<F, B>) -> crate::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait NewSvcExec<I, N, S: Service<Body>, E, W: Watcher<I, S, E>>: Clone {
|
pub trait NewSvcExec<I, N, S: HttpService<Body>, E, W: Watcher<I, S, E>>: Clone {
|
||||||
fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) -> crate::Result<()>;
|
fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) -> crate::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ where
|
|||||||
impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for Exec
|
impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for Exec
|
||||||
where
|
where
|
||||||
NewSvcTask<I, N, S, E, W>: Future<Output=()> + Send + 'static,
|
NewSvcTask<I, N, S, E, W>: Future<Output=()> + Send + 'static,
|
||||||
S: Service<Body>,
|
S: HttpService<Body>,
|
||||||
W: Watcher<I, S, E>,
|
W: Watcher<I, S, E>,
|
||||||
{
|
{
|
||||||
fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) -> crate::Result<()> {
|
fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) -> crate::Result<()> {
|
||||||
@@ -148,7 +148,7 @@ impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for E
|
|||||||
where
|
where
|
||||||
E: TypedExecutor<NewSvcTask<I, N, S, E, W>> + Clone,
|
E: TypedExecutor<NewSvcTask<I, N, S, E, W>> + Clone,
|
||||||
NewSvcTask<I, N, S, E, W>: Future<Output=()>,
|
NewSvcTask<I, N, S, E, W>: Future<Output=()>,
|
||||||
S: Service<Body>,
|
S: HttpService<Body>,
|
||||||
W: Watcher<I, S, E>,
|
W: Watcher<I, S, E>,
|
||||||
{
|
{
|
||||||
fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) -> crate::Result<()> {
|
fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) -> crate::Result<()> {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::body::{Body, Payload};
|
|||||||
use crate::common::{Future, Never, Poll, Pin, Unpin, task};
|
use crate::common::{Future, Never, Poll, Pin, Unpin, task};
|
||||||
use crate::proto::{BodyLength, DecodedLength, Conn, Dispatched, MessageHead, RequestHead, RequestLine, ResponseHead};
|
use crate::proto::{BodyLength, DecodedLength, Conn, Dispatched, MessageHead, RequestHead, RequestLine, ResponseHead};
|
||||||
use super::Http1Transaction;
|
use super::Http1Transaction;
|
||||||
use crate::service::Service;
|
use crate::service::HttpService;
|
||||||
|
|
||||||
pub(crate) struct Dispatcher<D, Bs: Payload, I, T> {
|
pub(crate) struct Dispatcher<D, Bs: Payload, I, T> {
|
||||||
conn: Conn<I, Bs::Data, T>,
|
conn: Conn<I, Bs::Data, T>,
|
||||||
@@ -29,7 +29,7 @@ pub(crate) trait Dispatch {
|
|||||||
fn should_poll(&self) -> bool;
|
fn should_poll(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Server<S: Service<B>, B> {
|
pub struct Server<S: HttpService<B>, B> {
|
||||||
in_flight: Pin<Box<Option<S::Future>>>,
|
in_flight: Pin<Box<Option<S::Future>>>,
|
||||||
pub(crate) service: S,
|
pub(crate) service: S,
|
||||||
}
|
}
|
||||||
@@ -407,7 +407,7 @@ impl<'a, T> Drop for OptGuard<'a, T> {
|
|||||||
|
|
||||||
impl<S, B> Server<S, B>
|
impl<S, B> Server<S, B>
|
||||||
where
|
where
|
||||||
S: Service<B>,
|
S: HttpService<B>,
|
||||||
{
|
{
|
||||||
pub fn new(service: S) -> Server<S, B> {
|
pub fn new(service: S) -> Server<S, B> {
|
||||||
Server {
|
Server {
|
||||||
@@ -422,11 +422,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Service is never pinned
|
// Service is never pinned
|
||||||
impl<S: Service<B>, B> Unpin for Server<S, B> {}
|
impl<S: HttpService<B>, B> Unpin for Server<S, B> {}
|
||||||
|
|
||||||
impl<S, Bs> Dispatch for Server<S, Body>
|
impl<S, Bs> Dispatch for Server<S, Body>
|
||||||
where
|
where
|
||||||
S: Service<Body, ResBody=Bs>,
|
S: HttpService<Body, ResBody=Bs>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
Bs: Payload,
|
Bs: Payload,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use crate::common::exec::H2Exec;
|
|||||||
use crate::common::{Future, Pin, Poll, task};
|
use crate::common::{Future, Pin, Poll, task};
|
||||||
use crate::headers;
|
use crate::headers;
|
||||||
use crate::headers::content_length_parse_all;
|
use crate::headers::content_length_parse_all;
|
||||||
use crate::service::Service;
|
use crate::service::HttpService;
|
||||||
use crate::proto::Dispatched;
|
use crate::proto::Dispatched;
|
||||||
use super::{PipeToSendStream, SendBuf};
|
use super::{PipeToSendStream, SendBuf};
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ use crate::{Body, Response};
|
|||||||
|
|
||||||
pub(crate) struct Server<T, S, B, E>
|
pub(crate) struct Server<T, S, B, E>
|
||||||
where
|
where
|
||||||
S: Service<Body>,
|
S: HttpService<Body>,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
{
|
{
|
||||||
exec: E,
|
exec: E,
|
||||||
@@ -28,7 +28,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fix me
|
// TODO: fix me
|
||||||
impl<T, S: Service<Body>, B: Payload, E> Unpin for Server<T, S, B, E> {}
|
impl<T, S: HttpService<Body>, B: Payload, E> Unpin for Server<T, S, B, E> {}
|
||||||
|
|
||||||
enum State<T, B>
|
enum State<T, B>
|
||||||
where
|
where
|
||||||
@@ -51,7 +51,7 @@ where
|
|||||||
impl<T, S, B, E> Server<T, S, B, E>
|
impl<T, S, B, E> Server<T, S, B, E>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite + Unpin,
|
T: AsyncRead + AsyncWrite + Unpin,
|
||||||
S: Service<Body, ResBody=B>,
|
S: HttpService<Body, ResBody=B>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
B::Data: Unpin,
|
B::Data: Unpin,
|
||||||
@@ -89,7 +89,7 @@ where
|
|||||||
impl<T, S, B, E> Future for Server<T, S, B, E>
|
impl<T, S, B, E> Future for Server<T, S, B, E>
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite + Unpin,
|
T: AsyncRead + AsyncWrite + Unpin,
|
||||||
S: Service<Body, ResBody=B>,
|
S: HttpService<Body, ResBody=B>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
B::Data: Unpin,
|
B::Data: Unpin,
|
||||||
@@ -131,7 +131,7 @@ where
|
|||||||
{
|
{
|
||||||
fn poll_server<S, E>(&mut self, cx: &mut task::Context<'_>, service: &mut S, exec: &mut E) -> Poll<crate::Result<()>>
|
fn poll_server<S, E>(&mut self, cx: &mut task::Context<'_>, service: &mut S, exec: &mut E) -> Poll<crate::Result<()>>
|
||||||
where
|
where
|
||||||
S: Service<
|
S: HttpService<
|
||||||
Body,
|
Body,
|
||||||
ResBody=B,
|
ResBody=B,
|
||||||
>,
|
>,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use crate::common::io::Rewind;
|
|||||||
use crate::common::{Future, Pin, Poll, Unpin, task};
|
use crate::common::{Future, Pin, Poll, Unpin, task};
|
||||||
use crate::error::{Kind, Parse};
|
use crate::error::{Kind, Parse};
|
||||||
use crate::proto;
|
use crate::proto;
|
||||||
use crate::service::{MakeServiceRef, Service};
|
use crate::service::{MakeServiceRef, HttpService};
|
||||||
use crate::upgrade::Upgraded;
|
use crate::upgrade::Upgraded;
|
||||||
use super::Accept;
|
use super::Accept;
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ pub(super) struct SpawnAll<I, S, E> {
|
|||||||
#[pin_project]
|
#[pin_project]
|
||||||
pub struct Connection<T, S, E = Exec>
|
pub struct Connection<T, S, E = Exec>
|
||||||
where
|
where
|
||||||
S: Service<Body>,
|
S: HttpService<Body>,
|
||||||
{
|
{
|
||||||
pub(super) conn: Option<Either<
|
pub(super) conn: Option<Either<
|
||||||
proto::h1::Dispatcher<
|
proto::h1::Dispatcher<
|
||||||
@@ -362,8 +362,9 @@ impl<E> Http<E> {
|
|||||||
/// # async fn run<I, S>(some_io: I, some_service: S)
|
/// # async fn run<I, S>(some_io: I, some_service: S)
|
||||||
/// # where
|
/// # where
|
||||||
/// # I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
/// # I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||||
/// # S: Service<Body, ResBody=Body> + Send + 'static,
|
/// # S: Service<hyper::Request<Body>, Response=hyper::Response<Body>> + Send + 'static,
|
||||||
/// # S::Future: Send
|
/// # S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
|
||||||
|
/// # S::Future: Send,
|
||||||
/// # {
|
/// # {
|
||||||
/// let http = Http::new();
|
/// let http = Http::new();
|
||||||
/// let conn = http.serve_connection(some_io, some_service);
|
/// let conn = http.serve_connection(some_io, some_service);
|
||||||
@@ -376,7 +377,7 @@ impl<E> Http<E> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn serve_connection<S, I, Bd>(&self, io: I, service: S) -> Connection<I, S, E>
|
pub fn serve_connection<S, I, Bd>(&self, io: I, service: S) -> Connection<I, S, E>
|
||||||
where
|
where
|
||||||
S: Service<Body, ResBody=Bd>,
|
S: HttpService<Body, ResBody=Bd>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
Bd: Payload,
|
Bd: Payload,
|
||||||
Bd::Data: Unpin,
|
Bd::Data: Unpin,
|
||||||
@@ -431,8 +432,9 @@ impl<E> Http<E> {
|
|||||||
ResBody=Bd,
|
ResBody=Bd,
|
||||||
>,
|
>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
|
S::Service: HttpService<Body>,
|
||||||
Bd: Payload,
|
Bd: Payload,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, Bd>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, Bd>,
|
||||||
{
|
{
|
||||||
let mut incoming = AddrIncoming::new(addr, None)?;
|
let mut incoming = AddrIncoming::new(addr, None)?;
|
||||||
if self.keep_alive {
|
if self.keep_alive {
|
||||||
@@ -454,7 +456,7 @@ impl<E> Http<E> {
|
|||||||
>,
|
>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
Bd: Payload,
|
Bd: Payload,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, Bd>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, Bd>,
|
||||||
{
|
{
|
||||||
let mut incoming = AddrIncoming::new(addr, Some(handle))?;
|
let mut incoming = AddrIncoming::new(addr, Some(handle))?;
|
||||||
if self.keep_alive {
|
if self.keep_alive {
|
||||||
@@ -477,7 +479,7 @@ impl<E> Http<E> {
|
|||||||
>,
|
>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
Bd: Payload,
|
Bd: Payload,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, Bd>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, Bd>,
|
||||||
{
|
{
|
||||||
Serve {
|
Serve {
|
||||||
incoming,
|
incoming,
|
||||||
@@ -498,7 +500,7 @@ impl<E> Http<E> {
|
|||||||
>,
|
>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
Bd: Payload,
|
Bd: Payload,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, Bd>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, Bd>,
|
||||||
{
|
{
|
||||||
Serve {
|
Serve {
|
||||||
incoming,
|
incoming,
|
||||||
@@ -513,7 +515,7 @@ impl<E> Http<E> {
|
|||||||
|
|
||||||
impl<I, B, S, E> Connection<I, S, E>
|
impl<I, B, S, E> Connection<I, S, E>
|
||||||
where
|
where
|
||||||
S: Service<Body, ResBody=B>,
|
S: HttpService<Body, ResBody=B>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
I: AsyncRead + AsyncWrite + Unpin,
|
I: AsyncRead + AsyncWrite + Unpin,
|
||||||
B: Payload + 'static,
|
B: Payload + 'static,
|
||||||
@@ -662,7 +664,7 @@ where
|
|||||||
|
|
||||||
impl<I, B, S, E> Future for Connection<I, S, E>
|
impl<I, B, S, E> Future for Connection<I, S, E>
|
||||||
where
|
where
|
||||||
S: Service<Body, ResBody=B>,
|
S: HttpService<Body, ResBody=B>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
I: AsyncRead + AsyncWrite + Unpin + 'static,
|
I: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
B: Payload + 'static,
|
B: Payload + 'static,
|
||||||
@@ -700,7 +702,7 @@ where
|
|||||||
|
|
||||||
impl<I, S> fmt::Debug for Connection<I, S>
|
impl<I, S> fmt::Debug for Connection<I, S>
|
||||||
where
|
where
|
||||||
S: Service<Body>,
|
S: HttpService<Body>,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Connection")
|
f.debug_struct("Connection")
|
||||||
@@ -740,7 +742,7 @@ where
|
|||||||
IE: Into<Box<dyn StdError + Send + Sync>>,
|
IE: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
S: MakeServiceRef<IO, Body, ResBody=B>,
|
S: MakeServiceRef<IO, Body, ResBody=B>,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, B>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, B>,
|
||||||
{
|
{
|
||||||
fn poll_next_(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<crate::Result<Connecting<IO, S::Future, E>>>> {
|
fn poll_next_(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<crate::Result<Connecting<IO, S::Future, E>>>> {
|
||||||
let me = self.project();
|
let me = self.project();
|
||||||
@@ -774,7 +776,7 @@ where
|
|||||||
IE: Into<Box<dyn StdError + Send + Sync>>,
|
IE: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
S: MakeServiceRef<IO, Body, ResBody=B>,
|
S: MakeServiceRef<IO, Body, ResBody=B>,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, B>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, B>,
|
||||||
{
|
{
|
||||||
type Item = crate::Result<Connecting<IO, S::Future, E>>;
|
type Item = crate::Result<Connecting<IO, S::Future, E>>;
|
||||||
|
|
||||||
@@ -790,7 +792,7 @@ impl<I, F, S, FE, E, B> Future for Connecting<I, F, E>
|
|||||||
where
|
where
|
||||||
I: AsyncRead + AsyncWrite + Unpin,
|
I: AsyncRead + AsyncWrite + Unpin,
|
||||||
F: Future<Output=Result<S, FE>>,
|
F: Future<Output=Result<S, FE>>,
|
||||||
S: Service<Body, ResBody=B>,
|
S: HttpService<Body, ResBody=B>,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
B::Data: Unpin,
|
B::Data: Unpin,
|
||||||
E: H2Exec<S::Future, B>,
|
E: H2Exec<S::Future, B>,
|
||||||
@@ -831,7 +833,7 @@ where
|
|||||||
ResBody=B,
|
ResBody=B,
|
||||||
>,
|
>,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, B>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, B>,
|
||||||
{
|
{
|
||||||
pub(super) fn poll_watch<W>(self: Pin<&mut Self>, cx: &mut task::Context<'_>, watcher: &W) -> Poll<crate::Result<()>>
|
pub(super) fn poll_watch<W>(self: Pin<&mut Self>, cx: &mut task::Context<'_>, watcher: &W) -> Poll<crate::Result<()>>
|
||||||
where
|
where
|
||||||
@@ -875,7 +877,7 @@ pub(crate) mod spawn_all {
|
|||||||
use crate::body::{Body, Payload};
|
use crate::body::{Body, Payload};
|
||||||
use crate::common::exec::H2Exec;
|
use crate::common::exec::H2Exec;
|
||||||
use crate::common::{Future, Pin, Poll, Unpin, task};
|
use crate::common::{Future, Pin, Poll, Unpin, task};
|
||||||
use crate::service::Service;
|
use crate::service::HttpService;
|
||||||
use super::{Connecting, UpgradeableConnection};
|
use super::{Connecting, UpgradeableConnection};
|
||||||
use pin_project::{pin_project, project};
|
use pin_project::{pin_project, project};
|
||||||
|
|
||||||
@@ -887,7 +889,7 @@ pub(crate) mod spawn_all {
|
|||||||
// The `Server::with_graceful_shutdown` needs to keep track of all active
|
// The `Server::with_graceful_shutdown` needs to keep track of all active
|
||||||
// connections, and signal that they start to shutdown when prompted, so
|
// connections, and signal that they start to shutdown when prompted, so
|
||||||
// it has a `GracefulWatcher` implementation to do that.
|
// it has a `GracefulWatcher` implementation to do that.
|
||||||
pub trait Watcher<I, S: Service<Body>, E>: Clone {
|
pub trait Watcher<I, S: HttpService<Body>, E>: Clone {
|
||||||
type Future: Future<Output = crate::Result<()>>;
|
type Future: Future<Output = crate::Result<()>>;
|
||||||
|
|
||||||
fn watch(&self, conn: UpgradeableConnection<I, S, E>) -> Self::Future;
|
fn watch(&self, conn: UpgradeableConnection<I, S, E>) -> Self::Future;
|
||||||
@@ -900,7 +902,7 @@ pub(crate) mod spawn_all {
|
|||||||
impl<I, S, E> Watcher<I, S, E> for NoopWatcher
|
impl<I, S, E> Watcher<I, S, E> for NoopWatcher
|
||||||
where
|
where
|
||||||
I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||||
S: Service<Body> + 'static,
|
S: HttpService<Body> + 'static,
|
||||||
<S::ResBody as Payload>::Data: Unpin,
|
<S::ResBody as Payload>::Data: Unpin,
|
||||||
E: H2Exec<S::Future, S::ResBody>,
|
E: H2Exec<S::Future, S::ResBody>,
|
||||||
{
|
{
|
||||||
@@ -923,18 +925,18 @@ pub(crate) mod spawn_all {
|
|||||||
|
|
||||||
#[pin_project]
|
#[pin_project]
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct NewSvcTask<I, N, S: Service<Body>, E, W: Watcher<I, S, E>> {
|
pub struct NewSvcTask<I, N, S: HttpService<Body>, E, W: Watcher<I, S, E>> {
|
||||||
#[pin]
|
#[pin]
|
||||||
state: State<I, N, S, E, W>,
|
state: State<I, N, S, E, W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project]
|
#[pin_project]
|
||||||
pub enum State<I, N, S: Service<Body>, E, W: Watcher<I, S, E>> {
|
pub enum State<I, N, S: HttpService<Body>, E, W: Watcher<I, S, E>> {
|
||||||
Connecting(#[pin] Connecting<I, N, E>, W),
|
Connecting(#[pin] Connecting<I, N, E>, W),
|
||||||
Connected(#[pin] W::Future),
|
Connected(#[pin] W::Future),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, N, S: Service<Body>, E, W: Watcher<I, S, E>> NewSvcTask<I, N, S, E, W> {
|
impl<I, N, S: HttpService<Body>, E, W: Watcher<I, S, E>> NewSvcTask<I, N, S, E, W> {
|
||||||
pub(super) fn new(connecting: Connecting<I, N, E>, watcher: W) -> Self {
|
pub(super) fn new(connecting: Connecting<I, N, E>, watcher: W) -> Self {
|
||||||
NewSvcTask {
|
NewSvcTask {
|
||||||
state: State::Connecting(connecting, watcher),
|
state: State::Connecting(connecting, watcher),
|
||||||
@@ -947,7 +949,7 @@ pub(crate) mod spawn_all {
|
|||||||
I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||||
N: Future<Output=Result<S, NE>>,
|
N: Future<Output=Result<S, NE>>,
|
||||||
NE: Into<Box<dyn StdError + Send + Sync>>,
|
NE: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
S: Service<Body, ResBody=B>,
|
S: HttpService<Body, ResBody=B>,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
B::Data: Unpin,
|
B::Data: Unpin,
|
||||||
E: H2Exec<S::Future, B>,
|
E: H2Exec<S::Future, B>,
|
||||||
@@ -1008,14 +1010,14 @@ mod upgrades {
|
|||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct UpgradeableConnection<T, S, E>
|
pub struct UpgradeableConnection<T, S, E>
|
||||||
where
|
where
|
||||||
S: Service<Body>,
|
S: HttpService<Body>,
|
||||||
{
|
{
|
||||||
pub(super) inner: Connection<T, S, E>,
|
pub(super) inner: Connection<T, S, E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, B, S, E> UpgradeableConnection<I, S, E>
|
impl<I, B, S, E> UpgradeableConnection<I, S, E>
|
||||||
where
|
where
|
||||||
S: Service<Body, ResBody=B>,// + 'static,
|
S: HttpService<Body, ResBody=B>,// + 'static,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
I: AsyncRead + AsyncWrite + Unpin,
|
I: AsyncRead + AsyncWrite + Unpin,
|
||||||
B: Payload + 'static,
|
B: Payload + 'static,
|
||||||
@@ -1033,7 +1035,7 @@ mod upgrades {
|
|||||||
|
|
||||||
impl<I, B, S, E> Future for UpgradeableConnection<I, S, E>
|
impl<I, B, S, E> Future for UpgradeableConnection<I, S, E>
|
||||||
where
|
where
|
||||||
S: Service<Body, ResBody=B> + 'static,
|
S: HttpService<Body, ResBody=B> + 'static,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||||
B: Payload + 'static,
|
B: Payload + 'static,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ use pin_project::pin_project;
|
|||||||
use crate::body::{Body, Payload};
|
use crate::body::{Body, Payload};
|
||||||
use crate::common::exec::{Exec, H2Exec, NewSvcExec};
|
use crate::common::exec::{Exec, H2Exec, NewSvcExec};
|
||||||
use crate::common::{Future, Pin, Poll, Unpin, task};
|
use crate::common::{Future, Pin, Poll, Unpin, task};
|
||||||
use crate::service::{MakeServiceRef, Service};
|
use crate::service::{MakeServiceRef, HttpService};
|
||||||
use self::accept::Accept;
|
use self::accept::Accept;
|
||||||
// Renamed `Http` as `Http_` for now so that people upgrading don't see an
|
// Renamed `Http` as `Http_` for now so that people upgrading don't see an
|
||||||
// error that `hyper::server::Http` is private...
|
// error that `hyper::server::Http` is private...
|
||||||
@@ -152,7 +152,7 @@ where
|
|||||||
S::Service: 'static,
|
S::Service: 'static,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
B::Data: Unpin,
|
B::Data: Unpin,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, B>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, B>,
|
||||||
E: NewSvcExec<IO, S::Future, S::Service, E, GracefulWatcher>,
|
E: NewSvcExec<IO, S::Future, S::Service, E, GracefulWatcher>,
|
||||||
{
|
{
|
||||||
/// Prepares a server to handle graceful shutdown when the provided future
|
/// Prepares a server to handle graceful shutdown when the provided future
|
||||||
@@ -209,7 +209,7 @@ where
|
|||||||
S::Service: 'static,
|
S::Service: 'static,
|
||||||
B: Payload,
|
B: Payload,
|
||||||
B::Data: Unpin,
|
B::Data: Unpin,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, B>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, B>,
|
||||||
E: NewSvcExec<IO, S::Future, S::Service, E, NoopWatcher>,
|
E: NewSvcExec<IO, S::Future, S::Service, E, NoopWatcher>,
|
||||||
{
|
{
|
||||||
type Output = crate::Result<()>;
|
type Output = crate::Result<()>;
|
||||||
@@ -396,7 +396,7 @@ impl<I, E> Builder<I, E> {
|
|||||||
B: Payload,
|
B: Payload,
|
||||||
B::Data: Unpin,
|
B::Data: Unpin,
|
||||||
E: NewSvcExec<I::Conn, S::Future, S::Service, E, NoopWatcher>,
|
E: NewSvcExec<I::Conn, S::Future, S::Service, E, NoopWatcher>,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, B>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, B>,
|
||||||
{
|
{
|
||||||
let serve = self.protocol.serve(self.incoming, new_service);
|
let serve = self.protocol.serve(self.incoming, new_service);
|
||||||
let spawn_all = serve.spawn_all();
|
let spawn_all = serve.spawn_all();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::body::{Body, Payload};
|
|||||||
use crate::common::drain::{self, Draining, Signal, Watch, Watching};
|
use crate::common::drain::{self, Draining, Signal, Watch, Watching};
|
||||||
use crate::common::exec::{H2Exec, NewSvcExec};
|
use crate::common::exec::{H2Exec, NewSvcExec};
|
||||||
use crate::common::{Future, Pin, Poll, Unpin, task};
|
use crate::common::{Future, Pin, Poll, Unpin, task};
|
||||||
use crate::service::{MakeServiceRef, Service};
|
use crate::service::{MakeServiceRef, HttpService};
|
||||||
use super::Accept;
|
use super::Accept;
|
||||||
use super::conn::{SpawnAll, UpgradeableConnection, Watcher};
|
use super::conn::{SpawnAll, UpgradeableConnection, Watcher};
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ where
|
|||||||
B: Payload,
|
B: Payload,
|
||||||
B::Data: Unpin,
|
B::Data: Unpin,
|
||||||
F: Future<Output=()>,
|
F: Future<Output=()>,
|
||||||
E: H2Exec<<S::Service as Service<Body>>::Future, B>,
|
E: H2Exec<<S::Service as HttpService<Body>>::Future, B>,
|
||||||
E: NewSvcExec<IO, S::Future, S::Service, E, GracefulWatcher>,
|
E: NewSvcExec<IO, S::Future, S::Service, E, GracefulWatcher>,
|
||||||
{
|
{
|
||||||
type Output = crate::Result<()>;
|
type Output = crate::Result<()>;
|
||||||
@@ -106,7 +106,7 @@ pub struct GracefulWatcher(Watch);
|
|||||||
impl<I, S, E> Watcher<I, S, E> for GracefulWatcher
|
impl<I, S, E> Watcher<I, S, E> for GracefulWatcher
|
||||||
where
|
where
|
||||||
I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
I: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||||
S: Service<Body> + 'static,
|
S: HttpService<Body> + 'static,
|
||||||
<S::ResBody as Payload>::Data: Unpin,
|
<S::ResBody as Payload>::Data: Unpin,
|
||||||
E: H2Exec<S::Future, S::ResBody>,
|
E: H2Exec<S::Future, S::ResBody>,
|
||||||
{
|
{
|
||||||
@@ -122,7 +122,7 @@ where
|
|||||||
|
|
||||||
fn on_drain<I, S, E>(conn: Pin<&mut UpgradeableConnection<I, S, E>>)
|
fn on_drain<I, S, E>(conn: Pin<&mut UpgradeableConnection<I, S, E>>)
|
||||||
where
|
where
|
||||||
S: Service<Body>,
|
S: HttpService<Body>,
|
||||||
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
S::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
I: AsyncRead + AsyncWrite + Unpin,
|
I: AsyncRead + AsyncWrite + Unpin,
|
||||||
S::ResBody: Payload + 'static,
|
S::ResBody: Payload + 'static,
|
||||||
|
|||||||
58
src/service/http.rs
Normal file
58
src/service/http.rs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
use std::error::Error as StdError;
|
||||||
|
|
||||||
|
use crate::body::Payload;
|
||||||
|
use crate::common::{Future, Poll, task};
|
||||||
|
use crate::{Request, Response};
|
||||||
|
|
||||||
|
/// An asynchronous function from `Request` to `Response`.
|
||||||
|
pub trait HttpService<ReqBody>: sealed::Sealed<ReqBody> {
|
||||||
|
/// The `Payload` body of the `http::Response`.
|
||||||
|
type ResBody: Payload;
|
||||||
|
|
||||||
|
/// 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 poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn call(&mut self, req: Request<ReqBody>) -> Self::Future;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, B1, B2> HttpService<B1> for T
|
||||||
|
where
|
||||||
|
T: tower_service::Service<Request<B1>, Response = Response<B2>>,
|
||||||
|
B2: Payload,
|
||||||
|
T::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
|
{
|
||||||
|
type ResBody = B2;
|
||||||
|
|
||||||
|
type Error = T::Error;
|
||||||
|
type Future = T::Future;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
tower_service::Service::poll_ready(self, cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Request<B1>) -> Self::Future {
|
||||||
|
tower_service::Service::call(self, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, B1, B2> sealed::Sealed<B1> for T
|
||||||
|
where
|
||||||
|
T: tower_service::Service<Request<B1>, Response = Response<B2>>,
|
||||||
|
B2: Payload,
|
||||||
|
{}
|
||||||
|
|
||||||
|
mod sealed {
|
||||||
|
pub trait Sealed<T> {}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,81 +1,50 @@
|
|||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
|
|
||||||
use crate::body::Payload;
|
use crate::body::Payload;
|
||||||
use crate::common::{Future, Poll, task};
|
use crate::common::{Future, Poll, task};
|
||||||
use super::Service;
|
use super::{HttpService, Service};
|
||||||
|
|
||||||
/// An asynchronous constructor of `Service`s.
|
// The same "trait alias" as tower::MakeConnection, but inlined to reduce
|
||||||
pub trait MakeService<Target, ReqBody>: sealed::Sealed<Target, ReqBody> {
|
// dependencies.
|
||||||
/// The `Payload` body of the `http::Response`.
|
pub trait MakeConnection<Target>: self::sealed::Sealed<(Target,)> {
|
||||||
type ResBody: Payload;
|
type Connection: AsyncRead + AsyncWrite;
|
||||||
|
type Error;
|
||||||
|
type Future: Future<Output = Result<Self::Connection, Self::Error>>;
|
||||||
|
|
||||||
/// The error type that can be returned by `Service`s.
|
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
|
||||||
type Error: Into<Box<dyn StdError + Send + Sync>>;
|
|
||||||
|
|
||||||
/// The resolved `Service` from `make_service()`.
|
fn make_connection(&mut self, target: Target) -> Self::Future;
|
||||||
type Service: Service<
|
|
||||||
ReqBody,
|
|
||||||
ResBody=Self::ResBody,
|
|
||||||
Error=Self::Error,
|
|
||||||
>;
|
|
||||||
|
|
||||||
/// The future returned from `new_service` of a `Service`.
|
|
||||||
type Future: Future<Output=Result<Self::Service, Self::MakeError>>;
|
|
||||||
|
|
||||||
/// The error type that can be returned when creating a new `Service`.
|
|
||||||
type MakeError: Into<Box<dyn StdError + Send + Sync>>;
|
|
||||||
|
|
||||||
/// Returns `Ready` when the constructor is ready to create a new `Service`.
|
|
||||||
///
|
|
||||||
/// The implementation of this method is allowed to return a `Ready` even if
|
|
||||||
/// the factory is not ready to create a new service. In this case, the future
|
|
||||||
/// returned from `make_service` will resolve to an error.
|
|
||||||
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>>;
|
|
||||||
|
|
||||||
/// Create a new `Service`.
|
|
||||||
fn make_service(&mut self, target: Target) -> Self::Future;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Target, S, B1, B2, E, F> MakeService<Target, B1> for T
|
impl<S, Target> self::sealed::Sealed<(Target,)> for S where S: Service<Target> {}
|
||||||
|
|
||||||
|
impl<S, Target> MakeConnection<Target> for S
|
||||||
where
|
where
|
||||||
T: for<'a> tower_service::Service<&'a Target, Response = S, Error = E, Future = F>,
|
S: Service<Target>,
|
||||||
S: tower_service::Service<crate::Request<B1>, Response = crate::Response<B2>>,
|
S::Response: AsyncRead + AsyncWrite,
|
||||||
E: Into<Box<dyn std::error::Error + Send + Sync>>,
|
|
||||||
S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
|
|
||||||
B1: Payload,
|
|
||||||
B2: Payload,
|
|
||||||
F: Future<Output = Result<S, E>>,
|
|
||||||
{
|
{
|
||||||
type ResBody = B2;
|
type Connection = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Service = S;
|
type Future = S::Future;
|
||||||
type Future = F;
|
|
||||||
type MakeError = E;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>> {
|
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
tower_service::Service::poll_ready(self, cx)
|
Service::poll_ready(self, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_service(&mut self, req: Target) -> Self::Future {
|
fn make_connection(&mut self, target: Target) -> Self::Future {
|
||||||
tower_service::Service::call(self, &req)
|
Service::call(self, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Target, S, B1, B2> sealed::Sealed<Target, B1> for T
|
|
||||||
where
|
|
||||||
T: for<'a> tower_service::Service<&'a Target, Response = S>,
|
|
||||||
S: tower_service::Service<crate::Request<B1>, Response = crate::Response<B2>>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just a sort-of "trait alias" of `MakeService`, not to be implemented
|
// Just a sort-of "trait alias" of `MakeService`, not to be implemented
|
||||||
// by anyone, only used as bounds.
|
// by anyone, only used as bounds.
|
||||||
#[doc(hidden)]
|
pub trait MakeServiceRef<Target, ReqBody>: self::sealed::Sealed<(Target, ReqBody)> {
|
||||||
pub trait MakeServiceRef<Target, ReqBody>: self::sealed::Sealed<Target, ReqBody> {
|
|
||||||
type ResBody: Payload;
|
type ResBody: Payload;
|
||||||
type Error: Into<Box<dyn StdError + Send + Sync>>;
|
type Error: Into<Box<dyn StdError + Send + Sync>>;
|
||||||
type Service: Service<
|
type Service: HttpService<
|
||||||
ReqBody,
|
ReqBody,
|
||||||
ResBody=Self::ResBody,
|
ResBody=Self::ResBody,
|
||||||
Error=Self::Error,
|
Error=Self::Error,
|
||||||
@@ -101,10 +70,10 @@ pub trait MakeServiceRef<Target, ReqBody>: self::sealed::Sealed<Target, ReqBody>
|
|||||||
|
|
||||||
impl<T, Target, E, ME, S, F, IB, OB> MakeServiceRef<Target, IB> for T
|
impl<T, Target, E, ME, S, F, IB, OB> MakeServiceRef<Target, IB> for T
|
||||||
where
|
where
|
||||||
T: for<'a> tower_service::Service<&'a Target, Error=ME, Response=S, Future=F>,
|
T: for<'a> Service<&'a Target, Error=ME, Response=S, Future=F>,
|
||||||
E: Into<Box<dyn StdError + Send + Sync>>,
|
E: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
ME: Into<Box<dyn StdError + Send + Sync>>,
|
ME: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
S: tower_service::Service<crate::Request<IB>, Response=crate::Response<OB>, Error=E>,
|
S: HttpService<IB, ResBody=OB, Error=E>,
|
||||||
F: Future<Output=Result<S, ME>>,
|
F: Future<Output=Result<S, ME>>,
|
||||||
IB: Payload,
|
IB: Payload,
|
||||||
OB: Payload,
|
OB: Payload,
|
||||||
@@ -126,17 +95,24 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, Target, S, B1, B2> self::sealed::Sealed<(Target, B1)> for T
|
||||||
|
where
|
||||||
|
T: for<'a> Service<&'a Target, Response = S>,
|
||||||
|
S: HttpService<B1, ResBody = B2>,
|
||||||
|
B1: Payload,
|
||||||
|
B2: Payload,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a `MakeService` from a function.
|
/// Create a `MakeService` from a function.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust,no_run
|
/// ```
|
||||||
/// # #[cfg(feature = "runtime")]
|
/// # #[cfg(feature = "runtime")]
|
||||||
/// # #[tokio::main]
|
/// # async fn run() {
|
||||||
/// # async fn main() {
|
/// use std::convert::Infallible;
|
||||||
/// use std::net::TcpStream;
|
/// use hyper::{Body, Request, Response, Server};
|
||||||
/// use hyper::{Body, Error, Request, Response, Server};
|
|
||||||
/// use hyper::rt::{self, Future};
|
|
||||||
/// use hyper::server::conn::AddrStream;
|
/// use hyper::server::conn::AddrStream;
|
||||||
/// use hyper::service::{make_service_fn, service_fn};
|
/// use hyper::service::{make_service_fn, service_fn};
|
||||||
///
|
///
|
||||||
@@ -145,8 +121,8 @@ where
|
|||||||
/// let make_svc = make_service_fn(|socket: &AddrStream| {
|
/// let make_svc = make_service_fn(|socket: &AddrStream| {
|
||||||
/// let remote_addr = socket.remote_addr();
|
/// let remote_addr = socket.remote_addr();
|
||||||
/// async move {
|
/// async move {
|
||||||
/// Ok::<_, Error>(service_fn(move |_: Request<Body>| async move {
|
/// Ok::<_, Infallible>(service_fn(move |_: Request<Body>| async move {
|
||||||
/// Ok::<_, Error>(
|
/// Ok::<_, Infallible>(
|
||||||
/// Response::new(Body::from(format!("Hello, {}!", remote_addr)))
|
/// Response::new(Body::from(format!("Hello, {}!", remote_addr)))
|
||||||
/// )
|
/// )
|
||||||
/// }))
|
/// }))
|
||||||
@@ -162,7 +138,7 @@ where
|
|||||||
/// eprintln!("server error: {}", e);
|
/// eprintln!("server error: {}", e);
|
||||||
/// }
|
/// }
|
||||||
/// # }
|
/// # }
|
||||||
/// # #[cfg(not(feature = "runtime"))] fn main() {}
|
/// # fn main() {}
|
||||||
/// ```
|
/// ```
|
||||||
pub fn make_service_fn<F, Target, Ret>(f: F) -> MakeServiceFn<F>
|
pub fn make_service_fn<F, Target, Ret>(f: F) -> MakeServiceFn<F>
|
||||||
where
|
where
|
||||||
@@ -179,7 +155,7 @@ pub struct MakeServiceFn<F> {
|
|||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t, F, Ret, Target, Svc, MkErr> tower_service::Service<&'t Target> for MakeServiceFn<F>
|
impl<'t, F, Ret, Target, Svc, MkErr> Service<&'t Target> for MakeServiceFn<F>
|
||||||
where
|
where
|
||||||
F: FnMut(&Target) -> Ret,
|
F: FnMut(&Target) -> Ret,
|
||||||
Ret: Future<Output=Result<Svc, MkErr>>,
|
Ret: Future<Output=Result<Svc, MkErr>>,
|
||||||
@@ -206,7 +182,7 @@ impl<F> fmt::Debug for MakeServiceFn<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod sealed {
|
mod sealed {
|
||||||
pub trait Sealed<T, B> {}
|
pub trait Sealed<X> {}
|
||||||
|
|
||||||
pub trait CantImpl {}
|
pub trait CantImpl {}
|
||||||
|
|
||||||
@@ -1,15 +1,21 @@
|
|||||||
//! Services and MakeServices
|
//! Asynchronous Services
|
||||||
//!
|
//!
|
||||||
//! - A [`Service`](service::Service) is a trait representing an asynchronous
|
//! A [`Service`](service::Service) is a trait representing an asynchronous
|
||||||
//! function of a request to a response. It's similar to
|
//! function of a request to a response. It's similar to
|
||||||
//! `async fn(Request) -> Result<Response, Error>`.
|
//! `async fn(Request) -> Result<Response, Error>`.
|
||||||
//! - A [`MakeService`](service::MakeService) is a trait creating specific
|
|
||||||
//! instances of a `Service`.
|
|
||||||
//!
|
//!
|
||||||
//! These types are conceptually similar to those in
|
//! The argument and return value isn't strictly required to be for HTTP.
|
||||||
//! [tower](https://crates.io/crates/tower), while being specific to hyper.
|
//! Therefore, hyper uses several "trait aliases" to reduce clutter around
|
||||||
|
//! bounds. These are:
|
||||||
//!
|
//!
|
||||||
//! # Service
|
//! - `HttpService`: This is blanketly implemented for all types that
|
||||||
|
//! implement `Service<http::Request<B1>, Response = http::Response<B2>>`.
|
||||||
|
//! - `MakeService`: When a `Service` returns a new `Service` as its "response",
|
||||||
|
//! we consider it a `MakeService`. Again, blanketly implemented in those cases.
|
||||||
|
//! - `MakeConnection`: A `Service` that returns a "connection", a type that
|
||||||
|
//! implements `AsyncRead` and `AsyncWrite`.
|
||||||
|
//!
|
||||||
|
//! # HttpService
|
||||||
//!
|
//!
|
||||||
//! In hyper, especially in the server setting, a `Service` is usually bound
|
//! 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
|
//! to a single connection. It defines how to respond to **all** requests that
|
||||||
@@ -25,11 +31,17 @@
|
|||||||
//! `MakeService` does.
|
//! `MakeService` does.
|
||||||
//!
|
//!
|
||||||
//! Resources that need to be shared by all `Service`s can be put into a
|
//! Resources that need to be shared by all `Service`s can be put into a
|
||||||
//! `MakeService`, and then passed to individual `Service`s when `make_service`
|
//! `MakeService`, and then passed to individual `Service`s when `call`
|
||||||
//! is called.
|
//! is called.
|
||||||
|
|
||||||
mod make_service;
|
pub use tower_service::Service;
|
||||||
mod service;
|
|
||||||
|
|
||||||
pub use self::make_service::{make_service_fn, MakeService, MakeServiceRef};
|
mod http;
|
||||||
pub use self::service::{service_fn, Service};
|
mod make;
|
||||||
|
mod util;
|
||||||
|
|
||||||
|
pub(crate) use self::make::{MakeConnection, MakeServiceRef};
|
||||||
|
pub(crate) use self::http::HttpService;
|
||||||
|
|
||||||
|
pub use self::make::make_service_fn;
|
||||||
|
pub use self::util::service_fn;
|
||||||
|
|||||||
@@ -1,127 +0,0 @@
|
|||||||
use std::error::Error as StdError;
|
|
||||||
use std::fmt;
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use crate::body::Payload;
|
|
||||||
use crate::common::{Future, Poll, task};
|
|
||||||
use crate::{Request, Response};
|
|
||||||
|
|
||||||
/// An asynchronous function from `Request` to `Response`.
|
|
||||||
pub trait Service<ReqBody>: sealed::Sealed<ReqBody> {
|
|
||||||
/// The `Payload` body of the `http::Response`.
|
|
||||||
type ResBody: Payload;
|
|
||||||
|
|
||||||
/// 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>>;
|
|
||||||
|
|
||||||
/// Returns `Ready` when the service is able to process requests.
|
|
||||||
///
|
|
||||||
/// The implementation of this method is allowed to return a `Ready` even if
|
|
||||||
/// the service is not ready to process. In this case, the future returned
|
|
||||||
/// from `call` will resolve to an error.
|
|
||||||
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
|
|
||||||
|
|
||||||
/// Calls this `Service` with a request, returning a `Future` of the response.
|
|
||||||
fn call(&mut self, req: Request<ReqBody>) -> Self::Future;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, B1, B2> Service<B1> for T
|
|
||||||
where
|
|
||||||
T: tower_service::Service<Request<B1>, Response = Response<B2>>,
|
|
||||||
B2: Payload,
|
|
||||||
T::Error: Into<Box<dyn StdError + Send + Sync>>,
|
|
||||||
{
|
|
||||||
type ResBody = B2;
|
|
||||||
|
|
||||||
type Error = T::Error;
|
|
||||||
type Future = T::Future;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
tower_service::Service::poll_ready(self, cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self, req: Request<B1>) -> Self::Future {
|
|
||||||
tower_service::Service::call(self, req)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, B1, B2> sealed::Sealed<B1> for T
|
|
||||||
where
|
|
||||||
T: tower_service::Service<Request<B1>, Response = Response<B2>>,
|
|
||||||
B2: Payload,
|
|
||||||
{}
|
|
||||||
|
|
||||||
mod sealed {
|
|
||||||
pub trait Sealed<T> {}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Create a `Service` from a function.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use hyper::{Body, Request, Response, Version};
|
|
||||||
/// use hyper::service::service_fn;
|
|
||||||
///
|
|
||||||
/// let service = service_fn(|req: Request<Body>| async move{
|
|
||||||
/// if req.version() == Version::HTTP_11 {
|
|
||||||
/// Ok(Response::new(Body::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: FnMut(Request<R>) -> S,
|
|
||||||
S: Future,
|
|
||||||
{
|
|
||||||
ServiceFn {
|
|
||||||
f,
|
|
||||||
_req: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not exported from crate as this will likely be replaced with `impl Service`.
|
|
||||||
pub struct ServiceFn<F, R> {
|
|
||||||
f: F,
|
|
||||||
_req: PhantomData<fn(R)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, ReqBody, Ret, ResBody, E> tower_service::Service<crate::Request<ReqBody>> for ServiceFn<F, ReqBody>
|
|
||||||
where
|
|
||||||
F: FnMut(Request<ReqBody>) -> Ret,
|
|
||||||
ReqBody: Payload,
|
|
||||||
Ret: Future<Output=Result<Response<ResBody>, E>>,
|
|
||||||
E: Into<Box<dyn StdError + Send + Sync>>,
|
|
||||||
ResBody: Payload,
|
|
||||||
{
|
|
||||||
type Response = crate::Response<ResBody>;
|
|
||||||
type Error = E;
|
|
||||||
type Future = Ret;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
Poll::Ready(Ok(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
70
src/service/util.rs
Normal file
70
src/service/util.rs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
use std::error::Error as StdError;
|
||||||
|
use std::fmt;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use crate::body::Payload;
|
||||||
|
use crate::common::{Future, Poll, task};
|
||||||
|
use crate::{Request, Response};
|
||||||
|
|
||||||
|
/// Create a `Service` from a function.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use hyper::{Body, Request, Response, Version};
|
||||||
|
/// use hyper::service::service_fn;
|
||||||
|
///
|
||||||
|
/// let service = service_fn(|req: Request<Body>| async move {
|
||||||
|
/// if req.version() == Version::HTTP_11 {
|
||||||
|
/// Ok(Response::new(Body::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: FnMut(Request<R>) -> S,
|
||||||
|
S: Future,
|
||||||
|
{
|
||||||
|
ServiceFn {
|
||||||
|
f,
|
||||||
|
_req: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not exported from crate as this will likely be replaced with `impl Service`.
|
||||||
|
pub struct ServiceFn<F, R> {
|
||||||
|
f: F,
|
||||||
|
_req: PhantomData<fn(R)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, ReqBody, Ret, ResBody, E> tower_service::Service<crate::Request<ReqBody>> for ServiceFn<F, ReqBody>
|
||||||
|
where
|
||||||
|
F: FnMut(Request<ReqBody>) -> Ret,
|
||||||
|
ReqBody: Payload,
|
||||||
|
Ret: Future<Output=Result<Response<ResBody>, E>>,
|
||||||
|
E: Into<Box<dyn StdError + Send + Sync>>,
|
||||||
|
ResBody: Payload,
|
||||||
|
{
|
||||||
|
type Response = crate::Response<ResBody>;
|
||||||
|
type Error = E;
|
||||||
|
type Future = Ret;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user