feat(client): remove hyper::client::server (#2940)
BREAKING CHANGE: Tower `Service` utilities will exist in `hyper-util`.
This commit is contained in:
@@ -181,11 +181,6 @@ name = "state"
|
|||||||
path = "examples/state.rs"
|
path = "examples/state.rs"
|
||||||
required-features = ["full"]
|
required-features = ["full"]
|
||||||
|
|
||||||
[[example]]
|
|
||||||
name = "tower_client"
|
|
||||||
path = "examples/tower_client.rs"
|
|
||||||
required-features = ["full"]
|
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "tower_server"
|
name = "tower_server"
|
||||||
path = "examples/tower_server.rs"
|
path = "examples/tower_server.rs"
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
#![deny(warnings)]
|
|
||||||
|
|
||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
|
||||||
use std::task::{Context, Poll};
|
|
||||||
|
|
||||||
use hyper::service::Service;
|
|
||||||
use hyper::{Body, Request, Response};
|
|
||||||
use tokio::net::TcpStream;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
|
|
||||||
pretty_env_logger::init();
|
|
||||||
|
|
||||||
let uri = "http://127.0.0.1:8080".parse::<http::Uri>()?;
|
|
||||||
|
|
||||||
let mut svc = Connector;
|
|
||||||
|
|
||||||
let body = Body::empty();
|
|
||||||
|
|
||||||
let req = Request::get(uri).body(body)?;
|
|
||||||
let res = svc.call(req).await?;
|
|
||||||
|
|
||||||
println!("RESPONSE={:?}", res);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Connector;
|
|
||||||
|
|
||||||
impl Service<Request<Body>> for Connector {
|
|
||||||
type Response = Response<Body>;
|
|
||||||
type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
|
|
||||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> std::task::Poll<Result<(), Self::Error>> {
|
|
||||||
Poll::Ready(Ok(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self, req: Request<Body>) -> Self::Future {
|
|
||||||
Box::pin(async move {
|
|
||||||
let host = req.uri().host().expect("no host in uri");
|
|
||||||
let port = req.uri().port_u16().expect("no port in uri");
|
|
||||||
|
|
||||||
let stream = TcpStream::connect(format!("{}:{}", host, port)).await?;
|
|
||||||
|
|
||||||
let (mut sender, conn) = hyper::client::conn::handshake(stream).await?;
|
|
||||||
|
|
||||||
tokio::task::spawn(async move {
|
|
||||||
if let Err(err) = conn.await {
|
|
||||||
println!("Connection error: {:?}", err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let res = sender.send_request(req).await?;
|
|
||||||
Ok(res)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -40,5 +40,4 @@ cfg_feature! {
|
|||||||
pub mod conn;
|
pub mod conn;
|
||||||
pub(super) mod dispatch;
|
pub(super) mod dispatch;
|
||||||
mod pool;
|
mod pool;
|
||||||
pub mod service;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
//! Utilities used to interact with the Tower ecosystem.
|
|
||||||
//!
|
|
||||||
//! This module provides `Connect` which hook-ins into the Tower ecosystem.
|
|
||||||
|
|
||||||
use std::error::Error as StdError;
|
|
||||||
use std::future::Future;
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use tracing::debug;
|
|
||||||
|
|
||||||
use super::conn::{Builder, SendRequest};
|
|
||||||
use crate::{
|
|
||||||
body::HttpBody,
|
|
||||||
common::{task, Pin, Poll},
|
|
||||||
service::{MakeConnection, Service},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Creates a connection via `SendRequest`.
|
|
||||||
///
|
|
||||||
/// This accepts a `hyper::client::conn::Builder` and provides
|
|
||||||
/// a `MakeService` implementation to create connections from some
|
|
||||||
/// target `T`.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Connect<C, B, T> {
|
|
||||||
inner: C,
|
|
||||||
builder: Builder,
|
|
||||||
_pd: PhantomData<fn(T, B)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, B, T> Connect<C, B, T> {
|
|
||||||
/// Create a new `Connect` with some inner connector `C` and a connection
|
|
||||||
/// builder.
|
|
||||||
pub fn new(inner: C, builder: Builder) -> Self {
|
|
||||||
Self {
|
|
||||||
inner,
|
|
||||||
builder,
|
|
||||||
_pd: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, B, T> Service<T> for Connect<C, B, T>
|
|
||||||
where
|
|
||||||
C: MakeConnection<T>,
|
|
||||||
C::Connection: Unpin + Send + 'static,
|
|
||||||
C::Future: Send + 'static,
|
|
||||||
C::Error: Into<Box<dyn StdError + Send + Sync>> + Send,
|
|
||||||
B: HttpBody + Unpin + Send + 'static,
|
|
||||||
B::Data: Send + Unpin,
|
|
||||||
B::Error: Into<Box<dyn StdError + Send + Sync>>,
|
|
||||||
{
|
|
||||||
type Response = SendRequest<B>;
|
|
||||||
type Error = crate::Error;
|
|
||||||
type Future =
|
|
||||||
Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
self.inner
|
|
||||||
.poll_ready(cx)
|
|
||||||
.map_err(|e| crate::Error::new(crate::error::Kind::Connect).with(e.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self, req: T) -> Self::Future {
|
|
||||||
let builder = self.builder.clone();
|
|
||||||
let io = self.inner.make_connection(req);
|
|
||||||
|
|
||||||
let fut = async move {
|
|
||||||
match io.await {
|
|
||||||
Ok(io) => match builder.handshake(io).await {
|
|
||||||
Ok((sr, conn)) => {
|
|
||||||
builder.exec.execute(async move {
|
|
||||||
if let Err(e) = conn.await {
|
|
||||||
debug!("connection error: {:?}", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Ok(sr)
|
|
||||||
}
|
|
||||||
Err(e) => Err(e),
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
let err = crate::Error::new(crate::error::Kind::Connect).with(e.into());
|
|
||||||
Err(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Box::pin(fut)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
use tokio::io::{AsyncRead, AsyncWrite};
|
|
||||||
|
|
||||||
use super::Service;
|
|
||||||
use crate::common::{task, Future, Poll};
|
|
||||||
|
|
||||||
// The same "trait alias" as tower::MakeConnection, but inlined to reduce
|
|
||||||
// dependencies.
|
|
||||||
pub trait MakeConnection<Target>: self::sealed::Sealed<(Target,)> {
|
|
||||||
type Connection: AsyncRead + AsyncWrite;
|
|
||||||
type Error;
|
|
||||||
type Future: Future<Output = Result<Self::Connection, Self::Error>>;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
|
|
||||||
fn make_connection(&mut self, target: Target) -> Self::Future;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, Target> self::sealed::Sealed<(Target,)> for S where S: Service<Target> {}
|
|
||||||
|
|
||||||
impl<S, Target> MakeConnection<Target> for S
|
|
||||||
where
|
|
||||||
S: Service<Target>,
|
|
||||||
S::Response: AsyncRead + AsyncWrite,
|
|
||||||
{
|
|
||||||
type Connection = S::Response;
|
|
||||||
type Error = S::Error;
|
|
||||||
type Future = S::Future;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
Service::poll_ready(self, cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_connection(&mut self, target: Target) -> Self::Future {
|
|
||||||
Service::call(self, target)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod sealed {
|
|
||||||
pub trait Sealed<X> {}
|
|
||||||
}
|
|
||||||
@@ -10,8 +10,6 @@
|
|||||||
//!
|
//!
|
||||||
//! - `HttpService`: This is blanketly implemented for all types that
|
//! - `HttpService`: This is blanketly implemented for all types that
|
||||||
//! implement `Service<http::Request<B1>, Response = http::Response<B2>>`.
|
//! implement `Service<http::Request<B1>, Response = http::Response<B2>>`.
|
||||||
//! - `MakeConnection`: A `Service` that returns a "connection", a type that
|
|
||||||
//! implements `AsyncRead` and `AsyncWrite`.
|
|
||||||
//!
|
//!
|
||||||
//! # HttpService
|
//! # HttpService
|
||||||
//!
|
//!
|
||||||
@@ -26,7 +24,6 @@
|
|||||||
pub use tower_service::Service;
|
pub use tower_service::Service;
|
||||||
|
|
||||||
mod http;
|
mod http;
|
||||||
mod make;
|
|
||||||
#[cfg(all(any(feature = "http1", feature = "http2"), feature = "client"))]
|
#[cfg(all(any(feature = "http1", feature = "http2"), feature = "client"))]
|
||||||
mod oneshot;
|
mod oneshot;
|
||||||
mod util;
|
mod util;
|
||||||
@@ -34,8 +31,6 @@ mod util;
|
|||||||
#[cfg(all(any(feature = "http1", feature = "http2"), feature = "server"))]
|
#[cfg(all(any(feature = "http1", feature = "http2"), feature = "server"))]
|
||||||
pub(super) use self::http::HttpService;
|
pub(super) use self::http::HttpService;
|
||||||
#[cfg(all(any(feature = "http1", feature = "http2"), feature = "client"))]
|
#[cfg(all(any(feature = "http1", feature = "http2"), feature = "client"))]
|
||||||
pub(super) use self::make::MakeConnection;
|
|
||||||
#[cfg(all(any(feature = "http1", feature = "http2"), feature = "client"))]
|
|
||||||
pub(super) use self::oneshot::{oneshot, Oneshot};
|
pub(super) use self::oneshot::{oneshot, Oneshot};
|
||||||
|
|
||||||
pub use self::util::service_fn;
|
pub use self::util::service_fn;
|
||||||
|
|||||||
Reference in New Issue
Block a user