feat(server): change NewService to MakeService with connection context

This adjusts the way `Service`s are created for a `hyper::Server`. The
`MakeService` trait allows receiving an argument when creating a
`Service`. The implementation for `hyper::Server` expects to pass a
reference to the accepted transport (so, `&Incoming::Item`). The user
can inspect the transport before making a `Service`.

In practice, this allows for things like getting the remote socket
address, or the TLS certification, or similar.

To prevent a breaking change, there is a blanket implementation of
`MakeService` for any `NewService`. Besides implementing `MakeService`
directly, there is also added `hyper::service::make_service_fn`.

Closes #1650
This commit is contained in:
Sean McArthur
2018-11-01 13:21:09 -07:00
parent 1158bd20b3
commit 30870029b9
8 changed files with 219 additions and 58 deletions

View File

@@ -3,7 +3,7 @@ use std::error::Error as StdError;
use futures::{Future, IntoFuture};
use body::Payload;
use super::Service;
use super::{MakeService, Service};
/// An asynchronous constructor of `Service`s.
pub trait NewService {
@@ -47,9 +47,24 @@ where
type Future = R::Future;
type InitError = R::Error;
fn new_service(&self) -> Self::Future {
(*self)().into_future()
}
}
impl<N, Ctx> MakeService<Ctx> for N
where
N: NewService,
{
type ReqBody = N::ReqBody;
type ResBody = N::ResBody;
type Error = N::Error;
type Service = N::Service;
type Future = N::Future;
type MakeError = N::InitError;
fn make_service(&mut self, _: Ctx) -> Self::Future {
self.new_service()
}
}