1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 17:52:40 +01:00
actix-extras/src/server/channel.rs

352 lines
9.2 KiB
Rust
Raw Normal View History

2018-04-14 01:02:01 +02:00
use std::net::{Shutdown, SocketAddr};
2017-12-08 18:24:05 +01:00
use std::rc::Rc;
2018-04-14 01:02:01 +02:00
use std::{io, mem, ptr, time};
2018-04-14 01:02:01 +02:00
use bytes::{Buf, BufMut, Bytes, BytesMut};
use futures::{Async, Future, Poll};
use tokio_io::{AsyncRead, AsyncWrite};
2018-01-12 03:35:05 +01:00
use super::settings::WorkerSettings;
2018-04-29 07:55:47 +02:00
use super::{h1, h2, utils, HttpHandler, IoStream};
const HTTP2_PREFACE: [u8; 14] = *b"PRI * HTTP/2.0";
2018-01-12 03:35:05 +01:00
enum HttpProtocol<T: IoStream, H: 'static> {
H1(h1::Http1<T, H>),
H2(h2::Http2<T, H>),
Unknown(Rc<WorkerSettings<H>>, Option<SocketAddr>, T, BytesMut),
}
2018-01-12 07:06:06 +01:00
enum ProtocolKind {
Http1,
Http2,
}
2017-11-27 07:53:28 +01:00
#[doc(hidden)]
2018-04-14 01:02:01 +02:00
pub struct HttpChannel<T, H>
where
T: IoStream,
H: HttpHandler + 'static,
{
proto: Option<HttpProtocol<T, H>>,
2018-01-04 07:43:44 +01:00
node: Option<Node<HttpChannel<T, H>>>,
}
2018-04-14 01:02:01 +02:00
impl<T, H> HttpChannel<T, H>
where
T: IoStream,
H: HttpHandler + 'static,
{
2018-04-14 01:02:01 +02:00
pub(crate) fn new(
settings: Rc<WorkerSettings<H>>, mut io: T, peer: Option<SocketAddr>,
http2: bool,
) -> HttpChannel<T, H> {
2018-01-12 05:11:34 +01:00
settings.add_channel();
2018-03-05 05:14:58 +01:00
let _ = io.set_nodelay(true);
2018-03-03 20:16:55 +01:00
if http2 {
HttpChannel {
2018-04-14 01:02:01 +02:00
node: None,
proto: Some(HttpProtocol::H2(h2::Http2::new(
settings,
io,
peer,
Bytes::new(),
))),
}
} else {
HttpChannel {
2018-04-14 01:02:01 +02:00
node: None,
proto: Some(HttpProtocol::Unknown(
settings,
peer,
io,
BytesMut::with_capacity(4096),
)),
}
}
}
2018-01-04 07:43:44 +01:00
fn shutdown(&mut self) {
match self.proto {
Some(HttpProtocol::H1(ref mut h1)) => {
let io = h1.io();
let _ = IoStream::set_linger(io, Some(time::Duration::new(0, 0)));
let _ = IoStream::shutdown(io, Shutdown::Both);
2018-01-04 07:43:44 +01:00
}
2018-04-14 01:02:01 +02:00
Some(HttpProtocol::H2(ref mut h2)) => h2.shutdown(),
_ => (),
2018-01-04 07:43:44 +01:00
}
}
}
2018-04-14 01:02:01 +02:00
impl<T, H> Future for HttpChannel<T, H>
where
T: IoStream,
H: HttpHandler + 'static,
{
type Item = ();
type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
2018-04-05 05:15:47 +02:00
if self.node.is_some() {
2018-03-03 20:16:55 +01:00
let el = self as *mut _;
self.node = Some(Node::new(el));
let _ = match self.proto {
2018-04-29 07:55:47 +02:00
Some(HttpProtocol::H1(ref mut h1)) => {
self.node.as_ref().map(|n| h1.settings().head().insert(n))
}
Some(HttpProtocol::H2(ref mut h2)) => {
self.node.as_ref().map(|n| h2.settings().head().insert(n))
}
2018-04-14 01:02:01 +02:00
Some(HttpProtocol::Unknown(ref mut settings, _, _, _)) => {
self.node.as_ref().map(|n| settings.head().insert(n))
}
2018-03-03 20:16:55 +01:00
None => unreachable!(),
};
2018-01-04 07:43:44 +01:00
}
let kind = match self.proto {
Some(HttpProtocol::H1(ref mut h1)) => {
2018-01-12 07:06:06 +01:00
let result = h1.poll();
match result {
Ok(Async::Ready(())) | Err(_) => {
2017-12-29 01:25:47 +01:00
h1.settings().remove_channel();
2018-04-29 07:55:47 +02:00
if let Some(n) = self.node.as_mut() {
n.remove()
};
2018-04-14 01:02:01 +02:00
}
2018-01-12 07:06:06 +01:00
_ => (),
2017-12-29 01:25:47 +01:00
}
2018-04-14 01:02:01 +02:00
return result;
}
2017-12-29 01:25:47 +01:00
Some(HttpProtocol::H2(ref mut h2)) => {
let result = h2.poll();
match result {
2018-01-04 07:43:44 +01:00
Ok(Async::Ready(())) | Err(_) => {
h2.settings().remove_channel();
2018-04-29 07:55:47 +02:00
if let Some(n) = self.node.as_mut() {
n.remove()
};
2018-04-14 01:02:01 +02:00
}
2017-12-29 01:25:47 +01:00
_ => (),
}
2018-04-14 01:02:01 +02:00
return result;
}
Some(HttpProtocol::Unknown(
ref mut settings,
_,
ref mut io,
ref mut buf,
)) => {
match utils::read_from_io(io, buf) {
2018-01-12 08:49:53 +01:00
Ok(Async::Ready(0)) | Err(_) => {
debug!("Ignored premature client disconnection");
2018-01-12 08:49:53 +01:00
settings.remove_channel();
2018-04-29 07:55:47 +02:00
if let Some(n) = self.node.as_mut() {
n.remove()
};
2018-04-14 01:02:01 +02:00
return Err(());
}
_ => (),
}
if buf.len() >= 14 {
if buf[..14] == HTTP2_PREFACE[..] {
ProtocolKind::Http2
} else {
ProtocolKind::Http1
}
} else {
return Ok(Async::NotReady);
}
2018-04-14 01:02:01 +02:00
}
None => unreachable!(),
};
2018-01-12 07:06:06 +01:00
// upgrade to specific http protocol
if let Some(HttpProtocol::Unknown(settings, addr, io, buf)) = self.proto.take() {
match kind {
ProtocolKind::Http1 => {
2018-04-29 07:55:47 +02:00
self.proto =
Some(HttpProtocol::H1(h1::Http1::new(settings, io, addr, buf)));
2018-04-14 01:02:01 +02:00
return self.poll();
}
2018-01-12 07:06:06 +01:00
ProtocolKind::Http2 => {
2018-04-14 01:02:01 +02:00
self.proto = Some(HttpProtocol::H2(h2::Http2::new(
settings,
io,
addr,
buf.freeze(),
)));
return self.poll();
}
}
}
2018-01-12 07:06:06 +01:00
unreachable!()
}
}
2018-01-04 07:43:44 +01:00
2018-04-14 01:02:01 +02:00
pub(crate) struct Node<T> {
2018-01-04 07:43:44 +01:00
next: Option<*mut Node<()>>,
prev: Option<*mut Node<()>>,
element: *mut T,
}
2018-04-14 01:02:01 +02:00
impl<T> Node<T> {
2018-03-03 20:16:55 +01:00
fn new(el: *mut T) -> Self {
2018-01-04 07:43:44 +01:00
Node {
next: None,
prev: None,
2018-03-03 20:16:55 +01:00
element: el,
2018-01-04 07:43:44 +01:00
}
}
fn insert<I>(&self, next: &Node<I>) {
#[allow(mutable_transmutes)]
unsafe {
if let Some(ref next2) = self.next {
2018-04-29 07:55:47 +02:00
let n: &mut Node<()> =
&mut *(next2.as_ref().unwrap() as *const _ as *mut _);
2018-01-04 07:43:44 +01:00
n.prev = Some(next as *const _ as *mut _);
}
let slf: &mut Node<T> = mem::transmute(self);
slf.next = Some(next as *const _ as *mut _);
let next: &mut Node<T> = mem::transmute(next);
next.prev = Some(slf as *const _ as *mut _);
}
}
2018-03-03 19:06:13 +01:00
fn remove(&mut self) {
2018-01-04 07:43:44 +01:00
unsafe {
2018-03-03 20:16:55 +01:00
self.element = ptr::null_mut();
2018-03-03 19:06:13 +01:00
let next = self.next.take();
2018-03-03 20:16:55 +01:00
let mut prev = self.prev.take();
2018-03-03 19:06:13 +01:00
if let Some(ref mut prev) = prev {
2018-03-03 20:16:55 +01:00
prev.as_mut().unwrap().next = next;
2018-01-04 07:43:44 +01:00
}
}
}
}
impl Node<()> {
pub(crate) fn head() -> Self {
Node {
next: None,
prev: None,
element: ptr::null_mut(),
}
}
2018-04-14 01:02:01 +02:00
pub(crate) fn traverse<T, H>(&self)
where
T: IoStream,
H: HttpHandler + 'static,
{
2018-01-04 07:43:44 +01:00
let mut next = self.next.as_ref();
loop {
if let Some(n) = next {
unsafe {
let n: &Node<()> = mem::transmute(n.as_ref().unwrap());
next = n.next.as_ref();
if !n.element.is_null() {
2018-04-14 01:02:01 +02:00
let ch: &mut HttpChannel<T, H> =
mem::transmute(&mut *(n.element as *mut _));
2018-01-04 07:43:44 +01:00
ch.shutdown();
}
}
} else {
2018-04-14 01:02:01 +02:00
return;
2018-01-04 07:43:44 +01:00
}
}
}
}
2018-01-04 08:59:12 +01:00
/// Wrapper for `AsyncRead + AsyncWrite` types
2018-04-14 01:02:01 +02:00
pub(crate) struct WrapperStream<T>
where
T: AsyncRead + AsyncWrite + 'static,
{
io: T,
}
2018-04-14 01:02:01 +02:00
impl<T> WrapperStream<T>
where
T: AsyncRead + AsyncWrite + 'static,
{
pub fn new(io: T) -> Self {
2018-04-29 07:55:47 +02:00
WrapperStream {
io,
}
}
}
2018-04-14 01:02:01 +02:00
impl<T> IoStream for WrapperStream<T>
where
T: AsyncRead + AsyncWrite + 'static,
{
#[inline]
fn shutdown(&mut self, _: Shutdown) -> io::Result<()> {
Ok(())
}
#[inline]
fn set_nodelay(&mut self, _: bool) -> io::Result<()> {
Ok(())
}
#[inline]
fn set_linger(&mut self, _: Option<time::Duration>) -> io::Result<()> {
Ok(())
}
}
2018-04-14 01:02:01 +02:00
impl<T> io::Read for WrapperStream<T>
where
T: AsyncRead + AsyncWrite + 'static,
{
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.io.read(buf)
}
}
2018-04-14 01:02:01 +02:00
impl<T> io::Write for WrapperStream<T>
where
T: AsyncRead + AsyncWrite + 'static,
{
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.io.write(buf)
}
#[inline]
fn flush(&mut self) -> io::Result<()> {
self.io.flush()
}
}
2018-04-14 01:02:01 +02:00
impl<T> AsyncRead for WrapperStream<T>
where
T: AsyncRead + AsyncWrite + 'static,
{
2018-01-12 07:06:06 +01:00
#[inline]
fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
self.io.read_buf(buf)
}
}
2018-04-14 01:02:01 +02:00
impl<T> AsyncWrite for WrapperStream<T>
where
T: AsyncRead + AsyncWrite + 'static,
{
2018-01-12 07:06:06 +01:00
#[inline]
fn shutdown(&mut self) -> Poll<(), io::Error> {
self.io.shutdown()
}
2018-01-12 07:06:06 +01:00
#[inline]
fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
self.io.write_buf(buf)
}
}