1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-25 08:52:42 +01:00
actix-web/src/client/connection.rs

133 lines
3.2 KiB
Rust
Raw Normal View History

2019-01-29 05:41:09 +01:00
use std::{fmt, time};
2018-11-12 08:12:54 +01:00
2018-12-11 03:08:33 +01:00
use actix_codec::{AsyncRead, AsyncWrite};
2019-01-29 05:41:09 +01:00
use bytes::Bytes;
use futures::Future;
use h2::client::SendRequest;
2018-11-12 08:12:54 +01:00
2019-01-29 05:41:09 +01:00
use crate::body::MessageBody;
use crate::message::RequestHead;
use super::error::SendRequestError;
2018-11-12 08:12:54 +01:00
use super::pool::Acquired;
2019-01-29 05:41:09 +01:00
use super::response::ClientResponse;
use super::{h1proto, h2proto};
pub(crate) enum ConnectionType<Io> {
H1(Io),
H2(SendRequest<Bytes>),
}
2019-01-29 19:34:27 +01:00
pub trait Connection {
2019-01-29 05:41:09 +01:00
type Future: Future<Item = ClientResponse, Error = SendRequestError>;
2019-03-26 05:52:45 +01:00
/// Send request and body
2019-01-29 05:41:09 +01:00
fn send_request<B: MessageBody + 'static>(
self,
head: RequestHead,
body: B,
) -> Self::Future;
}
2018-11-12 08:12:54 +01:00
2019-01-29 05:41:09 +01:00
pub(crate) trait ConnectionLifetime: AsyncRead + AsyncWrite + 'static {
2018-11-15 20:10:23 +01:00
/// Close connection
fn close(&mut self);
/// Release connection to the connection pool
fn release(&mut self);
}
#[doc(hidden)]
2018-11-12 08:12:54 +01:00
/// HTTP client connection
2018-11-15 20:10:23 +01:00
pub struct IoConnection<T> {
2019-01-29 05:41:09 +01:00
io: Option<ConnectionType<T>>,
2018-11-12 08:12:54 +01:00
created: time::Instant,
pool: Option<Acquired<T>>,
}
2018-11-15 20:10:23 +01:00
impl<T> fmt::Debug for IoConnection<T>
2018-11-12 08:12:54 +01:00
where
2018-11-14 07:53:30 +01:00
T: fmt::Debug,
2018-11-12 08:12:54 +01:00
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2019-01-29 05:41:09 +01:00
match self.io {
Some(ConnectionType::H1(ref io)) => write!(f, "H1Connection({:?})", io),
Some(ConnectionType::H2(_)) => write!(f, "H2Connection"),
None => write!(f, "Connection(Empty)"),
}
2018-11-12 08:12:54 +01:00
}
}
2018-11-15 20:10:23 +01:00
impl<T: AsyncRead + AsyncWrite + 'static> IoConnection<T> {
2019-01-29 05:41:09 +01:00
pub(crate) fn new(
io: ConnectionType<T>,
created: time::Instant,
pool: Option<Acquired<T>>,
) -> Self {
2018-11-15 20:10:23 +01:00
IoConnection {
2019-01-29 05:41:09 +01:00
pool,
2018-11-12 08:12:54 +01:00
created,
2018-11-15 20:10:23 +01:00
io: Some(io),
2018-11-12 08:12:54 +01:00
}
}
2019-01-29 05:41:09 +01:00
pub(crate) fn into_inner(self) -> (ConnectionType<T>, time::Instant) {
2018-11-15 20:10:23 +01:00
(self.io.unwrap(), self.created)
}
}
2019-01-29 19:34:27 +01:00
impl<T> Connection for IoConnection<T>
2019-01-29 05:41:09 +01:00
where
T: AsyncRead + AsyncWrite + 'static,
{
type Future = Box<Future<Item = ClientResponse, Error = SendRequestError>>;
fn send_request<B: MessageBody + 'static>(
mut self,
head: RequestHead,
body: B,
) -> Self::Future {
match self.io.take().unwrap() {
ConnectionType::H1(io) => Box::new(h1proto::send_request(
io,
head,
body,
self.created,
self.pool,
)),
ConnectionType::H2(io) => Box::new(h2proto::send_request(
io,
head,
body,
self.created,
self.pool,
)),
2018-11-12 08:12:54 +01:00
}
}
}
2019-01-29 05:41:09 +01:00
#[allow(dead_code)]
pub(crate) enum EitherConnection<A, B> {
A(IoConnection<A>),
B(IoConnection<B>),
2018-11-12 08:12:54 +01:00
}
2019-01-29 19:34:27 +01:00
impl<A, B> Connection for EitherConnection<A, B>
2019-01-29 05:41:09 +01:00
where
A: AsyncRead + AsyncWrite + 'static,
B: AsyncRead + AsyncWrite + 'static,
{
type Future = Box<Future<Item = ClientResponse, Error = SendRequestError>>;
fn send_request<RB: MessageBody + 'static>(
self,
head: RequestHead,
body: RB,
) -> Self::Future {
match self {
EitherConnection::A(con) => con.send_request(head, body),
EitherConnection::B(con) => con.send_request(head, body),
}
2018-11-12 08:12:54 +01:00
}
}