1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-28 10:02:38 +01:00
actix-web/src/server/mod.rs

356 lines
8.9 KiB
Rust
Raw Normal View History

2018-01-12 03:35:05 +01:00
//! Http server
use std::net::Shutdown;
2018-04-14 01:02:01 +02:00
use std::{io, time};
2018-01-12 03:35:05 +01:00
2018-06-22 05:01:20 +02:00
use bytes::{BufMut, BytesMut};
2018-05-21 05:37:19 +02:00
use futures::{Async, Poll};
2018-04-14 01:02:01 +02:00
use tokio_io::{AsyncRead, AsyncWrite};
2018-05-25 06:03:16 +02:00
use tokio_tcp::TcpStream;
2018-01-12 03:35:05 +01:00
mod channel;
2018-06-25 06:58:04 +02:00
mod error;
2018-01-28 07:03:03 +01:00
pub(crate) mod h1;
2018-04-29 07:20:32 +02:00
pub(crate) mod h1decoder;
2018-01-12 03:35:05 +01:00
mod h1writer;
2018-04-14 01:02:01 +02:00
mod h2;
2018-01-12 03:35:05 +01:00
mod h2writer;
pub(crate) mod helpers;
2018-06-24 06:42:20 +02:00
pub(crate) mod input;
2018-06-25 06:58:04 +02:00
pub(crate) mod message;
2018-06-24 06:42:20 +02:00
pub(crate) mod output;
2018-06-18 00:56:18 +02:00
pub(crate) mod settings;
2018-04-14 01:02:01 +02:00
mod srv;
mod worker;
2018-01-12 03:35:05 +01:00
2018-06-25 06:58:04 +02:00
pub use self::message::Request;
2018-01-12 03:35:05 +01:00
pub use self::settings::ServerSettings;
2018-04-14 01:02:01 +02:00
pub use self::srv::HttpServer;
2018-01-12 03:35:05 +01:00
2018-05-21 05:37:19 +02:00
#[doc(hidden)]
pub use self::helpers::write_content_length;
2018-06-01 18:36:16 +02:00
use actix::Message;
2018-01-14 22:50:38 +01:00
use body::Binary;
2018-01-12 03:35:05 +01:00
use error::Error;
2018-03-29 20:06:44 +02:00
use header::ContentEncoding;
2018-01-12 03:35:05 +01:00
use httpresponse::HttpResponse;
/// max buffer size 64k
pub(crate) const MAX_WRITE_BUFFER_SIZE: usize = 65_536;
2018-06-22 05:01:20 +02:00
const LW_BUFFER_SIZE: usize = 4096;
const HW_BUFFER_SIZE: usize = 32_768;
/// Create new http server with application factory.
///
/// This is shortcut for `server::HttpServer::new()` method.
///
/// ```rust
2018-06-01 19:27:23 +02:00
/// # extern crate actix_web;
2018-06-01 18:36:16 +02:00
/// use actix_web::{actix, server, App, HttpResponse};
///
/// fn main() {
2018-06-17 00:09:07 +02:00
/// let sys = actix::System::new("example"); // <- create Actix system
///
2018-06-17 00:09:07 +02:00
/// server::new(
/// || App::new()
/// .resource("/", |r| r.f(|_| HttpResponse::Ok())))
/// .bind("127.0.0.1:59090").unwrap()
/// .start();
///
2018-06-14 08:37:19 +02:00
/// # actix::System::current().stop();
2018-06-17 00:09:07 +02:00
/// sys.run();
/// }
/// ```
2018-03-31 03:54:38 +02:00
pub fn new<F, U, H>(factory: F) -> HttpServer<H>
2018-04-14 01:02:01 +02:00
where
F: Fn() -> U + Sync + Send + 'static,
U: IntoIterator<Item = H> + 'static,
H: IntoHttpHandler + 'static,
2018-03-31 03:54:38 +02:00
{
HttpServer::new(factory)
}
#[derive(Debug, PartialEq, Clone, Copy)]
/// Server keep-alive setting
pub enum KeepAlive {
/// Keep alive in seconds
Timeout(usize),
/// Use `SO_KEEPALIVE` socket option, value in seconds
Tcp(usize),
/// Relay on OS to shutdown tcp connection
Os,
/// Disabled
Disabled,
}
impl From<usize> for KeepAlive {
fn from(keepalive: usize) -> Self {
KeepAlive::Timeout(keepalive)
}
}
impl From<Option<usize>> for KeepAlive {
fn from(keepalive: Option<usize>) -> Self {
if let Some(keepalive) = keepalive {
KeepAlive::Timeout(keepalive)
} else {
KeepAlive::Disabled
}
}
}
2018-01-12 03:35:05 +01:00
/// Pause accepting incoming connections
///
/// If socket contains some pending connection, they might be dropped.
/// All opened connection remains active.
#[derive(Message)]
pub struct PauseServer;
/// Resume accepting incoming connections
#[derive(Message)]
pub struct ResumeServer;
/// Stop incoming connection processing, stop all workers and exit.
///
/// If server starts with `spawn()` method, then spawned thread get terminated.
pub struct StopServer {
/// Whether to try and shut down gracefully
2018-04-14 01:02:01 +02:00
pub graceful: bool,
2018-01-12 03:35:05 +01:00
}
2018-06-01 18:36:16 +02:00
impl Message for StopServer {
2018-02-12 21:17:30 +01:00
type Result = Result<(), ()>;
}
2018-01-12 03:35:05 +01:00
/// Low level http request handler
#[allow(unused_variables)]
pub trait HttpHandler: 'static {
2018-06-18 01:45:54 +02:00
/// Request handling task
type Task: HttpHandlerTask;
2018-01-12 03:35:05 +01:00
/// Handle request
2018-06-25 06:58:04 +02:00
fn handle(&self, req: Request) -> Result<Self::Task, Request>;
2018-01-12 03:35:05 +01:00
}
2018-06-18 01:45:54 +02:00
impl HttpHandler for Box<HttpHandler<Task = Box<HttpHandlerTask>>> {
type Task = Box<HttpHandlerTask>;
2018-06-25 06:58:04 +02:00
fn handle(&self, req: Request) -> Result<Box<HttpHandlerTask>, Request> {
self.as_ref().handle(req)
}
}
2018-06-18 01:45:54 +02:00
/// Low level http request handler
2018-01-12 03:35:05 +01:00
pub trait HttpHandlerTask {
2018-03-31 18:18:25 +02:00
/// Poll task, this method is used before or after *io* object is available
2018-06-18 01:45:54 +02:00
fn poll_completed(&mut self) -> Poll<(), Error> {
2018-05-21 05:37:19 +02:00
Ok(Async::Ready(()))
}
2018-01-12 03:35:05 +01:00
2018-03-31 18:18:25 +02:00
/// Poll task when *io* object is available
2018-01-12 07:06:06 +01:00
fn poll_io(&mut self, io: &mut Writer) -> Poll<bool, Error>;
2018-03-31 18:18:25 +02:00
/// Connection is disconnected
2018-05-21 05:37:19 +02:00
fn disconnected(&mut self) {}
2018-01-12 03:35:05 +01:00
}
2018-06-18 01:45:54 +02:00
impl HttpHandlerTask for Box<HttpHandlerTask> {
fn poll_io(&mut self, io: &mut Writer) -> Poll<bool, Error> {
self.as_mut().poll_io(io)
}
}
2018-01-12 03:35:05 +01:00
/// Conversion helper trait
pub trait IntoHttpHandler {
/// The associated type which is result of conversion.
type Handler: HttpHandler;
/// Convert into `HttpHandler` object.
2018-06-25 06:58:04 +02:00
fn into_handler(self) -> Self::Handler;
2018-01-12 03:35:05 +01:00
}
impl<T: HttpHandler> IntoHttpHandler for T {
type Handler = T;
2018-06-25 06:58:04 +02:00
fn into_handler(self) -> Self::Handler {
2018-01-12 03:35:05 +01:00
self
}
}
2018-03-31 18:18:25 +02:00
#[doc(hidden)]
2018-01-12 03:35:05 +01:00
#[derive(Debug)]
pub enum WriterState {
Done,
Pause,
}
2018-03-31 18:18:25 +02:00
#[doc(hidden)]
2018-01-12 03:35:05 +01:00
/// Stream writer
pub trait Writer {
2018-05-21 05:37:19 +02:00
/// number of bytes written to the stream
2018-01-12 03:35:05 +01:00
fn written(&self) -> u64;
2018-05-21 05:37:19 +02:00
#[doc(hidden)]
2018-06-25 06:58:04 +02:00
fn set_date(&mut self);
2018-05-21 05:37:19 +02:00
#[doc(hidden)]
2018-06-19 03:44:01 +02:00
fn buffer(&mut self) -> &mut BytesMut;
2018-05-21 05:37:19 +02:00
2018-04-14 01:02:01 +02:00
fn start(
2018-06-25 06:58:04 +02:00
&mut self, req: &Request, resp: &mut HttpResponse, encoding: ContentEncoding,
2018-04-14 01:02:01 +02:00
) -> io::Result<WriterState>;
2018-01-12 03:35:05 +01:00
2018-06-19 03:44:01 +02:00
fn write(&mut self, payload: &Binary) -> io::Result<WriterState>;
2018-01-12 03:35:05 +01:00
2018-01-14 22:50:38 +01:00
fn write_eof(&mut self) -> io::Result<WriterState>;
2018-01-12 03:35:05 +01:00
fn poll_completed(&mut self, shutdown: bool) -> Poll<(), io::Error>;
}
2018-01-12 07:06:06 +01:00
2018-03-31 18:18:25 +02:00
#[doc(hidden)]
2018-01-12 07:06:06 +01:00
/// Low-level io stream operations
pub trait IoStream: AsyncRead + AsyncWrite + 'static {
fn shutdown(&mut self, how: Shutdown) -> io::Result<()>;
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()>;
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()>;
2018-06-22 05:01:20 +02:00
2018-06-22 07:30:40 +02:00
fn read_available(&mut self, buf: &mut BytesMut) -> Poll<bool, io::Error> {
let mut read_some = false;
loop {
2018-06-23 07:51:02 +02:00
if buf.remaining_mut() < LW_BUFFER_SIZE {
buf.reserve(HW_BUFFER_SIZE);
}
2018-06-22 07:30:40 +02:00
unsafe {
match self.read(buf.bytes_mut()) {
Ok(n) => {
if n == 0 {
return Ok(Async::Ready(!read_some));
} else {
read_some = true;
buf.advance_mut(n);
}
}
Err(e) => {
return if e.kind() == io::ErrorKind::WouldBlock {
if read_some {
Ok(Async::Ready(false))
} else {
Ok(Async::NotReady)
}
} else {
Err(e)
};
2018-06-22 05:01:20 +02:00
}
}
}
}
}
2018-01-12 07:06:06 +01:00
}
impl IoStream for TcpStream {
#[inline]
fn shutdown(&mut self, how: Shutdown) -> io::Result<()> {
TcpStream::shutdown(self, how)
}
#[inline]
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
TcpStream::set_nodelay(self, nodelay)
}
#[inline]
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
TcpStream::set_linger(self, dur)
}
}
2018-04-14 01:02:01 +02:00
#[cfg(feature = "alpn")]
2018-01-12 07:06:06 +01:00
use tokio_openssl::SslStream;
2018-04-14 01:02:01 +02:00
#[cfg(feature = "alpn")]
2018-01-12 07:06:06 +01:00
impl IoStream for SslStream<TcpStream> {
#[inline]
fn shutdown(&mut self, _how: Shutdown) -> io::Result<()> {
let _ = self.get_mut().shutdown();
Ok(())
}
#[inline]
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
self.get_mut().get_mut().set_nodelay(nodelay)
}
#[inline]
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
self.get_mut().get_mut().set_linger(dur)
}
}
2018-04-14 01:02:01 +02:00
#[cfg(feature = "tls")]
2018-01-12 07:06:06 +01:00
use tokio_tls::TlsStream;
2018-04-14 01:02:01 +02:00
#[cfg(feature = "tls")]
2018-01-12 07:06:06 +01:00
impl IoStream for TlsStream<TcpStream> {
#[inline]
fn shutdown(&mut self, _how: Shutdown) -> io::Result<()> {
let _ = self.get_mut().shutdown();
Ok(())
}
#[inline]
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
self.get_mut().get_mut().set_nodelay(nodelay)
}
#[inline]
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
self.get_mut().get_mut().set_linger(dur)
}
}
2018-07-29 08:43:04 +02:00
#[cfg(feature = "rust-tls")]
use rustls::{ClientSession, ServerSession};
#[cfg(feature = "rust-tls")]
use tokio_rustls::TlsStream;
#[cfg(feature = "rust-tls")]
impl IoStream for TlsStream<TcpStream, ClientSession> {
#[inline]
fn shutdown(&mut self, _how: Shutdown) -> io::Result<()> {
let _ = <Self as AsyncWrite>::shutdown(self);
Ok(())
}
#[inline]
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
self.get_mut().0.set_nodelay(nodelay)
}
#[inline]
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
self.get_mut().0.set_linger(dur)
}
}
#[cfg(feature = "rust-tls")]
impl IoStream for TlsStream<TcpStream, ServerSession> {
#[inline]
fn shutdown(&mut self, _how: Shutdown) -> io::Result<()> {
let _ = <Self as AsyncWrite>::shutdown(self);
Ok(())
}
#[inline]
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
self.get_mut().0.set_nodelay(nodelay)
}
#[inline]
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
self.get_mut().0.set_linger(dur)
}
}