1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-24 07:53:00 +01:00

Improve HTTP server docs (#470)

This commit is contained in:
Douman 2018-08-16 16:11:15 +03:00 committed by GitHub
parent 9f5641c85b
commit 248bd388ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 136 additions and 15 deletions

View File

@ -251,7 +251,8 @@ pub mod dev {
pub use context::Drain; pub use context::Drain;
pub use extractor::{FormConfig, PayloadConfig}; pub use extractor::{FormConfig, PayloadConfig};
pub use handler::{AsyncResult, Handler}; pub use handler::{AsyncResult, Handler};
pub use httpmessage::{MessageBody, UrlEncoded}; pub use httpmessage::{MessageBody, Readlines, UrlEncoded};
pub use pipeline::Pipeline;
pub use httpresponse::HttpResponseBuilder; pub use httpresponse::HttpResponseBuilder;
pub use info::ConnectionInfo; pub use info::ConnectionInfo;
pub use json::{JsonBody, JsonConfig}; pub use json::{JsonBody, JsonConfig};

View File

@ -83,7 +83,7 @@ impl<S: 'static> PipelineInfo<S> {
} }
impl<S: 'static, H: PipelineHandler<S>> Pipeline<S, H> { impl<S: 'static, H: PipelineHandler<S>> Pipeline<S, H> {
pub fn new( pub(crate) fn new(
req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>, handler: Rc<H>, req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>, handler: Rc<H>,
) -> Pipeline<S, H> { ) -> Pipeline<S, H> {
let mut info = PipelineInfo { let mut info = PipelineInfo {
@ -475,7 +475,7 @@ impl<S: 'static, H> ProcessResponse<S, H> {
} }
} }
} }
Ok(Async::Ready(None)) => Ok(Async::Ready(None)) =>
return Some(FinishingMiddlewares::init( return Some(FinishingMiddlewares::init(
info, mws, self.resp.take().unwrap(), info, mws, self.resp.take().unwrap(),
)), )),

View File

@ -31,6 +31,10 @@ use super::{
}; };
/// An HTTP Server /// An HTTP Server
///
/// By default it serves HTTP2 when HTTPs is enabled,
/// in order to change it, use `ServerFlags` that can be provided
/// to acceptor service.
pub struct HttpServer<H> pub struct HttpServer<H>
where where
H: IntoHttpHandler + 'static, H: IntoHttpHandler + 'static,

View File

