diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 71eecbb..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -[package] -name = "actix-website" -version = "0.6.0" -authors = ["Actix Project and Contributors"] -readme = "README.md" -keywords = ["http", "web", "framework", "async", "futures"] -homepage = "https://github.com/actix/actix-website/" -repository = "https://github.com/actix/actix-website.git" -documentation = "https://docs.rs/actix-website/" -categories = ["network-programming", "asynchronous", - "web-programming::http-server", - "web-programming::http-client", - "web-programming::websocket"] -license = "MIT/Apache-2.0" -exclude = [".gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"] - -[lib] -src="src/lib.rs" -crate-type = ["dylib"] - -[dependencies] -actix = "^0.5.6" -actix-web = "^0.6" - -flate2 = "1.0" -serde = "1.0" -serde_json = "1.0" -serde_urlencoded = "0.5" - -# io -bytes = "0.4" -futures = "0.1" -tokio-io = "0.1" -tokio-core = "0.1" -http = "0.1" - -[dev-dependencies] -env_logger = "0.5" -serde_derive = "1.0" - -[build-dependencies] -futures = "0.1" diff --git a/content/docs/server.md b/content/docs/server.md index c37df48..e2a8843 100644 --- a/content/docs/server.md +++ b/content/docs/server.md @@ -21,22 +21,7 @@ To start the http server, one of the start methods. `HttpServer` is an actix actor. It must be initialized within a properly configured actix system: -```rust -use actix_web::{server::HttpServer, App, HttpResponse}; - -fn main() { - let sys = actix::System::new("guide"); - - HttpServer::new(|| { - App::new() - .resource("/", |r| r.f(|_| HttpResponse::Ok())) - }) - .bind("127.0.0.1:59080").unwrap() - .start(); - - let _ = sys.run(); -} -``` +{{< include-example example="server" section="main" >}} > It is possible to start a server in a separate thread with the `run()` method. In that > case the server spawns a new thread and creates a new actix system in it. To stop @@ -50,32 +35,7 @@ address of the started http server. It accepts several messages: - `ResumeServer` - Resume accepting incoming connections - `StopServer` - Stop incoming connection processing, stop all workers and exit -```rust -use std::thread; -use std::sync::mpsc; -use actix_web::{server, App, HttpResponse}; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let sys = actix::System::new("http-server"); - let addr = server::new(|| { - App::new() - .resource("/", |r| r.f(|_| HttpResponse::Ok())) - }) - .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. -} -``` +{{< include-example example="server" file="signals.rs" section="signals" >}} ## Multi-threading @@ -83,17 +43,7 @@ fn main() { this number is equal to number of logical CPUs in the system. This number can be overridden with the `HttpServer::workers()` method. -```rust -use actix_web::{App, HttpResponse, server::HttpServer}; - -fn main() { - HttpServer::new(|| { - App::new() - .resource("/", |r| r.f(|_| HttpResponse::Ok())) - }) - .workers(4); // <- Start 4 workers -} -``` +{{< include-example example="server" file="workers.rs" section="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. @@ -111,24 +61,7 @@ for `native-tls` integration and `alpn` is for `openssl`. actix-web = { version = "{{< actix-version "actix-web" >}}", features = ["alpn"] } ``` -```rust -use std::fs::File; -use actix_web::*; - -fn main() { - // load ssl keys - let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); - builder.set_private_key_file("key.pem", SslFiletype::PEM).unwrap(); - builder.set_certificate_chain_file("cert.pem").unwrap(); - - server::new(|| { - App::new() - .resource("/index.html", |r| r.f(index)) - }) - .bind_ssl("127.0.0.1:8080", builder).unwrap() - .serve(); -} -``` +{{< include-example example="server" file="ssl.rs" section="ssl" >}} > **Note**: the *HTTP/2.0* protocol requires > [tls alpn](https://tools.ietf.org/html/rfc7301). @@ -156,26 +89,7 @@ Actix can wait for requests on a keep-alive connection. - `None` or `KeepAlive::Disabled` - disable *keep alive*. - `KeepAlive::Tcp(75)` - use `SO_KEEPALIVE` socket option. -```rust -use actix_web::{server, App, HttpResponse}; - -fn main() { - server::new(|| - App::new() - .resource("/", |r| r.f(|_| HttpResponse::Ok()))) - .keep_alive(75); // <- Set keep-alive to 75 seconds - - server::new(|| - App::new() - .resource("/", |r| r.f(|_| HttpResponse::Ok()))) - .keep_alive(server::KeepAlive::Tcp(75)); // <- Use `SO_KEEPALIVE` socket option. - - server::new(|| - App::new() - .resource("/", |r| r.f(|_| HttpResponse::Ok()))) - .keep_alive(None); // <- Disable keep-alive -} -``` +{{< include-example example="server" file="ka.rs" section="ka" >}} If the first option is selected, then *keep alive* state is calculated based on the response's *connection-type*. By default @@ -186,16 +100,7 @@ defined by the request's http version. *Connection type* can be change with `HttpResponseBuilder::connection_type()` method. -```rust -use actix_web::{HttpRequest, HttpResponse, http}; - -fn index(req: HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .connection_type(http::ConnectionType::Close) // <- Close connection - .force_close() // <- Alternative method - .finish() -} -``` +{{< include-example example="server" file="ka_tp.rs" section="example" >}} ## Graceful shutdown diff --git a/examples/Cargo.toml b/examples/Cargo.toml index dcc7928..4123f2d 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -2,4 +2,5 @@ members = [ "application", "getting-started", + "server", ] diff --git a/examples/application/Cargo.toml b/examples/application/Cargo.toml index 0349037..9d9824d 100644 --- a/examples/application/Cargo.toml +++ b/examples/application/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "application" -version = "0.1.0" +version = "0.6.0" +workspace = "../" [dependencies] actix-web = "0.6" diff --git a/examples/application/src/main.rs b/examples/application/src/main.rs index 96808a2..17c9235 100644 --- a/examples/application/src/main.rs +++ b/examples/application/src/main.rs @@ -1,16 +1,16 @@ #![allow(unused)] extern crate actix_web; -use actix_web::{App, Responder, HttpRequest, HttpResponse, server, http::Method}; +use actix_web::{http::Method, server, App, HttpRequest, HttpResponse, Responder}; mod state; fn make_app() { -// -fn index(req: HttpRequest) -> impl Responder { - "Hello world!" -} + // + fn index(req: HttpRequest) -> impl Responder { + "Hello world!" + } -let app = App::new() + let app = App::new() .prefix("/app") .resource("/index.html", |r| r.method(Method::GET).f(index)) .finish() @@ -19,18 +19,19 @@ let app = App::new() } fn run_server() { -// -let server = server::new(|| vec![ - App::new() - .prefix("/app1") - .resource("/", |r| r.f(|r| HttpResponse::Ok())), - App::new() - .prefix("/app2") - .resource("/", |r| r.f(|r| HttpResponse::Ok())), - App::new() - .resource("/", |r| r.f(|r| HttpResponse::Ok())), -]); -// + // + let server = server::new(|| { + vec![ + App::new() + .prefix("/app1") + .resource("/", |r| r.f(|r| HttpResponse::Ok())), + App::new() + .prefix("/app2") + .resource("/", |r| r.f(|r| HttpResponse::Ok())), + App::new().resource("/", |r| r.f(|r| HttpResponse::Ok())), + ] + }); + // } fn main() { diff --git a/examples/application/src/state.rs b/examples/application/src/state.rs index 84a5f98..5f89508 100644 --- a/examples/application/src/state.rs +++ b/examples/application/src/state.rs @@ -1,6 +1,6 @@ // +use actix_web::{http, App, HttpRequest}; use std::cell::Cell; -use actix_web::{App, HttpRequest, http}; // This struct represents state struct AppState { @@ -9,51 +9,48 @@ struct AppState { fn index(req: HttpRequest) -> String { let count = req.state().counter.get() + 1; // <- get count - req.state().counter.set(count); // <- store new count in state + req.state().counter.set(count); // <- store new count in state - format!("Request number: {}", count) // <- response with count + format!("Request number: {}", count) // <- response with count } // fn make_app() { - -// -App::with_state(AppState { counter: Cell::new(0) }) + // + App::with_state(AppState { counter: Cell::new(0) }) .resource("/", |r| r.method(http::Method::GET).f(index)) .finish() // ; - } - -use std::thread; use actix_web::{server, HttpResponse}; +use std::thread; fn combine() { -thread::spawn(|| { -// -struct State1; -struct State2; + thread::spawn(|| { + // + struct State1; + struct State2; -fn main() { - server::new(|| { - vec![ - App::with_state(State1) - .prefix("/app1") - .resource("/", |r| r.f(|r| HttpResponse::Ok())) - .boxed(), - App::with_state(State2) - .prefix("/app2") - .resource("/", |r| r.f(|r| HttpResponse::Ok())) - .boxed() - ] - }) - .bind("127.0.0.1:8080").unwrap() - .run() -} -// -}); + fn main() { + server::new(|| { + vec![ + App::with_state(State1) + .prefix("/app1") + .resource("/", |r| r.f(|r| HttpResponse::Ok())) + .boxed(), + App::with_state(State2) + .prefix("/app2") + .resource("/", |r| r.f(|r| HttpResponse::Ok())) + .boxed(), + ] + }).bind("127.0.0.1:8080") + .unwrap() + .run() + } + // + }); } pub fn test() { diff --git a/examples/getting-started/Cargo.toml b/examples/getting-started/Cargo.toml index b7b3d54..1a75d14 100644 --- a/examples/getting-started/Cargo.toml +++ b/examples/getting-started/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "getting-started" -version = "0.1.0" +version = "0.6.0" +workspace = "../" [dependencies] actix-web = "0.6" diff --git a/examples/getting-started/src/main.rs b/examples/getting-started/src/main.rs index 7b96fad..a3e7e09 100644 --- a/examples/getting-started/src/main.rs +++ b/examples/getting-started/src/main.rs @@ -1,6 +1,6 @@ // extern crate actix_web; -use actix_web::{HttpRequest, App, server}; +use actix_web::{server, App, HttpRequest}; fn index(_req: HttpRequest) -> &'static str { "Hello world!" @@ -8,11 +8,9 @@ fn index(_req: HttpRequest) -> &'static str { // //
fn main() { - server::new(|| { - App::new() - .resource("/", |r| r.f(index)) - }) - .bind("127.0.0.1:8088").unwrap() - .run(); + server::new(|| App::new().resource("/", |r| r.f(index))) + .bind("127.0.0.1:8088") + .unwrap() + .run(); } //
diff --git a/examples/rustfmt.toml b/examples/rustfmt.toml new file mode 100644 index 0000000..6db67ed --- /dev/null +++ b/examples/rustfmt.toml @@ -0,0 +1,5 @@ +max_width = 89 +reorder_imports = true +wrap_comments = true +fn_args_density = "Compressed" +#use_small_heuristics = false diff --git a/examples/server/Cargo.toml b/examples/server/Cargo.toml new file mode 100644 index 0000000..1d394c7 --- /dev/null +++ b/examples/server/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "server" +version = "0.6.0" +workspace = "../" + +[dependencies] +actix = "0.5" +actix-web = { version="0.6", features=["alpn"] } +futures = "0.1" +openssl = "0.10" diff --git a/examples/server/src/ka.rs b/examples/server/src/ka.rs new file mode 100644 index 0000000..675110c --- /dev/null +++ b/examples/server/src/ka.rs @@ -0,0 +1,14 @@ +// +use actix_web::{server, App, HttpResponse}; + +fn main() { + server::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok()))) + .keep_alive(75); // <- Set keep-alive to 75 seconds + + server::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok()))) + .keep_alive(server::KeepAlive::Tcp(75)); // <- Use `SO_KEEPALIVE` socket option. + + server::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok()))) + .keep_alive(None); // <- Disable keep-alive +} +// diff --git a/examples/server/src/ka_tp.rs b/examples/server/src/ka_tp.rs new file mode 100644 index 0000000..bb3c0a8 --- /dev/null +++ b/examples/server/src/ka_tp.rs @@ -0,0 +1,10 @@ +// +use actix_web::{http, HttpRequest, HttpResponse}; + +fn index(req: HttpRequest) -> HttpResponse { + HttpResponse::Ok() + .connection_type(http::ConnectionType::Close) // <- Close connection + .force_close() // <- Alternative method + .finish() +} +// diff --git a/examples/server/src/main.rs b/examples/server/src/main.rs new file mode 100644 index 0000000..3006fe2 --- /dev/null +++ b/examples/server/src/main.rs @@ -0,0 +1,25 @@ +extern crate actix; +extern crate actix_web; +extern crate futures; +extern crate openssl; + +mod ka; +mod ka_tp; +mod signals; +mod ssl; +mod workers; + +//
+use actix_web::{server::HttpServer, App, HttpResponse}; + +fn main() { + let sys = actix::System::new("guide"); + + HttpServer::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok()))) + .bind("127.0.0.1:59080") + .unwrap() + .start(); + + let _ = sys.run(); +} +//
diff --git a/examples/server/src/signals.rs b/examples/server/src/signals.rs new file mode 100644 index 0000000..bc0d935 --- /dev/null +++ b/examples/server/src/signals.rs @@ -0,0 +1,28 @@ +use actix; +use futures::Future; + +// +use actix_web::{server, App, HttpResponse}; +use std::sync::mpsc; +use std::thread; + +fn main() { + let (tx, rx) = mpsc::channel(); + + thread::spawn(move || { + let sys = actix::System::new("http-server"); + let addr = server::new(|| { + App::new() + .resource("/", |r| r.f(|_| HttpResponse::Ok())) + }) + .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. +} +// diff --git a/examples/server/src/ssl.rs b/examples/server/src/ssl.rs new file mode 100644 index 0000000..63dfd83 --- /dev/null +++ b/examples/server/src/ssl.rs @@ -0,0 +1,22 @@ +// +use actix_web::{server, App, HttpRequest, Responder}; +use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; + +fn index(req: HttpRequest) -> impl Responder { + "Welcome!" +} + +fn main() { + // load ssl keys + let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + builder + .set_private_key_file("key.pem", SslFiletype::PEM) + .unwrap(); + builder.set_certificate_chain_file("cert.pem").unwrap(); + + server::new(|| App::new().resource("/index.html", |r| r.f(index))) + .bind_ssl("127.0.0.1:8080", builder) + .unwrap() + .run(); +} +// diff --git a/examples/server/src/workers.rs b/examples/server/src/workers.rs new file mode 100644 index 0000000..89cf498 --- /dev/null +++ b/examples/server/src/workers.rs @@ -0,0 +1,8 @@ +// +use actix_web::{server::HttpServer, App, HttpResponse}; + +fn main() { + HttpServer::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok()))) + .workers(4); // <- Start 4 workers +} +// diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 62bee73..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -extern crate http; -extern crate actix; -extern crate actix_web; -extern crate futures; -extern crate tokio_io; -extern crate tokio_core; - -pub fn test() { - println!("test"); -}