1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-24 07:53:00 +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)]
impl<S: 'static> HttpApplication<S> {
pub(crate) fn run(&mut self, req: HttpRequest<S>) -> Reply {
self.inner.borrow_mut().handle(req)
}
#[cfg(test)]
pub(crate) fn prepare_request(&self, req: HttpRequest) -> HttpRequest<S> {
req.with_state(Rc::clone(&self.state), self.router.clone())
}
@ -60,15 +59,12 @@ impl<S: 'static> HttpHandler for HttpApplication<S> {
Err(req)
}
}
fn server_settings(&mut self, settings: ServerSettings) {
self.router.set_server_settings(settings);
}
}
struct ApplicationParts<S> {
state: S,
prefix: String,
settings: ServerSettings,
default: Resource<S>,
resources: HashMap<Pattern, Option<Resource<S>>>,
external: HashMap<String, Pattern>,
@ -89,6 +85,7 @@ impl Application<()> {
parts: Some(ApplicationParts {
state: (),
prefix: "/".to_owned(),
settings: ServerSettings::default(),
default: Resource::default_not_found(),
resources: HashMap::new(),
external: HashMap::new(),
@ -116,6 +113,7 @@ impl<S> Application<S> where S: 'static {
parts: Some(ApplicationParts {
state: state,
prefix: "/".to_owned(),
settings: ServerSettings::default(),
default: Resource::default_not_found(),
resources: HashMap::new(),
external: HashMap::new(),
@ -279,7 +277,7 @@ impl<S> Application<S> where S: 'static {
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(
Inner {
@ -301,7 +299,11 @@ impl<S> Application<S> where S: 'static {
impl<S: 'static> IntoHttpHandler for Application<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()
}
}
@ -309,7 +311,11 @@ impl<S: 'static> IntoHttpHandler for Application<S> {
impl<'a, S: 'static> IntoHttpHandler for &'a mut Application<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()
}
}

View File

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

View File

@ -24,8 +24,9 @@ struct Inner {
impl Router {
/// Create new router
pub fn new<S>(prefix: &str, map: HashMap<Pattern, Option<Resource<S>>>)
-> (Router, Vec<Resource<S>>)
pub fn new<S>(prefix: &str,
settings: ServerSettings,
map: HashMap<Pattern, Option<Resource<S>>>) -> (Router, Vec<Resource<S>>)
{
let prefix = prefix.trim().trim_right_matches('/').to_owned();
let mut named = HashMap::new();
@ -51,14 +52,7 @@ impl Router {
regset: RegexSet::new(&paths).unwrap(),
named: named,
patterns: patterns,
srv: ServerSettings::default() })), 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;
srv: settings })), resources)
}
/// 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 factory = Arc::clone(&self.factory);
let addr = Arbiter::start(move |ctx: &mut Context<_>| {
let mut apps: Vec<_> = (*factory)()
.into_iter().map(|h| h.into_handler()).collect();
for app in &mut apps {
app.server_settings(s.clone());
}
let apps: Vec<_> = (*factory)()
.into_iter()
.map(|h| h.into_handler(s.clone())).collect();
ctx.add_stream(rx);
Worker::new(apps, h, ka)
});
@ -482,10 +480,9 @@ impl<T, A, H, U, V> HttpServer<T, A, H, U>
// set server settings
let addr: net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let settings = ServerSettings::new(Some(addr), &self.host, secure);
let mut apps: Vec<_> = (*self.factory)().into_iter().map(|h| h.into_handler()).collect();
for app in &mut apps {
app.server_settings(settings.clone());
}
let apps: Vec<_> = (*self.factory)()
.into_iter()
.map(|h| h.into_handler(settings.clone())).collect();
self.h = Some(Rc::new(WorkerSettings::new(apps, self.keep_alive)));
// start server

View File

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