@ -1,4 +1,111 @@
//! Http server //! Http server module
//!
//! The module contains everything necessary to setup
//! HTTP server.
//!
//! In order to start HTTP server, first you need to create and configure it
//! using factory that can be supplied to [new](fn.new.html).
//!
//! ## Factory
//!
//! Factory is a function that returns Application, describing how
//! to serve incoming HTTP requests.
//!
//! As the server uses worker pool, the factory function is restricted to trait bounds
//! `Sync + Send + 'static` so that each worker would be able to accept Application
//! without a need for synchronization.
//!
//! If you wish to share part of state among all workers you should
//! wrap it in `Arc` and potentially synchronization primitive like
//! [RwLock](https://doc.rust-lang.org/std/sync/struct.RwLock.html)
//! If the wrapped type is not thread safe.
//!
//! Note though that locking is not advisable for asynchronous programming
//! and you should minimize all locks in your request handlers
//!
//! ## HTTPS Support
//!
//! Actix-web provides support for major crates that provides TLS.
//! Each TLS implementation is provided with [AcceptorService](trait.AcceptorService.html)
//! that describes how HTTP Server accepts connections.
//!
//! For `bind` and `listen` there are corresponding `bind_with` and `listen_with` that accepts
//! these services.
//!
//! By default, acceptor would work with both HTTP2 and HTTP1 protocols.
//! But it can be controlled using [ServerFlags](struct.ServerFlags.html) which
//! can be supplied when creating `AcceptorService`.
//!
//! **NOTE:** `native-tls` doesn't support `HTTP2` yet
//!
//! ## Signal handling and shutdown
//!
//! By default HTTP Server listens for system signals
//! and, gracefully shuts down at most after 30 seconds.
//!
//! Both signal handling and shutdown timeout can be controlled
//! using corresponding methods.
//!
//! If worker, for some reason, unable to shut down within timeout
//! it is forcibly dropped.
//!
//! ## Example
//!
//! ```rust,ignore
//!extern crate actix;
//!extern crate actix_web;
//!extern crate rustls;
//!
//!use actix_web::{http, middleware, server, App, Error, HttpRequest, HttpResponse, Responder};
//!use std::io::BufReader;
//!use rustls::internal::pemfile::{certs, rsa_private_keys};
//!use rustls::{NoClientAuth, ServerConfig};
//!
//!fn index(req: &HttpRequest) -> Result<HttpResponse, Error> {
//! Ok(HttpResponse::Ok().content_type("text/plain").body("Welcome!"))
//!}
//!
//!fn load_ssl() -> ServerConfig {
//! use std::io::BufReader;
//!
//! const CERT: &'static [u8] = include_bytes!("../cert.pem");
//! const KEY: &'static [u8] = include_bytes!("../key.pem");
//!
//! let mut cert = BufReader::new(CERT);
//! let mut key = BufReader::new(KEY);
//!
//! let mut config = ServerConfig::new(NoClientAuth::new());
//! let cert_chain = certs(&mut cert).unwrap();
//! let mut keys = rsa_private_keys(&mut key).unwrap();
//! config.set_single_cert(cert_chain, keys.remove(0)).unwrap();
//!
//! config
//!}
//!
//!fn main() {
//! let sys = actix::System::new("http-server");
//! // load ssl keys
//! let config = load_ssl();
//!
//! // Create acceptor service for only HTTP1 protocol
//! // You can use ::new(config) to leave defaults
//! let acceptor = server::RustlsAcceptor::with_flags(config, actix_web::server::ServerFlags::HTTP1);
//!
//! // create and start server at once
//! server::new(|| {
//! App::new()
//! // register simple handler, handle all methods
//! .resource("/index.html", |r| r.f(index))
//! }))
//! }).bind_with("127.0.0.1:8080", acceptor)
//! .unwrap()
//! .start();
//!
//! println!("Started http server: 127.0.0.1:8080");
//! //Run system so that server would start accepting connections
//! let _ = sys.run();
//!}
//! ```
use std::net::Shutdown; use std::net::Shutdown;
use std::rc::Rc; use std::rc::Rc;
use std::{io, net, time}; use std::{io, net, time};
@ -83,8 +190,11 @@ where
} }
bitflags! { bitflags! {
///Flags that can be used to configure HTTP Server.
pub struct ServerFlags: u8 { pub struct ServerFlags: u8 {
///Use HTTP1 protocol
const HTTP1 = 0b0000_0001; const HTTP1 = 0b0000_0001;
///Use HTTP2 protocol
const HTTP2 = 0b0000_0010; const HTTP2 = 0b0000_0010;
} }
} }

View File

