2018-01-04 07:43:44 +01:00
|
|
|
use std::{ptr, mem, time};
|
2017-12-08 18:24:05 +01:00
|
|
|
use std::rc::Rc;
|
2018-01-04 07:43:44 +01:00
|
|
|
use std::net::{SocketAddr, Shutdown};
|
2017-11-04 20:33:14 +01:00
|
|
|
|
|
|
|
use bytes::Bytes;
|
|
|
|
use futures::{Future, Poll, Async};
|
|
|
|
use tokio_io::{AsyncRead, AsyncWrite};
|
2018-01-04 07:43:44 +01:00
|
|
|
use tokio_core::net::TcpStream;
|
2017-11-04 20:33:14 +01:00
|
|
|
|
2017-12-29 20:45:56 +01:00
|
|
|
use {h1, h2};
|
2017-12-09 13:33:40 +01:00
|
|
|
use error::Error;
|
|
|
|
use h1writer::Writer;
|
2017-11-04 20:33:14 +01:00
|
|
|
use httprequest::HttpRequest;
|
2017-12-28 21:38:37 +01:00
|
|
|
use server::ServerSettings;
|
|
|
|
use worker::WorkerSettings;
|
2017-11-04 20:33:14 +01:00
|
|
|
|
|
|
|
/// Low level http request handler
|
2017-12-08 18:24:05 +01:00
|
|
|
#[allow(unused_variables)]
|
2017-11-04 20:33:14 +01:00
|
|
|
pub trait HttpHandler: 'static {
|
2017-12-09 13:33:40 +01:00
|
|
|
|
2017-11-04 20:33:14 +01:00
|
|
|
/// Handle request
|
2017-12-26 18:00:45 +01:00
|
|
|
fn handle(&mut self, req: HttpRequest) -> Result<Box<HttpHandlerTask>, HttpRequest>;
|
2017-11-04 20:33:14 +01:00
|
|
|
}
|
|
|
|
|
2017-12-09 13:33:40 +01:00
|
|
|
pub trait HttpHandlerTask {
|
|
|
|
|
|
|
|
fn poll_io(&mut self, io: &mut Writer) -> Poll<bool, Error>;
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Poll<(), Error>;
|
|
|
|
|
|
|
|
fn disconnected(&mut self);
|
|
|
|
}
|
|
|
|
|
2017-12-06 20:00:39 +01:00
|
|
|
/// Conversion helper trait
|
|
|
|
pub trait IntoHttpHandler {
|
|
|
|
/// The associated type which is result of conversion.
|
|
|
|
type Handler: HttpHandler;
|
|
|
|
|
|
|
|
/// Convert into `HttpHandler` object.
|
2017-12-29 20:33:04 +01:00
|
|
|
fn into_handler(self, settings: ServerSettings) -> Self::Handler;
|
2017-12-06 20:00:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: HttpHandler> IntoHttpHandler for T {
|
|
|
|
type Handler = T;
|
|
|
|
|
2017-12-29 20:33:04 +01:00
|
|
|
fn into_handler(self, _: ServerSettings) -> Self::Handler {
|
2017-12-06 20:00:39 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-10 22:08:15 +01:00
|
|
|
enum HttpProtocol<T, H>
|
2017-12-09 13:33:40 +01:00
|
|
|
where T: AsyncRead + AsyncWrite + 'static, H: HttpHandler + 'static
|
2017-11-04 20:33:14 +01:00
|
|
|
{
|
2017-11-10 22:08:15 +01:00
|
|
|
H1(h1::Http1<T, H>),
|
|
|
|
H2(h2::Http2<T, H>),
|
2017-11-04 20:33:14 +01:00
|
|
|
}
|
|
|
|
|
2017-11-27 07:53:28 +01:00
|
|
|
#[doc(hidden)]
|
2017-11-10 22:08:15 +01:00
|
|
|
pub struct HttpChannel<T, H>
|
2017-12-09 13:33:40 +01:00
|
|
|
where T: AsyncRead + AsyncWrite + 'static, H: HttpHandler + 'static
|
2017-11-04 20:33:14 +01:00
|
|
|
{
|
2017-11-10 22:08:15 +01:00
|
|
|
proto: Option<HttpProtocol<T, H>>,
|
2018-01-04 07:43:44 +01:00
|
|
|
node: Option<Node<HttpChannel<T, H>>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T, H> Drop for HttpChannel<T, H>
|
|
|
|
where T: AsyncRead + AsyncWrite + 'static, H: HttpHandler + 'static
|
|
|
|
{
|
|
|
|
fn drop(&mut self) {
|
|
|
|
self.shutdown()
|
|
|
|
}
|
2017-11-04 20:33:14 +01:00
|
|
|
}
|
|
|
|
|
2017-11-10 22:08:15 +01:00
|
|
|
impl<T, H> HttpChannel<T, H>
|
|
|
|
where T: AsyncRead + AsyncWrite + 'static, H: HttpHandler + 'static
|
2017-11-04 20:33:14 +01:00
|
|
|
{
|
2017-12-14 06:38:47 +01:00
|
|
|
pub(crate) fn new(h: Rc<WorkerSettings<H>>,
|
2018-01-04 07:43:44 +01:00
|
|
|
io: T, peer: Option<SocketAddr>, http2: bool) -> HttpChannel<T, H>
|
2017-12-08 06:52:46 +01:00
|
|
|
{
|
2017-12-29 01:25:47 +01:00
|
|
|
h.add_channel();
|
2017-11-04 20:33:14 +01:00
|
|
|
if http2 {
|
|
|
|
HttpChannel {
|
2018-01-04 07:43:44 +01:00
|
|
|
node: None,
|
2017-11-04 20:33:14 +01:00
|
|
|
proto: Some(HttpProtocol::H2(
|
2017-12-08 18:24:05 +01:00
|
|
|
h2::Http2::new(h, io, peer, Bytes::new()))) }
|
2017-11-04 20:33:14 +01:00
|
|
|
} else {
|
|
|
|
HttpChannel {
|
2018-01-04 07:43:44 +01:00
|
|
|
node: None,
|
2017-11-04 20:33:14 +01:00
|
|
|
proto: Some(HttpProtocol::H1(
|
2017-12-08 18:24:05 +01:00
|
|
|
h1::Http1::new(h, io, peer))) }
|
2017-11-04 20:33:14 +01:00
|
|
|
}
|
|
|
|
}
|
2018-01-04 07:43:44 +01:00
|
|
|
|
|
|
|
fn io(&mut self) -> Option<&mut T> {
|
|
|
|
match self.proto {
|
|
|
|
Some(HttpProtocol::H1(ref mut h1)) => {
|
|
|
|
Some(h1.io())
|
|
|
|
}
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn shutdown(&mut self) {
|
|
|
|
match self.proto {
|
|
|
|
Some(HttpProtocol::H1(ref mut h1)) => {
|
|
|
|
let _ = h1.io().shutdown();
|
|
|
|
}
|
|
|
|
Some(HttpProtocol::H2(ref mut h2)) => {
|
|
|
|
h2.shutdown()
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
2017-11-04 20:33:14 +01:00
|
|
|
}
|
|
|
|
|
2018-01-04 03:21:34 +01:00
|
|
|
/*impl<T, H> Drop for HttpChannel<T, H>
|
|
|
|
where T: AsyncRead + AsyncWrite + 'static, H: HttpHandler + 'static
|
|
|
|
{
|
2017-11-04 20:33:14 +01:00
|
|
|
fn drop(&mut self) {
|
|
|
|
println!("Drop http channel");
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
|
2017-11-10 22:08:15 +01:00
|
|
|
impl<T, H> Future for HttpChannel<T, H>
|
|
|
|
where T: AsyncRead + AsyncWrite + 'static, H: HttpHandler + 'static
|
2017-11-04 20:33:14 +01:00
|
|
|
{
|
|
|
|
type Item = ();
|
|
|
|
type Error = ();
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
2018-01-04 07:43:44 +01:00
|
|
|
if self.node.is_none() {
|
|
|
|
self.node = Some(Node::new(self));
|
|
|
|
match self.proto {
|
|
|
|
Some(HttpProtocol::H1(ref mut h1)) => {
|
|
|
|
h1.settings().head().insert(self.node.as_ref().unwrap());
|
|
|
|
}
|
|
|
|
Some(HttpProtocol::H2(ref mut h2)) => {
|
|
|
|
h2.settings().head().insert(self.node.as_ref().unwrap());
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-04 20:33:14 +01:00
|
|
|
match self.proto {
|
|
|
|
Some(HttpProtocol::H1(ref mut h1)) => {
|
|
|
|
match h1.poll() {
|
2017-12-29 01:25:47 +01:00
|
|
|
Ok(Async::Ready(h1::Http1Result::Done)) => {
|
|
|
|
h1.settings().remove_channel();
|
2018-01-04 07:43:44 +01:00
|
|
|
self.node.as_ref().unwrap().remove();
|
2017-12-29 01:25:47 +01:00
|
|
|
return Ok(Async::Ready(()))
|
|
|
|
}
|
2017-11-04 21:49:05 +01:00
|
|
|
Ok(Async::Ready(h1::Http1Result::Switch)) => (),
|
2017-11-04 20:33:14 +01:00
|
|
|
Ok(Async::NotReady) =>
|
|
|
|
return Ok(Async::NotReady),
|
2017-12-29 01:25:47 +01:00
|
|
|
Err(_) => {
|
|
|
|
h1.settings().remove_channel();
|
2018-01-04 07:43:44 +01:00
|
|
|
self.node.as_ref().unwrap().remove();
|
2017-12-29 01:25:47 +01:00
|
|
|
return Err(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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();
|
|
|
|
self.node.as_ref().unwrap().remove();
|
|
|
|
}
|
2017-12-29 01:25:47 +01:00
|
|
|
_ => (),
|
2017-11-04 20:33:14 +01:00
|
|
|
}
|
2017-12-29 01:25:47 +01:00
|
|
|
return result
|
2017-11-04 20:33:14 +01:00
|
|
|
}
|
|
|
|
None => unreachable!(),
|
|
|
|
}
|
|
|
|
|
|
|
|
// upgrade to h2
|
|
|
|
let proto = self.proto.take().unwrap();
|
|
|
|
match proto {
|
|
|
|
HttpProtocol::H1(h1) => {
|
2017-12-08 18:24:05 +01:00
|
|
|
let (h, io, addr, buf) = h1.into_inner();
|
2017-12-08 07:54:44 +01:00
|
|
|
self.proto = Some(
|
2017-12-08 18:24:05 +01:00
|
|
|
HttpProtocol::H2(h2::Http2::new(h, io, addr, buf)));
|
2017-11-04 20:33:14 +01:00
|
|
|
self.poll()
|
|
|
|
}
|
|
|
|
_ => unreachable!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-01-04 07:43:44 +01:00
|
|
|
|
|
|
|
pub(crate) struct Node<T>
|
|
|
|
{
|
|
|
|
next: Option<*mut Node<()>>,
|
|
|
|
prev: Option<*mut Node<()>>,
|
|
|
|
element: *mut T,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Node<T>
|
|
|
|
{
|
|
|
|
fn new(el: &mut T) -> Self {
|
|
|
|
Node {
|
|
|
|
next: None,
|
|
|
|
prev: None,
|
|
|
|
element: el as *mut _,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn insert<I>(&self, next: &Node<I>) {
|
|
|
|
#[allow(mutable_transmutes)]
|
|
|
|
unsafe {
|
|
|
|
if let Some(ref next2) = self.next {
|
|
|
|
let n: &mut Node<()> = mem::transmute(next2.as_ref().unwrap());
|
|
|
|
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 _);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn remove(&self) {
|
|
|
|
#[allow(mutable_transmutes)]
|
|
|
|
unsafe {
|
|
|
|
if let Some(ref prev) = self.prev {
|
|
|
|
let p: &mut Node<()> = mem::transmute(prev.as_ref().unwrap());
|
|
|
|
let slf: &mut Node<T> = mem::transmute(self);
|
|
|
|
p.next = slf.next.take();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Node<()> {
|
|
|
|
|
|
|
|
pub(crate) fn head() -> Self {
|
|
|
|
Node {
|
|
|
|
next: None,
|
|
|
|
prev: None,
|
|
|
|
element: ptr::null_mut(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn traverse<H>(&self) where H: HttpHandler + 'static {
|
|
|
|
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() {
|
|
|
|
let ch: &mut HttpChannel<TcpStream, H> = mem::transmute(
|
|
|
|
&mut *(n.element as *mut _));
|
|
|
|
if let Some(io) = ch.io() {
|
|
|
|
let _ = TcpStream::set_linger(io, Some(time::Duration::new(0, 0)));
|
|
|
|
let _ = TcpStream::shutdown(io, Shutdown::Both);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ch.shutdown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|