#![allow(dead_code, unused_must_use, unused_variables, unused_imports)]
use mio;
use std::fmt;
use std::net::SocketAddr;
pub mod buffer;
pub mod buffer_queue;
#[macro_use] pub mod metrics;
pub mod socket;
pub mod trie;
pub mod protocol;
pub mod http;
pub mod tls;
#[cfg(feature = "splice")]
mod splice;
pub mod tcp;
pub mod proxy;
pub mod session;
use mio::Token;
use messages::Order;
pub type MessageId = String;
#[derive(Debug)]
pub enum Protocol {
HTTP,
TLS,
TCP
}
#[derive(Debug,Clone,PartialEq,Eq,Hash, Serialize, Deserialize)]
pub struct ServerMessage {
pub id: MessageId,
pub status: ServerMessageStatus,
}
impl fmt::Display for ServerMessage {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}-{:?}", self.id, self.status)
}
}
#[derive(Debug,Clone,PartialEq,Eq,Hash, Serialize, Deserialize)]
pub enum ServerMessageStatus {
Ok,
Processing,
Error(String),
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct ProxyOrder {
pub id: MessageId,
pub order: Order,
}
impl fmt::Display for ProxyOrder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}-{:?}", self.id, self.order)
}
}
#[derive(Debug,PartialEq,Eq)]
pub enum RequiredEvents {
FrontReadBackNone,
FrontWriteBackNone,
FrontReadWriteBackNone,
FrontNoneBackNone,
FrontReadBackRead,
FrontWriteBackRead,
FrontReadWriteBackRead,
FrontNoneBackRead,
FrontReadBackWrite,
FrontWriteBackWrite,
FrontReadWriteBackWrite,
FrontNoneBackWrite,
FrontReadBackReadWrite,
FrontWriteBackReadWrite,
FrontReadWriteBackReadWrite,
FrontNoneBackReadWrite,
}
impl RequiredEvents {
pub fn front_readable(&self) -> bool {
match *self {
RequiredEvents::FrontReadBackNone
| RequiredEvents:: FrontReadWriteBackNone
| RequiredEvents:: FrontReadBackRead
| RequiredEvents:: FrontReadWriteBackRead
| RequiredEvents:: FrontReadBackWrite
| RequiredEvents:: FrontReadWriteBackWrite
| RequiredEvents:: FrontReadBackReadWrite
| RequiredEvents:: FrontReadWriteBackReadWrite => true,
_ => false
}
}
pub fn front_writable(&self) -> bool {
match *self {
RequiredEvents::FrontWriteBackNone
| RequiredEvents::FrontReadWriteBackNone
| RequiredEvents::FrontWriteBackRead
| RequiredEvents::FrontReadWriteBackRead
| RequiredEvents::FrontWriteBackWrite
| RequiredEvents::FrontReadWriteBackWrite
| RequiredEvents::FrontWriteBackReadWrite
| RequiredEvents::FrontReadWriteBackReadWrite => true,
_ => false
}
}
pub fn back_readable(&self) -> bool {
match *self {
RequiredEvents::FrontReadBackRead
| RequiredEvents::FrontWriteBackRead
| RequiredEvents::FrontReadWriteBackRead
| RequiredEvents::FrontNoneBackRead
| RequiredEvents::FrontReadBackReadWrite
| RequiredEvents::FrontWriteBackReadWrite
| RequiredEvents::FrontReadWriteBackReadWrite
| RequiredEvents::FrontNoneBackReadWrite => true,
_ => false
}
}
pub fn back_writable(&self) -> bool {
match *self {
RequiredEvents::FrontReadBackWrite
| RequiredEvents::FrontWriteBackWrite
| RequiredEvents::FrontReadWriteBackWrite
| RequiredEvents::FrontNoneBackWrite
| RequiredEvents::FrontReadBackReadWrite
| RequiredEvents::FrontWriteBackReadWrite
| RequiredEvents::FrontReadWriteBackReadWrite
| RequiredEvents::FrontNoneBackReadWrite => true,
_ => false
}
}
}
#[derive(Debug,PartialEq,Eq)]
pub enum ClientResult {
CloseClient,
CloseBackend,
CloseBothSuccess,
CloseBothFailure,
Continue,
ConnectBackend
}
#[derive(Debug,PartialEq,Eq)]
pub enum ConnectionError {
NoHostGiven,
NoRequestLineGiven,
HostNotFound,
NoBackendAvailable,
ToBeDefined
}
#[derive(Debug,PartialEq,Eq)]
pub enum SocketType {
Listener,
FrontClient,
BackClient,
}
#[derive(Debug,PartialEq,Eq)]
pub enum BackendStatus {
Normal,
Closing,
Closed,
}
#[derive(Debug,PartialEq,Eq)]
pub struct Backend {
pub address: SocketAddr,
pub status: BackendStatus,
pub active_connections: usize,
pub failures: usize,
}
impl Backend {
pub fn new(addr: SocketAddr) -> Backend {
Backend {
address: addr,
status: BackendStatus::Normal,
active_connections: 0,
failures: 0,
}
}
pub fn set_closing(&mut self) {
self.status = BackendStatus::Closing;
}
pub fn can_open(&self, max_failures: usize) -> bool {
self.status == BackendStatus::Normal && self.failures < max_failures
}
pub fn inc_connections(&mut self) -> Option<usize> {
if self.status == BackendStatus::Normal {
self.active_connections += 1;
Some(self.active_connections)
} else {
None
}
}
pub fn dec_connections(&mut self) -> Option<usize> {
if self.active_connections == 0 {
self.status = BackendStatus::Closed;
return None;
}
match self.status {
BackendStatus::Normal => {
self.active_connections -= 1;
Some(self.active_connections)
}
BackendStatus::Closed => None,
BackendStatus::Closing => {
self.active_connections -= 1;
if self.active_connections == 0 {
self.status = BackendStatus::Closed;
None
} else {
Some(self.active_connections)
}
},
}
}
pub fn try_connect(&mut self, max_failures: usize) -> Result<mio::tcp::TcpStream, ConnectionError> {
if self.failures >= max_failures || self.status == BackendStatus::Closing || self.status == BackendStatus::Closed {
return Err(ConnectionError::NoBackendAvailable);
}
let conn = mio::tcp::TcpStream::connect(&self.address).map_err(|_| ConnectionError::NoBackendAvailable);
if conn.is_ok() {
self.inc_connections();
} else {
self.failures += 1;
}
conn
}
}