From e9aa67b75d8bb9c999032ea58fcc647c4ceccca7 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Tue, 12 Dec 2017 07:40:36 -0800 Subject: [PATCH] http server accepts factory of HttpHandlers --- examples/basic.rs | 2 +- examples/state.rs | 3 ++- examples/websocket.rs | 2 +- guide/src/qs_2.md | 6 +++--- guide/src/qs_3.md | 2 +- guide/src/qs_4.md | 2 +- src/application.rs | 22 +++++++++++----------- src/server.rs | 7 ++++--- tests/test_server.rs | 19 ++++++++++--------- 9 files changed, 34 insertions(+), 31 deletions(-) diff --git a/examples/basic.rs b/examples/basic.rs index 53dda877..304eabd2 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -57,7 +57,7 @@ fn main() { let sys = actix::System::new("ws-example"); HttpServer::new( - Application::new() + || Application::new() // enable logger .middleware(middlewares::Logger::default()) // cookie session middleware diff --git a/examples/state.rs b/examples/state.rs index 8d489dcf..aef09fc2 100644 --- a/examples/state.rs +++ b/examples/state.rs @@ -54,13 +54,14 @@ impl Handler for MyWebSocket { } } + fn main() { ::std::env::set_var("RUST_LOG", "actix_web=info"); let _ = env_logger::init(); let sys = actix::System::new("ws-example"); HttpServer::new( - Application::with_state(AppState{counter: Cell::new(0)}) + || Application::with_state(AppState{counter: Cell::new(0)}) // enable logger .middleware(middlewares::Logger::default()) // websocket route diff --git a/examples/websocket.rs b/examples/websocket.rs index cb644753..cbcf91c1 100644 --- a/examples/websocket.rs +++ b/examples/websocket.rs @@ -61,7 +61,7 @@ fn main() { let sys = actix::System::new("ws-example"); HttpServer::new( - Application::new() + || Application::new() // enable logger .middleware(middlewares::Logger::default()) // websocket route diff --git a/guide/src/qs_2.md b/guide/src/qs_2.md index 719f24cc..1b28892e 100644 --- a/guide/src/qs_2.md +++ b/guide/src/qs_2.md @@ -55,10 +55,10 @@ request handler with the application's `resource` on a particular *HTTP method* ``` After that, application instance can be used with `HttpServer` to listen for incoming -connections: +connections. Server accepts function that should return `HttpHandler` instance: ```rust,ignore - HttpServer::new(app).serve::<_, ()>("127.0.0.1:8088"); + HttpServer::new(|| app).serve::<_, ()>("127.0.0.1:8088"); ``` That's it. Now, compile and run the program with cargo run. @@ -79,7 +79,7 @@ fn main() { let sys = actix::System::new("example"); HttpServer::new( - Application::new() + || Application::new() .resource("/", |r| r.f(index))) .serve::<_, ()>("127.0.0.1:8088").unwrap(); diff --git a/guide/src/qs_3.md b/guide/src/qs_3.md index d826998c..b6a83cf1 100644 --- a/guide/src/qs_3.md +++ b/guide/src/qs_3.md @@ -42,7 +42,7 @@ Multiple applications could be served with one server: use actix_web::*; fn main() { - HttpServer::::new(vec![ + HttpServer::::new(|| vec![ Application::new() .prefix("/app1") .resource("/", |r| r.f(|r| httpcodes::HTTPOk)), diff --git a/guide/src/qs_4.md b/guide/src/qs_4.md index 354cac12..addb1541 100644 --- a/guide/src/qs_4.md +++ b/guide/src/qs_4.md @@ -81,7 +81,7 @@ fn main() { let sys = actix::System::new("example"); HttpServer::new( - Application::new() + || Application::new() .resource("/", |r| r.method(Method::GET).f(index))) .serve::<_, ()>("127.0.0.1:8088").unwrap(); diff --git a/src/application.rs b/src/application.rs index 9da145f0..d5118799 100644 --- a/src/application.rs +++ b/src/application.rs @@ -19,7 +19,7 @@ pub struct HttpApplication { middlewares: Rc>>>, } -impl HttpApplication { +impl HttpApplication { pub(crate) fn prepare_request(&self, req: HttpRequest) -> HttpRequest { req.with_state(Rc::clone(&self.state), self.router.clone()) @@ -34,7 +34,7 @@ impl HttpApplication { } } -impl HttpHandler for HttpApplication { +impl HttpHandler for HttpApplication { fn handle(&self, req: HttpRequest) -> Result, HttpRequest> { if req.path().starts_with(&self.prefix) { @@ -89,7 +89,7 @@ impl Default for Application<()> { } } -impl Application where S: 'static { +impl Application where S: Send + 'static { /// Create application with specific state. Application can be /// configured with builder-like pattern. @@ -133,7 +133,7 @@ impl Application where S: 'static { /// .finish(); /// } /// ``` - pub fn prefix>(&mut self, prefix: P) -> &mut Self { + pub fn prefix>(mut self, prefix: P) -> Application { { let parts = self.parts.as_mut().expect("Use after finish"); let mut prefix = prefix.into(); @@ -176,7 +176,7 @@ impl Application where S: 'static { /// .finish(); /// } /// ``` - pub fn resource(&mut self, path: &str, f: F) -> &mut Self + pub fn resource(mut self, path: &str, f: F) -> Application where F: FnOnce(&mut Resource) + 'static { { @@ -197,7 +197,7 @@ impl Application where S: 'static { } /// Default resource is used if no matched route could be found. - pub fn default_resource(&mut self, f: F) -> &mut Self + pub fn default_resource(mut self, f: F) -> Application where F: FnOnce(&mut Resource) + 'static { { @@ -230,7 +230,7 @@ impl Application where S: 'static { /// .finish(); /// } /// ``` - pub fn external_resource(&mut self, name: T, url: U) -> &mut Self + pub fn external_resource(mut self, name: T, url: U) -> Application where T: AsRef, U: AsRef { { @@ -246,7 +246,7 @@ impl Application where S: 'static { } /// Register a middleware - pub fn middleware(&mut self, mw: T) -> &mut Self + pub fn middleware(mut self, mw: T) -> Application where T: Middleware + 'static { self.parts.as_mut().expect("Use after finish") @@ -274,7 +274,7 @@ impl Application where S: 'static { } } -impl IntoHttpHandler for Application { +impl IntoHttpHandler for Application { type Handler = HttpApplication; fn into_handler(mut self) -> HttpApplication { @@ -282,7 +282,7 @@ impl IntoHttpHandler for Application { } } -impl<'a, S: 'static> IntoHttpHandler for &'a mut Application { +impl<'a, S: Send + 'static> IntoHttpHandler for &'a mut Application { type Handler = HttpApplication; fn into_handler(self) -> HttpApplication { @@ -291,7 +291,7 @@ impl<'a, S: 'static> IntoHttpHandler for &'a mut Application { } #[doc(hidden)] -impl Iterator for Application { +impl Iterator for Application { type Item = HttpApplication; fn next(&mut self) -> Option { diff --git a/src/server.rs b/src/server.rs index 98e60242..a5862c34 100644 --- a/src/server.rs +++ b/src/server.rs @@ -95,10 +95,11 @@ impl Actor for HttpServer { impl HttpServer where H: HttpHandler { /// Create new http server with vec of http handlers - pub fn new>(handler: U) -> Self - where V: IntoHttpHandler + pub fn new>(factory: F) -> Self + where F: Fn() -> U + Send, + V: IntoHttpHandler { - let apps: Vec<_> = handler.into_iter().map(|h| h.into_handler()).collect(); + let apps: Vec<_> = factory().into_iter().map(|h| h.into_handler()).collect(); HttpServer{ h: Rc::new(apps), io: PhantomData, diff --git a/tests/test_server.rs b/tests/test_server.rs index 35a3d76c..4a657bcc 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -4,6 +4,7 @@ extern crate tokio_core; extern crate reqwest; use std::{net, thread}; +use std::rc::Rc; use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; use tokio_core::net::TcpListener; @@ -16,8 +17,8 @@ fn test_serve() { thread::spawn(|| { let sys = System::new("test"); let srv = HttpServer::new( - vec![Application::new() - .resource("/", |r| r.method(Method::GET).h(httpcodes::HTTPOk))]); + || vec![Application::new() + .resource("/", |r| r.method(Method::GET).h(httpcodes::HTTPOk))]); srv.serve::<_, ()>("127.0.0.1:58902").unwrap(); sys.run(); }); @@ -36,7 +37,7 @@ fn test_serve_incoming() { let sys = System::new("test"); let srv = HttpServer::new( - Application::new() + || Application::new() .resource("/", |r| r.method(Method::GET).h(httpcodes::HTTPOk))); let tcp = TcpListener::from_listener(tcp, &addr2, Arbiter::handle()).unwrap(); srv.serve_incoming::<_, ()>(tcp.incoming(), false).unwrap(); @@ -51,6 +52,7 @@ struct MiddlewareTest { start: Arc, response: Arc, finish: Arc, + test: Rc, } impl middlewares::Middleware for MiddlewareTest { @@ -84,12 +86,11 @@ fn test_middlewares() { let sys = System::new("test"); HttpServer::new( - vec![Application::new() - .middleware(MiddlewareTest{start: act_num1, - response: act_num2, - finish: act_num3}) - .resource("/", |r| r.method(Method::GET).h(httpcodes::HTTPOk)) - .finish()]) + move || vec![Application::new() + .middleware(MiddlewareTest{start: act_num1.clone(), + response: act_num2.clone(), + finish: act_num3.clone(), test: Rc::new(1)}) + .resource("/", |r| r.method(Method::GET).h(httpcodes::HTTPOk))]) .serve::<_, ()>("127.0.0.1:58904").unwrap(); sys.run(); });