1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-08-02 10:45:05 +00: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 extractor::{FormConfig, PayloadConfig};
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 info::ConnectionInfo;
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> {
pub fn new(
pub(crate) fn new(
req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>, handler: Rc<H>,
) -> Pipeline<S, H> {
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(
info, mws, self.resp.take().unwrap(),
)),

View file

@ -31,6 +31,10 @@ use super::{
};
/// 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>
where
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::rc::Rc;
use std::{io, net, time};
@ -83,8 +190,11 @@ where
}
bitflags! {
///Flags that can be used to configure HTTP Server.
pub struct ServerFlags: u8 {
///Use HTTP1 protocol
const HTTP1 = 0b0000_0001;
///Use HTTP2 protocol
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::{PauseServer, ResumeServer, StopServer, Token};
///Describes service that could be used
///with [Server](struct.Server.html)
pub trait Service: Send + 'static {
/// Clone 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 {
/// Handle incoming stream
fn handle(&mut self, token: Token, io: net::TcpStream, peer: Option<net::SocketAddr>);
@ -43,6 +47,7 @@ pub(crate) enum ServerCommand {
WorkerDied(usize),
}
///Server
pub struct Server {
threads: usize,
workers: Vec<(usize, Addr<Worker>)>,
@ -80,7 +85,7 @@ impl Server {
maxconnrate: 256,
}
}
/// Set number of workers to start.
///
/// 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.
pub fn maxconnrate(mut self, num: usize) -> Self {
self.maxconnrate= num;
self.maxconnrate = num;
self
}
@ -146,7 +151,7 @@ impl 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
T: Into<(Box<Service>, Vec<(Token, net::TcpListener)>)>
{
@ -171,7 +176,7 @@ impl Server {
///
/// fn main() {
/// Server::new().
/// .service(
/// .service(
/// HttpServer::new(|| App::new().resource("/", |r| r.h(|_| HttpResponse::Ok())))
/// .bind("127.0.0.1:0")
/// .expect("Can not bind to 127.0.0.1:0"))
@ -184,7 +189,7 @@ impl Server {
sys.run();
}
/// Start
/// Starts Server Actor and returns its address
pub fn start(mut self) -> Addr<Server> {
if self.sockets.is_empty() {
panic!("Service should have at least one bound socket");
@ -393,7 +398,8 @@ impl StreamHandler<ServerCommand, ()> for Server {
}
#[derive(Clone, Default)]
pub struct Connections (Arc<ConnectionsInner>);
///Contains information about connection.
pub struct Connections(Arc<ConnectionsInner>);
impl Connections {
fn new(notify: AcceptNotify, maxconn: usize, maxconnrate: usize) -> Self {
@ -458,7 +464,7 @@ impl ConnectionsInner {
self.notify.notify();
}
}
fn notify_maxconnrate(&self, connrate: usize) {
if connrate > self.maxconnrate_low && connrate <= self.maxconnrate {
self.notify.notify();
@ -468,8 +474,8 @@ impl ConnectionsInner {
}
/// 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>);
impl ConnectionTag {
@ -487,8 +493,8 @@ impl Drop for ConnectionTag {
}
/// 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>);
impl ConnectionRateTag {