use std::time::Duration;
use bytes::Bytes;
use http::{HeaderMap, Method, Version};
use super::PeerSpec;
#[derive(Clone, Debug)]
pub struct RequestHead {
pub headers: HeaderMap,
pub method: Method,
pub target: String,
}
#[derive(Clone, Copy, Debug)]
pub struct ResponseHead<'response> {
pub headers: &'response HeaderMap,
pub status: u16,
pub version: Version,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Completion {
Finished,
Incomplete,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum EgressError {
#[error("invalid request: {0}")]
InvalidRequest(String),
#[error("connect failed: {0}")]
Connect(String),
#[error("exchange failed: {0}")]
Io(String),
#[error("no network backend is compiled into this build")]
Unavailable,
}
pub trait Connector: Clone + Send + Sync + 'static {
type Session: Session;
fn new(keepalive_pool_size: usize) -> Self;
fn connect(
&self,
peer: &PeerSpec,
timeout: Duration,
) -> impl Future<Output = Result<Self::Session, EgressError>> + Send;
fn release(&self, session: Self::Session, keepalive: bool) -> impl Future<Output = ()> + Send;
}
pub trait Session: Send + 'static {
fn reused(&self) -> bool;
fn send_request_head(&mut self, head: RequestHead) -> impl Future<Output = Result<(), EgressError>> + Send;
fn send_request_body(
&mut self,
chunk: Bytes,
end_of_stream: bool,
) -> impl Future<Output = Result<(), EgressError>> + Send;
fn finish_request(&mut self) -> impl Future<Output = Result<(), EgressError>> + Send;
fn read_response_head(&mut self) -> impl Future<Output = Result<(), EgressError>> + Send;
fn response_head(&self) -> Result<ResponseHead<'_>, EgressError>;
fn response_done(&mut self) -> bool;
fn read_response_body(&mut self) -> impl Future<Output = Result<Option<Bytes>, EgressError>> + Send;
fn completion(&mut self) -> Result<Completion, EgressError>;
fn clear_read_timeout(&mut self);
fn shutdown(&mut self) -> impl Future<Output = ()> + Send;
}