@ -13,6 +13,8 @@ use super::accept::{AcceptLoop, AcceptNotify, Command};
use super::worker::{StopWorker, Worker, WorkerClient, Conn}; use super::worker::{StopWorker, Worker, WorkerClient, Conn};
use super::{PauseServer, ResumeServer, StopServer, Token}; use super::{PauseServer, ResumeServer, StopServer, Token};
///Describes service that could be used
///with [Server](struct.Server.html)
pub trait Service: Send + 'static { pub trait Service: Send + 'static {
/// Clone service /// Clone service
fn clone(&self) -> Box<Service>; fn clone(&self) -> Box<Service>;
@ -31,6 +33,8 @@ impl Service for Box<Service> {
} }
} }
///Describes the way serivce handles incoming
///TCP connections.
pub trait ServiceHandler { pub trait ServiceHandler {
/// Handle incoming stream /// Handle incoming stream
fn handle(&mut self, token: Token, io: net::TcpStream, peer: Option<net::SocketAddr>); fn handle(&mut self, token: Token, io: net::TcpStream, peer: Option<net::SocketAddr>);
@ -43,6 +47,7 @@ pub(crate) enum ServerCommand {
WorkerDied(usize), WorkerDied(usize),
} }
///Server
pub struct Server { pub struct Server {
threads: usize, threads: usize,
workers: Vec<(usize, Addr<Worker>)>, workers: Vec<(usize, Addr<Worker>)>,
@ -80,7 +85,7 @@ impl Server {
maxconnrate: 256, maxconnrate: 256,
} }
} }
/// Set number of workers to start. /// Set number of workers to start.
/// ///
/// By default http server uses number of available logical cpu as threads /// By default http server uses number of available logical cpu as threads
@ -108,7 +113,7 @@ impl Server {
/// ///
/// By default max connections is set to a 256. /// By default max connections is set to a 256.
pub fn maxconnrate(mut self, num: usize) -> Self { pub fn maxconnrate(mut self, num: usize) -> Self {
self.maxconnrate= num; self.maxconnrate = num;
self self
} }
@ -146,7 +151,7 @@ impl Server {
} }
/// Add new service to server /// Add new service to server
pub fn service<T>(mut self, srv: T) -> Self pub fn service<T>(mut self, srv: T) -> Self
where where
T: Into<(Box<Service>, Vec<(Token, net::TcpListener)>)> T: Into<(Box<Service>, Vec<(Token, net::TcpListener)>)>
{ {
@ -171,7 +176,7 @@ impl Server {
/// ///
/// fn main() { /// fn main() {
/// Server::new(). /// Server::new().
/// .service( /// .service(
/// HttpServer::new(|| App::new().resource("/", |r| r.h(|_| HttpResponse::Ok()))) /// HttpServer::new(|| App::new().resource("/", |r| r.h(|_| HttpResponse::Ok())))
/// .bind("127.0.0.1:0") /// .bind("127.0.0.1:0")
/// .expect("Can not bind to 127.0.0.1:0")) /// .expect("Can not bind to 127.0.0.1:0"))
@ -184,7 +189,7 @@ impl Server {
sys.run(); sys.run();
} }
/// Start /// Starts Server Actor and returns its address
pub fn start(mut self) -> Addr<Server> { pub fn start(mut self) -> Addr<Server> {
if self.sockets.is_empty() { if self.sockets.is_empty() {
panic!("Service should have at least one bound socket"); panic!("Service should have at least one bound socket");
@ -393,7 +398,8 @@ impl StreamHandler<ServerCommand, ()> for Server {
} }
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct Connections (Arc<ConnectionsInner>); ///Contains information about connection.
pub struct Connections(Arc<ConnectionsInner>);
impl Connections { impl Connections {
fn new(notify: AcceptNotify, maxconn: usize, maxconnrate: usize) -> Self { fn new(notify: AcceptNotify, maxconn: usize, maxconnrate: usize) -> Self {
@ -458,7 +464,7 @@ impl ConnectionsInner {
self.notify.notify(); self.notify.notify();
} }
} }
fn notify_maxconnrate(&self, connrate: usize) { fn notify_maxconnrate(&self, connrate: usize) {
if connrate > self.maxconnrate_low && connrate <= self.maxconnrate { if connrate > self.maxconnrate_low && connrate <= self.maxconnrate {
self.notify.notify(); self.notify.notify();
@ -468,8 +474,8 @@ impl ConnectionsInner {
} }
/// Type responsible for max connection stat. /// Type responsible for max connection stat.
/// ///
/// Max connections stat get updated on drop. /// Max connections stat get updated on drop.
pub struct ConnectionTag(Arc<ConnectionsInner>); pub struct ConnectionTag(Arc<ConnectionsInner>);
impl ConnectionTag { impl ConnectionTag {
@ -487,8 +493,8 @@ impl Drop for ConnectionTag {
} }
/// Type responsible for max connection rate stat. /// Type responsible for max connection rate stat.
/// ///
/// Max connections rate stat get updated on drop. /// Max connections rate stat get updated on drop.
pub struct ConnectionRateTag (Arc<ConnectionsInner>); pub struct ConnectionRateTag (Arc<ConnectionsInner>);
impl ConnectionRateTag { impl ConnectionRateTag {