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

refactor IntoHttpHandler trait

This commit is contained in:
Nikolay Kim 2017-12-29 11:33:04 -08:00
parent 1d195a2cf2
commit 3d3e4dae9a
5 changed files with 31 additions and 37 deletions

View File

@ -37,12 +37,11 @@ impl<S: 'static> PipelineHandler<S> for Inner<S> {
} }
} }
impl<S: 'static> HttpApplication<S> {
#[cfg(test)] #[cfg(test)]
impl<S: 'static> HttpApplication<S> {
pub(crate) fn run(&mut self, req: HttpRequest<S>) -> Reply { pub(crate) fn run(&mut self, req: HttpRequest<S>) -> Reply {
self.inner.borrow_mut().handle(req) self.inner.borrow_mut().handle(req)
} }
#[cfg(test)]
pub(crate) fn prepare_request(&self, req: HttpRequest) -> HttpRequest<S> { pub(crate) fn prepare_request(&self, req: HttpRequest) -> HttpRequest<S> {
req.with_state(Rc::clone(&self.state), self.router.clone()) req.with_state(Rc::clone(&self.state), self.router.clone())
} }
@ -60,15 +59,12 @@ impl<S: 'static> HttpHandler for HttpApplication<S> {
Err(req) Err(req)
} }
} }
fn server_settings(&mut self, settings: ServerSettings) {
self.router.set_server_settings(settings);
}
} }
struct ApplicationParts<S> { struct ApplicationParts<S> {
state: S, state: S,
prefix: String, prefix: String,
settings: ServerSettings,
default: Resource<S>, default: Resource<S>,
resources: HashMap<Pattern, Option<Resource<S>>>, resources: HashMap<Pattern, Option<Resource<S>>>,
external: HashMap<String, Pattern>, external: HashMap<String, Pattern>,
@ -89,6 +85,7 @@ impl Application<()> {
parts: Some(ApplicationParts { parts: Some(ApplicationParts {
state: (), state: (),
prefix: "/".to_owned(), prefix: "/".to_owned(),
settings: ServerSettings::default(),
default: Resource::default_not_found(), default: Resource::default_not_found(),
resources: HashMap::new(), resources: HashMap::new(),
external: HashMap::new(), external: HashMap::new(),
@ -116,6 +113,7 @@ impl<S> Application<S> where S: 'static {
parts: Some(ApplicationParts { parts: Some(ApplicationParts {
state: state, state: state,
prefix: "/".to_owned(), prefix: "/".to_owned(),
settings: ServerSettings::default(),
default: Resource::default_not_found(), default: Resource::default_not_found(),
resources: HashMap::new(), resources: HashMap::new(),
external: HashMap::new(), external: HashMap::new(),
@ -279,7 +277,7 @@ impl<S> Application<S> where S: 'static {
resources.insert(pattern, None); resources.insert(pattern, None);
} }
let (router, resources) = Router::new(prefix, resources); let (router, resources) = Router::new(prefix, parts.settings, resources);
let inner = Rc::new(RefCell::new( let inner = Rc::new(RefCell::new(
Inner { Inner {
@ -301,7 +299,11 @@ impl<S> Application<S> where S: 'static {
impl<S: 'static> IntoHttpHandler for Application<S> { impl<S: 'static> IntoHttpHandler for Application<S> {
type Handler = HttpApplication<S>; type Handler = HttpApplication<S>;
fn into_handler(mut self) -> HttpApplication<S> { fn into_handler(mut self, settings: ServerSettings) -> HttpApplication<S> {
{
let parts = self.parts.as_mut().expect("Use after finish");
parts.settings = settings;
}
self.finish() self.finish()
} }
} }
@ -309,7 +311,11 @@ impl<S: 'static> IntoHttpHandler for Application<S> {
impl<'a, S: 'static> IntoHttpHandler for &'a mut Application<S> { impl<'a, S: 'static> IntoHttpHandler for &'a mut Application<S> {
type Handler = HttpApplication<S>; type Handler = HttpApplication<S>;
fn into_handler(self) -> HttpApplication<S> { fn into_handler(self, settings: ServerSettings) -> HttpApplication<S> {
{
let parts = self.parts.as_mut().expect("Use after finish");
parts.settings = settings;
}
self.finish() self.finish()
} }
} }

View File

@ -19,9 +19,6 @@ pub trait HttpHandler: 'static {
/// Handle request /// Handle request
fn handle(&mut self, req: HttpRequest) -> Result<Box<HttpHandlerTask>, HttpRequest>; fn handle(&mut self, req: HttpRequest) -> Result<Box<HttpHandlerTask>, HttpRequest>;
/// Set server settings
fn server_settings(&mut self, settings: ServerSettings) {}
} }
pub trait HttpHandlerTask { pub trait HttpHandlerTask {
@ -39,13 +36,13 @@ pub trait IntoHttpHandler {
type Handler: HttpHandler; type Handler: HttpHandler;
/// Convert into `HttpHandler` object. /// Convert into `HttpHandler` object.
fn into_handler(self) -> Self::Handler; fn into_handler(self, settings: ServerSettings) -> Self::Handler;
} }
impl<T: HttpHandler> IntoHttpHandler for T { impl<T: HttpHandler> IntoHttpHandler for T {
type Handler = T; type Handler = T;
fn into_handler(self) -> Self::Handler { fn into_handler(self, _: ServerSettings) -> Self::Handler {
self self
} }
} }

View File

@ -24,8 +24,9 @@ struct Inner {
impl Router { impl Router {
/// Create new router /// Create new router
pub fn new<S>(prefix: &str, map: HashMap<Pattern, Option<Resource<S>>>) pub fn new<S>(prefix: &str,
-> (Router, Vec<Resource<S>>) settings: ServerSettings,
map: HashMap<Pattern, Option<Resource<S>>>) -> (Router, Vec<Resource<S>>)
{ {
let prefix = prefix.trim().trim_right_matches('/').to_owned(); let prefix = prefix.trim().trim_right_matches('/').to_owned();
let mut named = HashMap::new(); let mut named = HashMap::new();
@ -51,14 +52,7 @@ impl Router {
regset: RegexSet::new(&paths).unwrap(), regset: RegexSet::new(&paths).unwrap(),
named: named, named: named,
patterns: patterns, patterns: patterns,
srv: ServerSettings::default() })), resources) srv: settings })), resources)
}
#[allow(mutable_transmutes)]
pub(crate) fn set_server_settings(&mut self, settings: ServerSettings) {
let inner: &Inner = self.0.as_ref();
let inner: &mut Inner = unsafe{mem::transmute(inner)};
inner.srv = settings;
} }
/// Router prefix /// Router prefix

View File

@ -268,11 +268,9 @@ impl<T, A, H, U, V> HttpServer<T, A, H, U>
let ka = self.keep_alive; let ka = self.keep_alive;
let factory = Arc::clone(&self.factory); let factory = Arc::clone(&self.factory);
let addr = Arbiter::start(move |ctx: &mut Context<_>| { let addr = Arbiter::start(move |ctx: &mut Context<_>| {
let mut apps: Vec<_> = (*factory)() let apps: Vec<_> = (*factory)()
.into_iter().map(|h| h.into_handler()).collect(); .into_iter()
for app in &mut apps { .map(|h| h.into_handler(s.clone())).collect();
app.server_settings(s.clone());
}
ctx.add_stream(rx); ctx.add_stream(rx);
Worker::new(apps, h, ka) Worker::new(apps, h, ka)
}); });
@ -482,10 +480,9 @@ impl<T, A, H, U, V> HttpServer<T, A, H, U>
// set server settings // set server settings
let addr: net::SocketAddr = "127.0.0.1:8080".parse().unwrap(); let addr: net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let settings = ServerSettings::new(Some(addr), &self.host, secure); let settings = ServerSettings::new(Some(addr), &self.host, secure);
let mut apps: Vec<_> = (*self.factory)().into_iter().map(|h| h.into_handler()).collect(); let apps: Vec<_> = (*self.factory)()
for app in &mut apps { .into_iter()
app.server_settings(settings.clone()); .map(|h| h.into_handler(settings.clone())).collect();
}
self.h = Some(Rc::new(WorkerSettings::new(apps, self.keep_alive))); self.h = Some(Rc::new(WorkerSettings::new(apps, self.keep_alive)));
// start server // start server

View File

@ -16,7 +16,7 @@ use tokio_core::reactor::Core;
use net2::TcpBuilder; use net2::TcpBuilder;
use error::Error; use error::Error;
use server::HttpServer; use server::{HttpServer, ServerSettings};
use handler::{Handler, Responder, ReplyItem}; use handler::{Handler, Responder, ReplyItem};
use channel::{HttpHandler, IntoHttpHandler}; use channel::{HttpHandler, IntoHttpHandler};
use middleware::Middleware; use middleware::Middleware;
@ -199,8 +199,8 @@ impl<S: 'static> TestApp<S> {
impl<S: 'static> IntoHttpHandler for TestApp<S> { impl<S: 'static> IntoHttpHandler for TestApp<S> {
type Handler = HttpApplication<S>; type Handler = HttpApplication<S>;
fn into_handler(self) -> HttpApplication<S> { fn into_handler(mut self, settings: ServerSettings) -> HttpApplication<S> {
self.app.unwrap().finish() self.app.take().unwrap().into_handler(settings)
} }
} }
@ -347,7 +347,7 @@ impl<S> TestRequest<S> {
let req = HttpRequest::new(method, uri, version, headers, payload); let req = HttpRequest::new(method, uri, version, headers, payload);
req.as_mut().cookies = cookies; req.as_mut().cookies = cookies;
req.as_mut().params = params; req.as_mut().params = params;
let (router, _) = Router::new::<S>("/", HashMap::new()); let (router, _) = Router::new::<S>("/", ServerSettings::default(), HashMap::new());
req.with_state(Rc::new(state), router) req.with_state(Rc::new(state), router)
} }