1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-02-07 05:54:22 +01:00
actix-web/guide/src/qs_3_5.md
2018-03-30 17:31:18 -07:00

204 lines
6.7 KiB
Markdown

# Server
The [*HttpServer*](../actix_web/struct.HttpServer.html) type is responsible for
serving http requests. *HttpServer* accepts application factory as a parameter,
Application factory must have `Send` + `Sync` boundaries. More about that in the
*multi-threading* section. To bind to a specific socket address, `bind()` must be used.
This method can be called multiple times. To start the http server, one of the *start*
methods can be used. `start()` method starts a simple server, `start_tls()` or `start_ssl()`
starts ssl server. *HttpServer* is an actix actor, it has to be initialized
within a properly configured actix system:
```rust
# extern crate actix;
# extern crate actix_web;
use actix::*;
use actix_web::*;
fn main() {
let sys = actix::System::new("guide");
HttpServer::new(
|| Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.bind("127.0.0.1:59080").unwrap()
.start();
# actix::Arbiter::system().do_send(actix::msgs::SystemExit(0));
let _ = sys.run();
}
```
It is possible to start a server in a separate thread with the *spawn()* method. In that
case the server spawns a new thread and creates a new actix system in it. To stop
this server, send a `StopServer` message.
Http server is implemented as an actix actor. It is possible to communicate with the server
via a messaging system. All start methods like `start()`, `start_ssl()`, etc. return the
address of the started http server. Actix http server accepts several messages:
* `PauseServer` - Pause accepting incoming connections
* `ResumeServer` - Resume accepting incoming connections
* `StopServer` - Stop incoming connection processing, stop all workers and exit
```rust
# extern crate futures;
# extern crate actix;
# extern crate actix_web;
# use futures::Future;
use actix_web::*;
use std::thread;
use std::sync::mpsc;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let sys = actix::System::new("http-server");
let addr = HttpServer::new(
|| Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.bind("127.0.0.1:0").expect("Can not bind to 127.0.0.1:0")
.shutdown_timeout(60) // <- Set shutdown timeout to 60 seconds
.start();
let _ = tx.send(addr);
let _ = sys.run();
});
let addr = rx.recv().unwrap();
let _ = addr.send(
server::StopServer{graceful:true}).wait(); // <- Send `StopServer` message to server.
}
```
## Multi-threading
Http server automatically starts an number of http workers, by default
this number is equal to number of logical CPUs in the system. This number
can be overridden with the `HttpServer::threads()` method.
```rust
# extern crate actix_web;
# extern crate tokio_core;
use actix_web::*;
fn main() {
HttpServer::new(
|| Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.threads(4); // <- Start 4 workers
}
```
The server creates a separate application instance for each created worker. Application state
is not shared between threads, to share state `Arc` could be used. Application state
does not need to be `Send` and `Sync` but application factory must be `Send` + `Sync`.
## SSL
There are two features for ssl server: `tls` and `alpn`. The `tls` feature is for `native-tls`
integration and `alpn` is for `openssl`.
```toml
[dependencies]
actix-web = { git = "https://github.com/actix/actix-web", features=["alpn"] }
```
```rust,ignore
use std::fs::File;
use actix_web::*;
fn main() {
let mut file = File::open("identity.pfx").unwrap();
let mut pkcs12 = vec![];
file.read_to_end(&mut pkcs12).unwrap();
let pkcs12 = Pkcs12::from_der(&pkcs12).unwrap().parse("12345").unwrap();
HttpServer::new(
|| Application::new()
.resource("/index.html", |r| r.f(index)))
.bind("127.0.0.1:8080").unwrap()
.serve_ssl(pkcs12).unwrap();
}
```
Note on *HTTP/2.0* protocol over tls without prior knowledge, it requires
[tls alpn](https://tools.ietf.org/html/rfc7301). At the moment only
`openssl` has `alpn ` support.
Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls)
for a full example.
## Keep-Alive
Actix can wait for requests on a keep-alive connection. *Keep alive*
connection behavior is defined by server settings.
* `75` or `Some(75)` or `KeepAlive::Timeout(75)` - enable 75 sec *keep alive* timer according
request and response settings.
* `None` or `KeepAlive::Disabled` - disable *keep alive*.
* `KeepAlive::Tcp(75)` - Use `SO_KEEPALIVE` socket option.
```rust
# extern crate actix_web;
# extern crate tokio_core;
use actix_web::*;
fn main() {
HttpServer::new(||
Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.keep_alive(75); // <- Set keep-alive to 75 seconds
HttpServer::new(||
Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.keep_alive(server::KeepAlive::Tcp(75)); // <- Use `SO_KEEPALIVE` socket option.
HttpServer::new(||
Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.keep_alive(None); // <- Disable keep-alive
}
```
If first option is selected then *keep alive* state is
calculated based on the response's *connection-type*. By default
`HttpResponse::connection_type` is not defined in that case *keep alive*
defined by request's http version. Keep alive is off for *HTTP/1.0*
and is on for *HTTP/1.1* and *HTTP/2.0*.
*Connection type* can be change with `HttpResponseBuilder::connection_type()` method.
```rust
# extern crate actix_web;
use actix_web::{HttpRequest, HttpResponse, http, httpcodes::HttpOk};
fn index(req: HttpRequest) -> HttpResponse {
HttpOk.build()
.connection_type(http::ConnectionType::Close) // <- Close connection
.force_close() // <- Alternative method
.finish().unwrap()
}
# fn main() {}
```
## Graceful shutdown
Actix http server supports graceful shutdown. After receiving a stop signal, workers
have a specific amount of time to finish serving requests. Workers still alive after the
timeout are force-dropped. By default the shutdown timeout is set to 30 seconds.
You can change this parameter with the `HttpServer::shutdown_timeout()` method.
You can send a stop message to the server with the server address and specify if you want
graceful shutdown or not. The `start()` methods return address of the server.
Http server handles several OS signals. *CTRL-C* is available on all OSs,
other signals are available on unix systems.
* *SIGINT* - Force shutdown workers
* *SIGTERM* - Graceful shutdown workers
* *SIGQUIT* - Force shutdown workers
It is possible to disable signal handling with `HttpServer::disable_signals()` method.