mirror of
https://github.com/fafhrd91/actix-web
synced 2024-11-24 16:32:59 +01:00
define generic client Connection trait
This commit is contained in:
parent
acd42f92d8
commit
6d9733cdf7
@ -5,14 +5,23 @@ use tokio_io::{AsyncRead, AsyncWrite};
|
|||||||
|
|
||||||
use super::pool::Acquired;
|
use super::pool::Acquired;
|
||||||
|
|
||||||
|
pub trait Connection: AsyncRead + AsyncWrite + 'static {
|
||||||
|
/// Close connection
|
||||||
|
fn close(&mut self);
|
||||||
|
|
||||||
|
/// Release connection to the connection pool
|
||||||
|
fn release(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
/// HTTP client connection
|
/// HTTP client connection
|
||||||
pub struct Connection<T> {
|
pub struct IoConnection<T> {
|
||||||
io: T,
|
io: Option<T>,
|
||||||
created: time::Instant,
|
created: time::Instant,
|
||||||
pool: Option<Acquired<T>>,
|
pool: Option<Acquired<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> fmt::Debug for Connection<T>
|
impl<T> fmt::Debug for IoConnection<T>
|
||||||
where
|
where
|
||||||
T: fmt::Debug,
|
T: fmt::Debug,
|
||||||
{
|
{
|
||||||
@ -21,59 +30,73 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsyncRead + AsyncWrite + 'static> Connection<T> {
|
impl<T: AsyncRead + AsyncWrite + 'static> IoConnection<T> {
|
||||||
pub(crate) fn new(io: T, created: time::Instant, pool: Acquired<T>) -> Self {
|
pub(crate) fn new(io: T, created: time::Instant, pool: Acquired<T>) -> Self {
|
||||||
Connection {
|
IoConnection {
|
||||||
io,
|
|
||||||
created,
|
created,
|
||||||
|
io: Some(io),
|
||||||
pool: Some(pool),
|
pool: Some(pool),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Raw IO stream
|
/// Raw IO stream
|
||||||
pub fn get_mut(&mut self) -> &mut T {
|
pub fn get_mut(&mut self) -> &mut T {
|
||||||
&mut self.io
|
self.io.as_mut().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn into_inner(self) -> (T, time::Instant) {
|
||||||
|
(self.io.unwrap(), self.created)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsyncRead + AsyncWrite + 'static> Connection for IoConnection<T> {
|
||||||
/// Close connection
|
/// Close connection
|
||||||
pub fn close(mut self) {
|
fn close(&mut self) {
|
||||||
if let Some(mut pool) = self.pool.take() {
|
if let Some(mut pool) = self.pool.take() {
|
||||||
pool.close(self)
|
if let Some(io) = self.io.take() {
|
||||||
|
pool.close(IoConnection {
|
||||||
|
io: Some(io),
|
||||||
|
created: self.created,
|
||||||
|
pool: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Release this connection to the connection pool
|
/// Release this connection to the connection pool
|
||||||
pub fn release(mut self) {
|
fn release(&mut self) {
|
||||||
if let Some(mut pool) = self.pool.take() {
|
if let Some(mut pool) = self.pool.take() {
|
||||||
pool.release(self)
|
if let Some(io) = self.io.take() {
|
||||||
|
pool.release(IoConnection {
|
||||||
|
io: Some(io),
|
||||||
|
created: self.created,
|
||||||
|
pool: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn into_inner(self) -> (T, time::Instant) {
|
impl<T: AsyncRead + AsyncWrite + 'static> io::Read for IoConnection<T> {
|
||||||
(self.io, self.created)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsyncRead + AsyncWrite + 'static> io::Read for Connection<T> {
|
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.io.read(buf)
|
self.io.as_mut().unwrap().read(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsyncRead + AsyncWrite + 'static> AsyncRead for Connection<T> {}
|
impl<T: AsyncRead + AsyncWrite + 'static> AsyncRead for IoConnection<T> {}
|
||||||
|
|
||||||
impl<T: AsyncRead + AsyncWrite + 'static> io::Write for Connection<T> {
|
impl<T: AsyncRead + AsyncWrite + 'static> io::Write for IoConnection<T> {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.io.write(buf)
|
self.io.as_mut().unwrap().write(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
self.io.flush()
|
self.io.as_mut().unwrap().flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsyncRead + AsyncWrite + 'static> AsyncWrite for Connection<T> {
|
impl<T: AsyncRead + AsyncWrite + 'static> AsyncWrite for IoConnection<T> {
|
||||||
fn shutdown(&mut self) -> Poll<(), io::Error> {
|
fn shutdown(&mut self) -> Poll<(), io::Error> {
|
||||||
self.io.shutdown()
|
self.io.as_mut().unwrap().shutdown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use tokio_io::{AsyncRead, AsyncWrite};
|
|||||||
use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
|
use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
|
||||||
|
|
||||||
use super::connect::Connect;
|
use super::connect::Connect;
|
||||||
use super::connection::Connection;
|
use super::connection::{Connection, IoConnection};
|
||||||
use super::error::ConnectorError;
|
use super::error::ConnectorError;
|
||||||
use super::pool::ConnectionPool;
|
use super::pool::ConnectionPool;
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ impl Connector {
|
|||||||
self,
|
self,
|
||||||
) -> impl Service<
|
) -> impl Service<
|
||||||
Request = Connect,
|
Request = Connect,
|
||||||
Response = Connection<impl AsyncRead + AsyncWrite + fmt::Debug>,
|
Response = impl Connection,
|
||||||
Error = ConnectorError,
|
Error = ConnectorError,
|
||||||
> + Clone {
|
> + Clone {
|
||||||
#[cfg(not(feature = "ssl"))]
|
#[cfg(not(feature = "ssl"))]
|
||||||
@ -234,11 +234,11 @@ mod connect_impl {
|
|||||||
T: Service<Request = Connect, Response = (Connect, Io), Error = ConnectorError>,
|
T: Service<Request = Connect, Response = (Connect, Io), Error = ConnectorError>,
|
||||||
{
|
{
|
||||||
type Request = Connect;
|
type Request = Connect;
|
||||||
type Response = Connection<Io>;
|
type Response = IoConnection<Io>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
type Future = Either<
|
type Future = Either<
|
||||||
<ConnectionPool<T, Io> as Service>::Future,
|
<ConnectionPool<T, Io> as Service>::Future,
|
||||||
FutureResult<Connection<Io>, ConnectorError>,
|
FutureResult<IoConnection<Io>, ConnectorError>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
@ -324,7 +324,7 @@ mod connect_impl {
|
|||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
type Request = Connect;
|
type Request = Connect;
|
||||||
type Response = IoEither<Connection<Io1>, Connection<Io2>>;
|
type Response = IoEither<IoConnection<Io1>, IoConnection<Io2>>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
type Future = Either<
|
type Future = Either<
|
||||||
FutureResult<Self::Response, Self::Error>,
|
FutureResult<Self::Response, Self::Error>,
|
||||||
@ -342,13 +342,13 @@ mod connect_impl {
|
|||||||
if let Err(e) = req.validate() {
|
if let Err(e) = req.validate() {
|
||||||
Either::A(err(e))
|
Either::A(err(e))
|
||||||
} else if req.is_secure() {
|
} else if req.is_secure() {
|
||||||
Either::B(Either::A(InnerConnectorResponseA {
|
Either::B(Either::B(InnerConnectorResponseB {
|
||||||
fut: self.tcp_pool.call(req),
|
fut: self.ssl_pool.call(req),
|
||||||
_t: PhantomData,
|
_t: PhantomData,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Either::B(Either::B(InnerConnectorResponseB {
|
Either::B(Either::A(InnerConnectorResponseA {
|
||||||
fut: self.ssl_pool.call(req),
|
fut: self.tcp_pool.call(req),
|
||||||
_t: PhantomData,
|
_t: PhantomData,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -370,7 +370,7 @@ mod connect_impl {
|
|||||||
Io1: AsyncRead + AsyncWrite + 'static,
|
Io1: AsyncRead + AsyncWrite + 'static,
|
||||||
Io2: AsyncRead + AsyncWrite + 'static,
|
Io2: AsyncRead + AsyncWrite + 'static,
|
||||||
{
|
{
|
||||||
type Item = IoEither<Connection<Io1>, Connection<Io2>>;
|
type Item = IoEither<IoConnection<Io1>, IoConnection<Io2>>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
@ -396,7 +396,7 @@ mod connect_impl {
|
|||||||
Io1: AsyncRead + AsyncWrite + 'static,
|
Io1: AsyncRead + AsyncWrite + 'static,
|
||||||
Io2: AsyncRead + AsyncWrite + 'static,
|
Io2: AsyncRead + AsyncWrite + 'static,
|
||||||
{
|
{
|
||||||
type Item = IoEither<Connection<Io1>, Connection<Io2>>;
|
type Item = IoEither<IoConnection<Io1>, IoConnection<Io2>>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
@ -413,10 +413,30 @@ pub(crate) enum IoEither<Io1, Io2> {
|
|||||||
B(Io2),
|
B(Io2),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Io1, Io2> Connection for IoEither<Io1, Io2>
|
||||||
|
where
|
||||||
|
Io1: Connection,
|
||||||
|
Io2: Connection,
|
||||||
|
{
|
||||||
|
fn close(&mut self) {
|
||||||
|
match self {
|
||||||
|
IoEither::A(ref mut io) => io.close(),
|
||||||
|
IoEither::B(ref mut io) => io.close(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn release(&mut self) {
|
||||||
|
match self {
|
||||||
|
IoEither::A(ref mut io) => io.release(),
|
||||||
|
IoEither::B(ref mut io) => io.release(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<Io1, Io2> io::Read for IoEither<Io1, Io2>
|
impl<Io1, Io2> io::Read for IoEither<Io1, Io2>
|
||||||
where
|
where
|
||||||
Io1: io::Read,
|
Io1: Connection,
|
||||||
Io2: io::Read,
|
Io2: Connection,
|
||||||
{
|
{
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
match self {
|
match self {
|
||||||
@ -428,8 +448,8 @@ where
|
|||||||
|
|
||||||
impl<Io1, Io2> AsyncRead for IoEither<Io1, Io2>
|
impl<Io1, Io2> AsyncRead for IoEither<Io1, Io2>
|
||||||
where
|
where
|
||||||
Io1: AsyncRead,
|
Io1: Connection,
|
||||||
Io2: AsyncRead,
|
Io2: Connection,
|
||||||
{
|
{
|
||||||
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
|
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
|
||||||
match self {
|
match self {
|
||||||
@ -441,8 +461,8 @@ where
|
|||||||
|
|
||||||
impl<Io1, Io2> AsyncWrite for IoEither<Io1, Io2>
|
impl<Io1, Io2> AsyncWrite for IoEither<Io1, Io2>
|
||||||
where
|
where
|
||||||
Io1: AsyncWrite,
|
Io1: Connection,
|
||||||
Io2: AsyncWrite,
|
Io2: Connection,
|
||||||
{
|
{
|
||||||
fn shutdown(&mut self) -> Poll<(), io::Error> {
|
fn shutdown(&mut self) -> Poll<(), io::Error> {
|
||||||
match self {
|
match self {
|
||||||
@ -468,8 +488,8 @@ where
|
|||||||
|
|
||||||
impl<Io1, Io2> io::Write for IoEither<Io1, Io2>
|
impl<Io1, Io2> io::Write for IoEither<Io1, Io2>
|
||||||
where
|
where
|
||||||
Io1: io::Write,
|
Io1: Connection,
|
||||||
Io2: io::Write,
|
Io2: Connection,
|
||||||
{
|
{
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -15,27 +15,32 @@ use body::{BodyType, MessageBody, PayloadStream};
|
|||||||
use error::PayloadError;
|
use error::PayloadError;
|
||||||
use h1;
|
use h1;
|
||||||
|
|
||||||
pub fn send_request<T, Io, B>(
|
pub(crate) fn send_request<T, I, B>(
|
||||||
head: RequestHead,
|
head: RequestHead,
|
||||||
body: B,
|
body: B,
|
||||||
connector: &mut T,
|
connector: &mut T,
|
||||||
) -> impl Future<Item = ClientResponse, Error = SendRequestError>
|
) -> impl Future<Item = ClientResponse, Error = SendRequestError>
|
||||||
where
|
where
|
||||||
T: Service<Request = Connect, Response = Connection<Io>, Error = ConnectorError>,
|
T: Service<Request = Connect, Response = I, Error = ConnectorError>,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
Io: AsyncRead + AsyncWrite + 'static,
|
I: Connection,
|
||||||
{
|
{
|
||||||
let tp = body.tp();
|
let tp = body.tp();
|
||||||
|
|
||||||
connector
|
connector
|
||||||
|
// connect to the host
|
||||||
.call(Connect::new(head.uri.clone()))
|
.call(Connect::new(head.uri.clone()))
|
||||||
.from_err()
|
.from_err()
|
||||||
|
// create Framed and send reqest
|
||||||
.map(|io| Framed::new(io, h1::ClientCodec::default()))
|
.map(|io| Framed::new(io, h1::ClientCodec::default()))
|
||||||
.and_then(|framed| framed.send((head, tp).into()).from_err())
|
.and_then(|framed| framed.send((head, tp).into()).from_err())
|
||||||
|
// send request body
|
||||||
.and_then(move |framed| match body.tp() {
|
.and_then(move |framed| match body.tp() {
|
||||||
BodyType::None | BodyType::Zero => Either::A(ok(framed)),
|
BodyType::None | BodyType::Zero => Either::A(ok(framed)),
|
||||||
_ => Either::B(SendBody::new(body, framed)),
|
_ => Either::B(SendBody::new(body, framed)),
|
||||||
}).and_then(|framed| {
|
})
|
||||||
|
// read response and init read body
|
||||||
|
.and_then(|framed| {
|
||||||
framed
|
framed
|
||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|(e, _)| SendRequestError::from(e))
|
.map_err(|(e, _)| SendRequestError::from(e))
|
||||||
@ -55,19 +60,20 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SendBody<Io, B> {
|
/// Future responsible for sending request body to the peer
|
||||||
|
struct SendBody<I, B> {
|
||||||
body: Option<B>,
|
body: Option<B>,
|
||||||
framed: Option<Framed<Connection<Io>, h1::ClientCodec>>,
|
framed: Option<Framed<I, h1::ClientCodec>>,
|
||||||
write_buf: VecDeque<h1::Message<(RequestHead, BodyType)>>,
|
write_buf: VecDeque<h1::Message<(RequestHead, BodyType)>>,
|
||||||
flushed: bool,
|
flushed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Io, B> SendBody<Io, B>
|
impl<I, B> SendBody<I, B>
|
||||||
where
|
where
|
||||||
Io: AsyncRead + AsyncWrite + 'static,
|
I: AsyncRead + AsyncWrite + 'static,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
fn new(body: B, framed: Framed<Connection<Io>, h1::ClientCodec>) -> Self {
|
fn new(body: B, framed: Framed<I, h1::ClientCodec>) -> Self {
|
||||||
SendBody {
|
SendBody {
|
||||||
body: Some(body),
|
body: Some(body),
|
||||||
framed: Some(framed),
|
framed: Some(framed),
|
||||||
@ -77,12 +83,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Io, B> Future for SendBody<Io, B>
|
impl<I, B> Future for SendBody<I, B>
|
||||||
where
|
where
|
||||||
Io: AsyncRead + AsyncWrite + 'static,
|
I: Connection,
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
{
|
{
|
||||||
type Item = Framed<Connection<Io>, h1::ClientCodec>;
|
type Item = Framed<I, h1::ClientCodec>;
|
||||||
type Error = SendRequestError;
|
type Error = SendRequestError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
@ -135,7 +141,7 @@ impl Stream for EmptyPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct Payload<Io> {
|
pub(crate) struct Payload<Io> {
|
||||||
framed: Option<Framed<Connection<Io>, h1::ClientPayloadCodec>>,
|
framed: Option<Framed<Io, h1::ClientPayloadCodec>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Payload<()> {
|
impl Payload<()> {
|
||||||
@ -144,15 +150,15 @@ impl Payload<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Io: AsyncRead + AsyncWrite + 'static> Payload<Io> {
|
impl<Io: Connection> Payload<Io> {
|
||||||
fn stream(framed: Framed<Connection<Io>, h1::ClientCodec>) -> PayloadStream {
|
fn stream(framed: Framed<Io, h1::ClientCodec>) -> PayloadStream {
|
||||||
Box::new(Payload {
|
Box::new(Payload {
|
||||||
framed: Some(framed.map_codec(|codec| codec.into_payload_codec())),
|
framed: Some(framed.map_codec(|codec| codec.into_payload_codec())),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Io: AsyncRead + AsyncWrite + 'static> Stream for Payload<Io> {
|
impl<Io: Connection> Stream for Payload<Io> {
|
||||||
type Item = Bytes;
|
type Item = Bytes;
|
||||||
type Error = PayloadError;
|
type Error = PayloadError;
|
||||||
|
|
||||||
@ -170,11 +176,11 @@ impl<Io: AsyncRead + AsyncWrite + 'static> Stream for Payload<Io> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn release_connection<T, U>(framed: Framed<Connection<T>, U>)
|
fn release_connection<T, U>(framed: Framed<T, U>)
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite + 'static,
|
T: Connection,
|
||||||
{
|
{
|
||||||
let parts = framed.into_parts();
|
let mut parts = framed.into_parts();
|
||||||
if parts.read_buf.is_empty() && parts.write_buf.is_empty() {
|
if parts.read_buf.is_empty() && parts.write_buf.is_empty() {
|
||||||
parts.io.release()
|
parts.io.release()
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,7 +17,7 @@ use tokio_io::{AsyncRead, AsyncWrite};
|
|||||||
use tokio_timer::{sleep, Delay};
|
use tokio_timer::{sleep, Delay};
|
||||||
|
|
||||||
use super::connect::Connect;
|
use super::connect::Connect;
|
||||||
use super::connection::Connection;
|
use super::connection::IoConnection;
|
||||||
use super::error::ConnectorError;
|
use super::error::ConnectorError;
|
||||||
|
|
||||||
#[derive(Hash, Eq, PartialEq, Clone, Debug)]
|
#[derive(Hash, Eq, PartialEq, Clone, Debug)]
|
||||||
@ -89,10 +89,10 @@ where
|
|||||||
T: Service<Request = Connect, Response = (Connect, Io), Error = ConnectorError>,
|
T: Service<Request = Connect, Response = (Connect, Io), Error = ConnectorError>,
|
||||||
{
|
{
|
||||||
type Request = Connect;
|
type Request = Connect;
|
||||||
type Response = Connection<Io>;
|
type Response = IoConnection<Io>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
type Future = Either<
|
type Future = Either<
|
||||||
FutureResult<Connection<Io>, ConnectorError>,
|
FutureResult<IoConnection<Io>, ConnectorError>,
|
||||||
Either<WaitForConnection<Io>, OpenConnection<T::Future, Io>>,
|
Either<WaitForConnection<Io>, OpenConnection<T::Future, Io>>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ where
|
|||||||
match self.1.as_ref().borrow_mut().acquire(&key) {
|
match self.1.as_ref().borrow_mut().acquire(&key) {
|
||||||
Acquire::Acquired(io, created) => {
|
Acquire::Acquired(io, created) => {
|
||||||
// use existing connection
|
// use existing connection
|
||||||
Either::A(ok(Connection::new(
|
Either::A(ok(IoConnection::new(
|
||||||
io,
|
io,
|
||||||
created,
|
created,
|
||||||
Acquired(key, Some(self.1.clone())),
|
Acquired(key, Some(self.1.clone())),
|
||||||
@ -142,7 +142,7 @@ where
|
|||||||
{
|
{
|
||||||
key: Key,
|
key: Key,
|
||||||
token: usize,
|
token: usize,
|
||||||
rx: oneshot::Receiver<Result<Connection<Io>, ConnectorError>>,
|
rx: oneshot::Receiver<Result<IoConnection<Io>, ConnectorError>>,
|
||||||
inner: Option<Rc<RefCell<Inner<Io>>>>,
|
inner: Option<Rc<RefCell<Inner<Io>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ impl<Io> Future for WaitForConnection<Io>
|
|||||||
where
|
where
|
||||||
Io: AsyncRead + AsyncWrite,
|
Io: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type Item = Connection<Io>;
|
type Item = IoConnection<Io>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
@ -226,7 +226,7 @@ where
|
|||||||
F: Future<Item = (Connect, Io), Error = ConnectorError>,
|
F: Future<Item = (Connect, Io), Error = ConnectorError>,
|
||||||
Io: AsyncRead + AsyncWrite,
|
Io: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type Item = Connection<Io>;
|
type Item = IoConnection<Io>;
|
||||||
type Error = ConnectorError;
|
type Error = ConnectorError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
@ -234,7 +234,7 @@ where
|
|||||||
Err(err) => Err(err.into()),
|
Err(err) => Err(err.into()),
|
||||||
Ok(Async::Ready((_, io))) => {
|
Ok(Async::Ready((_, io))) => {
|
||||||
let _ = self.inner.take();
|
let _ = self.inner.take();
|
||||||
Ok(Async::Ready(Connection::new(
|
Ok(Async::Ready(IoConnection::new(
|
||||||
io,
|
io,
|
||||||
Instant::now(),
|
Instant::now(),
|
||||||
Acquired(self.key.clone(), self.inner.clone()),
|
Acquired(self.key.clone(), self.inner.clone()),
|
||||||
@ -251,7 +251,7 @@ where
|
|||||||
{
|
{
|
||||||
fut: F,
|
fut: F,
|
||||||
key: Key,
|
key: Key,
|
||||||
rx: Option<oneshot::Sender<Result<Connection<Io>, ConnectorError>>>,
|
rx: Option<oneshot::Sender<Result<IoConnection<Io>, ConnectorError>>>,
|
||||||
inner: Option<Rc<RefCell<Inner<Io>>>>,
|
inner: Option<Rc<RefCell<Inner<Io>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ where
|
|||||||
{
|
{
|
||||||
fn spawn(
|
fn spawn(
|
||||||
key: Key,
|
key: Key,
|
||||||
rx: oneshot::Sender<Result<Connection<Io>, ConnectorError>>,
|
rx: oneshot::Sender<Result<IoConnection<Io>, ConnectorError>>,
|
||||||
inner: Rc<RefCell<Inner<Io>>>,
|
inner: Rc<RefCell<Inner<Io>>>,
|
||||||
fut: F,
|
fut: F,
|
||||||
) {
|
) {
|
||||||
@ -308,7 +308,7 @@ where
|
|||||||
Ok(Async::Ready((_, io))) => {
|
Ok(Async::Ready((_, io))) => {
|
||||||
let _ = self.inner.take();
|
let _ = self.inner.take();
|
||||||
if let Some(rx) = self.rx.take() {
|
if let Some(rx) = self.rx.take() {
|
||||||
let _ = rx.send(Ok(Connection::new(
|
let _ = rx.send(Ok(IoConnection::new(
|
||||||
io,
|
io,
|
||||||
Instant::now(),
|
Instant::now(),
|
||||||
Acquired(self.key.clone(), self.inner.clone()),
|
Acquired(self.key.clone(), self.inner.clone()),
|
||||||
@ -336,7 +336,7 @@ pub(crate) struct Inner<Io> {
|
|||||||
available: HashMap<Key, VecDeque<AvailableConnection<Io>>>,
|
available: HashMap<Key, VecDeque<AvailableConnection<Io>>>,
|
||||||
waiters: Slab<(
|
waiters: Slab<(
|
||||||
Connect,
|
Connect,
|
||||||
oneshot::Sender<Result<Connection<Io>, ConnectorError>>,
|
oneshot::Sender<Result<IoConnection<Io>, ConnectorError>>,
|
||||||
)>,
|
)>,
|
||||||
waiters_queue: IndexSet<(Key, usize)>,
|
waiters_queue: IndexSet<(Key, usize)>,
|
||||||
task: AtomicTask,
|
task: AtomicTask,
|
||||||
@ -378,7 +378,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
connect: Connect,
|
connect: Connect,
|
||||||
) -> (
|
) -> (
|
||||||
oneshot::Receiver<Result<Connection<Io>, ConnectorError>>,
|
oneshot::Receiver<Result<IoConnection<Io>, ConnectorError>>,
|
||||||
usize,
|
usize,
|
||||||
) {
|
) {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
@ -479,7 +479,7 @@ where
|
|||||||
Acquire::NotAvailable => break,
|
Acquire::NotAvailable => break,
|
||||||
Acquire::Acquired(io, created) => {
|
Acquire::Acquired(io, created) => {
|
||||||
let (_, tx) = inner.waiters.remove(token);
|
let (_, tx) = inner.waiters.remove(token);
|
||||||
if let Err(conn) = tx.send(Ok(Connection::new(
|
if let Err(conn) = tx.send(Ok(IoConnection::new(
|
||||||
io,
|
io,
|
||||||
created,
|
created,
|
||||||
Acquired(key.clone(), Some(self.inner.clone())),
|
Acquired(key.clone(), Some(self.inner.clone())),
|
||||||
@ -546,13 +546,13 @@ impl<T> Acquired<T>
|
|||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite + 'static,
|
T: AsyncRead + AsyncWrite + 'static,
|
||||||
{
|
{
|
||||||
pub(crate) fn close(&mut self, conn: Connection<T>) {
|
pub(crate) fn close(&mut self, conn: IoConnection<T>) {
|
||||||
if let Some(inner) = self.1.take() {
|
if let Some(inner) = self.1.take() {
|
||||||
let (io, _) = conn.into_inner();
|
let (io, _) = conn.into_inner();
|
||||||
inner.as_ref().borrow_mut().release_close(io);
|
inner.as_ref().borrow_mut().release_close(io);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn release(&mut self, conn: Connection<T>) {
|
pub(crate) fn release(&mut self, conn: IoConnection<T>) {
|
||||||
if let Some(inner) = self.1.take() {
|
if let Some(inner) = self.1.take() {
|
||||||
let (io, created) = conn.into_inner();
|
let (io, created) = conn.into_inner();
|
||||||
inner
|
inner
|
||||||
|
@ -7,7 +7,6 @@ use bytes::{BufMut, Bytes, BytesMut};
|
|||||||
use cookie::{Cookie, CookieJar};
|
use cookie::{Cookie, CookieJar};
|
||||||
use futures::{Future, Stream};
|
use futures::{Future, Stream};
|
||||||
use percent_encoding::{percent_encode, USERINFO_ENCODE_SET};
|
use percent_encoding::{percent_encode, USERINFO_ENCODE_SET};
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
|
||||||
use urlcrate::Url;
|
use urlcrate::Url;
|
||||||
|
|
||||||
use body::{MessageBody, MessageBodyStream};
|
use body::{MessageBody, MessageBodyStream};
|
||||||
@ -176,13 +175,13 @@ where
|
|||||||
// Send request
|
// Send request
|
||||||
///
|
///
|
||||||
/// This method returns a future that resolves to a ClientResponse
|
/// This method returns a future that resolves to a ClientResponse
|
||||||
pub fn send<T, Io>(
|
pub fn send<T, I>(
|
||||||
self,
|
self,
|
||||||
connector: &mut T,
|
connector: &mut T,
|
||||||
) -> impl Future<Item = ClientResponse, Error = SendRequestError>
|
) -> impl Future<Item = ClientResponse, Error = SendRequestError>
|
||||||
where
|
where
|
||||||
T: Service<Request = Connect, Response = Connection<Io>, Error = ConnectorError>,
|
T: Service<Request = Connect, Response = I, Error = ConnectorError>,
|
||||||
Io: AsyncRead + AsyncWrite + 'static,
|
I: Connection,
|
||||||
{
|
{
|
||||||
pipeline::send_request(self.head, self.body, connector)
|
pipeline::send_request(self.head, self.body, connector)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user