diff --git a/README.md b/README.md
index ccd49e9fc..46f589d6f 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Actix web [![Build Status](https://travis-ci.org/actix/actix-web.svg?branch=master)](https://travis-ci.org/actix/actix-web) [![Build status](https://ci.appveyor.com/api/projects/status/kkdb4yce7qhm5w85/branch/master?svg=true)](https://ci.appveyor.com/project/fafhrd91/actix-web-hdy9d/branch/master) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) [![crates.io](http://meritbadge.herokuapp.com/actix-web)](https://crates.io/crates/actix-web) [![Join the chat at https://gitter.im/actix/actix](https://badges.gitter.im/actix/actix.svg)](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+# Actix web [![Build Status](https://travis-ci.org/actix/actix-web.svg?branch=master)](https://travis-ci.org/actix/actix-web) [![Build status](https://ci.appveyor.com/api/projects/status/kkdb4yce7qhm5w85/branch/master?svg=true)](https://ci.appveyor.com/project/fafhrd91/actix-web-hdy9d/branch/master) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) [![crates.io](https://meritbadge.herokuapp.com/actix-web)](https://crates.io/crates/actix-web) [![Join the chat at https://gitter.im/actix/actix](https://badges.gitter.im/actix/actix.svg)](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 
 Actix web is a simple, pragmatic, extremely fast, web framework for Rust.
 
diff --git a/src/application.rs b/src/application.rs
index cf58cc971..38886efc5 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -1,6 +1,6 @@
 use std::mem;
 use std::rc::Rc;
-use std::cell::RefCell;
+use std::cell::UnsafeCell;
 use std::collections::HashMap;
 
 use handler::Reply;
@@ -9,7 +9,7 @@ use resource::{ResourceHandler};
 use header::ContentEncoding;
 use handler::{Handler, RouteHandler, WrapHandler};
 use httprequest::HttpRequest;
-use pipeline::{Pipeline, PipelineHandler};
+use pipeline::{Pipeline, PipelineHandler, HandlerType};
 use middleware::Middleware;
 use server::{HttpHandler, IntoHttpHandler, HttpHandlerTask, ServerSettings};
 
@@ -21,7 +21,7 @@ pub struct HttpApplication<S=()> {
     state: Rc<S>,
     prefix: String,
     router: Router,
-    inner: Rc<RefCell<Inner<S>>>,
+    inner: Rc<UnsafeCell<Inner<S>>>,
     middlewares: Rc<Vec<Box<Middleware<S>>>>,
 }
 
@@ -29,7 +29,6 @@ pub(crate) struct Inner<S> {
     prefix: usize,
     default: ResourceHandler<S>,
     encoding: ContentEncoding,
-    router: Router,
     resources: Vec<ResourceHandler<S>>,
     handlers: Vec<(String, Box<RouteHandler<S>>)>,
 }
@@ -40,39 +39,60 @@ impl<S: 'static> PipelineHandler<S> for Inner<S> {
         self.encoding
     }
 
-    fn handle(&mut self, mut req: HttpRequest<S>) -> Reply {
-        if let Some(idx) = self.router.recognize(&mut req) {
-            self.resources[idx].handle(req.clone(), Some(&mut self.default))
+    fn handle(&mut self, req: HttpRequest<S>, htype: HandlerType) -> Reply {
+        match htype {
+            HandlerType::Normal(idx) =>
+                self.resources[idx].handle(req, Some(&mut self.default)),
+            HandlerType::Handler(idx) =>
+                self.handlers[idx].1.handle(req),
+            HandlerType::Default =>
+                self.default.handle(req, None)
+        }
+    }
+}
+
+impl<S: 'static> HttpApplication<S> {
+
+    #[inline]
+    fn as_ref(&self) -> &Inner<S> {
+        unsafe{&*self.inner.get()}
+    }
+
+    #[inline]
+    fn get_handler(&self, req: &mut HttpRequest<S>) -> HandlerType {
+        if let Some(idx) = self.router.recognize(req) {
+            HandlerType::Normal(idx)
         } else {
-            for &mut (ref prefix, ref mut handler) in &mut self.handlers {
+            let inner = self.as_ref();
+            for idx in 0..inner.handlers.len() {
+                let &(ref prefix, _) = &inner.handlers[idx];
                 let m = {
-                    let path = &req.path()[self.prefix..];
+                    let path = &req.path()[inner.prefix..];
                     path.starts_with(prefix) && (
                         path.len() == prefix.len() ||
                             path.split_at(prefix.len()).1.starts_with('/'))
                 };
                 if m {
                     let path: &'static str = unsafe {
-                        mem::transmute(&req.path()[self.prefix+prefix.len()..]) };
+                        mem::transmute(&req.path()[inner.prefix+prefix.len()..]) };
                     if path.is_empty() {
                         req.match_info_mut().add("tail", "");
                     } else {
                         req.match_info_mut().add("tail", path.split_at(1).1);
                     }
-                    return handler.handle(req)
+                    return HandlerType::Handler(idx)
                 }
             }
-            self.default.handle(req, None)
+            HandlerType::Default
         }
     }
-}
 
-#[cfg(test)]
-impl<S: 'static> HttpApplication<S> {
     #[cfg(test)]
-    pub(crate) fn run(&mut self, req: HttpRequest<S>) -> Reply {
-        self.inner.borrow_mut().handle(req)
+    pub(crate) fn run(&mut self, mut req: HttpRequest<S>) -> Reply {
+        let tp = self.get_handler(&mut req);
+        unsafe{&mut *self.inner.get()}.handle(req, tp)
     }
+
     #[cfg(test)]
     pub(crate) fn prepare_request(&self, req: HttpRequest) -> HttpRequest<S> {
         req.with_state(Rc::clone(&self.state), self.router.clone())
@@ -89,10 +109,10 @@ impl<S: 'static> HttpHandler for HttpApplication<S> {
                     path.split_at(self.prefix.len()).1.starts_with('/'))
         };
         if m {
+            let mut req = req.with_state(Rc::clone(&self.state), self.router.clone());
+            let tp = self.get_handler(&mut req);
             let inner = Rc::clone(&self.inner);
-            let req = req.with_state(Rc::clone(&self.state), self.router.clone());
-
-            Ok(Box::new(Pipeline::new(req, Rc::clone(&self.middlewares), inner)))
+            Ok(Box::new(Pipeline::new(req, Rc::clone(&self.middlewares), inner, tp)))
         } else {
             Err(req)
         }
@@ -392,12 +412,11 @@ impl<S> App<S> where S: 'static {
 
         let (router, resources) = Router::new(prefix, parts.settings, resources);
 
-        let inner = Rc::new(RefCell::new(
+        let inner = Rc::new(UnsafeCell::new(
             Inner {
                 prefix: prefix.len(),
                 default: parts.default,
                 encoding: parts.encoding,
-                router: router.clone(),
                 handlers: parts.handlers,
                 resources,
             }
diff --git a/src/httprequest.rs b/src/httprequest.rs
index 16dea0c8b..00aacb810 100644
--- a/src/httprequest.rs
+++ b/src/httprequest.rs
@@ -39,7 +39,13 @@ pub struct HttpInnerMessage {
     pub addr: Option<SocketAddr>,
     pub payload: Option<Payload>,
     pub info: Option<ConnectionInfo<'static>>,
-    pub resource: i16,
+    resource: RouterResource,
+}
+
+#[derive(Debug, Copy, Clone,PartialEq)]
+enum RouterResource {
+    Notset,
+    Normal(u16),
 }
 
 impl Default for HttpInnerMessage {
@@ -58,7 +64,7 @@ impl Default for HttpInnerMessage {
             payload: None,
             extensions: Extensions::new(),
             info: None,
-            resource: -1,
+            resource: RouterResource::Notset,
         }
     }
 }
@@ -95,12 +101,12 @@ impl HttpInnerMessage {
         self.addr = None;
         self.info = None;
         self.payload = None;
-        self.resource = -1;
+        self.resource = RouterResource::Notset;
     }
 }
 
 lazy_static!{
-    static ref RESOURCE: Resource = Resource::default();
+    static ref RESOURCE: Resource = Resource::unset();
 }
 
 
@@ -128,7 +134,7 @@ impl HttpRequest<()> {
                 addr: None,
                 extensions: Extensions::new(),
                 info: None,
-                resource: -1,
+                resource: RouterResource::Notset,
             }),
             None,
             None,
@@ -330,17 +336,16 @@ impl<S> HttpRequest<S> {
     /// This method returns reference to matched `Resource` object.
     #[inline]
     pub fn resource(&self) -> &Resource {
-        let idx = self.as_ref().resource;
-        if idx >= 0 {
-            if let Some(ref router) = self.2 {
+        if let Some(ref router) = self.2 {
+            if let RouterResource::Normal(idx) = self.as_ref().resource {
                 return router.get_resource(idx as usize)
             }
         }
         &*RESOURCE
     }
 
-    pub(crate) fn set_resource(&mut self, idx: usize) {
-        self.as_mut().resource = idx as i16;
+    pub(crate) fn set_resource(&mut self, res: usize) {
+        self.as_mut().resource = RouterResource::Normal(res as u16);
     }
 
     /// Peer socket address
diff --git a/src/pipeline.rs b/src/pipeline.rs
index d8a5dcfb2..842d519ab 100644
--- a/src/pipeline.rs
+++ b/src/pipeline.rs
@@ -1,6 +1,6 @@
 use std::{io, mem};
 use std::rc::Rc;
-use std::cell::RefCell;
+use std::cell::UnsafeCell;
 use std::marker::PhantomData;
 
 use log::Level::Debug;
@@ -18,11 +18,18 @@ use middleware::{Middleware, Finished, Started, Response};
 use application::Inner;
 use server::{Writer, WriterState, HttpHandlerTask};
 
+#[derive(Debug, Clone, Copy)]
+pub(crate) enum HandlerType {
+    Normal(usize),
+    Handler(usize),
+    Default,
+}
+
 pub(crate) trait PipelineHandler<S> {
 
     fn encoding(&self) -> ContentEncoding;
 
-    fn handle(&mut self, req: HttpRequest<S>) -> Reply;
+    fn handle(&mut self, req: HttpRequest<S>, htype: HandlerType) -> Reply;
 }
 
 pub(crate) struct Pipeline<S, H>(PipelineInfo<S>, PipelineState<S, H>);
@@ -105,7 +112,7 @@ impl<S: 'static, H: PipelineHandler<S>> Pipeline<S, H> {
 
     pub fn new(req: HttpRequest<S>,
                mws: Rc<Vec<Box<Middleware<S>>>>,
-               handler: Rc<RefCell<H>>) -> Pipeline<S, H>
+               handler: Rc<UnsafeCell<H>>, htype: HandlerType) -> Pipeline<S, H>
     {
         let mut info = PipelineInfo {
             req, mws,
@@ -113,9 +120,9 @@ impl<S: 'static, H: PipelineHandler<S>> Pipeline<S, H> {
             error: None,
             context: None,
             disconnected: None,
-            encoding: handler.borrow().encoding(),
+            encoding: unsafe{&*handler.get()}.encoding(),
         };
-        let state = StartMiddlewares::init(&mut info, handler);
+        let state = StartMiddlewares::init(&mut info, handler, htype);
 
         Pipeline(info, state)
     }
@@ -209,20 +216,23 @@ type Fut = Box<Future<Item=Option<HttpResponse>, Error=Error>>;
 
 /// Middlewares start executor
 struct StartMiddlewares<S, H> {
-    hnd: Rc<RefCell<H>>,
+    hnd: Rc<UnsafeCell<H>>,
+    htype: HandlerType,
     fut: Option<Fut>,
     _s: PhantomData<S>,
 }
 
 impl<S: 'static, H: PipelineHandler<S>> StartMiddlewares<S, H> {
 
-    fn init(info: &mut PipelineInfo<S>, handler: Rc<RefCell<H>>) -> PipelineState<S, H> {
+    fn init(info: &mut PipelineInfo<S>, hnd: Rc<UnsafeCell<H>>, htype: HandlerType)
+            -> PipelineState<S, H>
+    {
         // execute middlewares, we need this stage because middlewares could be non-async
         // and we can move to next state immediately
         let len = info.mws.len() as u16;
         loop {
             if info.count == len {
-                let reply = handler.borrow_mut().handle(info.req.clone());
+                let reply = unsafe{&mut *hnd.get()}.handle(info.req.clone(), htype);
                 return WaitingResponse::init(info, reply)
             } else {
                 match info.mws[info.count as usize].start(&mut info.req) {
@@ -234,7 +244,7 @@ impl<S: 'static, H: PipelineHandler<S>> StartMiddlewares<S, H> {
                         match fut.poll() {
                             Ok(Async::NotReady) =>
                                 return PipelineState::Starting(StartMiddlewares {
-                                    hnd: handler,
+                                    hnd, htype,
                                     fut: Some(fut),
                                     _s: PhantomData}),
                             Ok(Async::Ready(resp)) => {
@@ -264,7 +274,8 @@ impl<S: 'static, H: PipelineHandler<S>> StartMiddlewares<S, H> {
                         return Some(RunMiddlewares::init(info, resp));
                     }
                     if info.count == len {
-                        let reply = (*self.hnd.borrow_mut()).handle(info.req.clone());
+                        let reply = unsafe{
+                            &mut *self.hnd.get()}.handle(info.req.clone(), self.htype);
                         return Some(WaitingResponse::init(info, reply));
                     } else {
                         loop {
diff --git a/src/router.rs b/src/router.rs
index 050520b20..b8e6baf00 100644
--- a/src/router.rs
+++ b/src/router.rs
@@ -12,7 +12,6 @@ use resource::ResourceHandler;
 use httprequest::HttpRequest;
 use server::ServerSettings;
 
-
 /// Interface for application router.
 pub struct Router(Rc<Inner>);
 
@@ -68,7 +67,7 @@ impl Router {
     pub(crate) fn get_resource(&self, idx: usize) -> &Resource {
         &self.0.patterns[idx]
     }
-    
+
     /// Query for matched resource
     pub fn recognize<S>(&self, req: &mut HttpRequest<S>) -> Option<usize> {
         if self.0.prefix_len > req.path().len() {
@@ -127,7 +126,6 @@ impl Clone for Router {
     }
 }
 
-
 #[derive(Debug, Clone, PartialEq)]
 enum PatternElement {
     Str(String),
@@ -140,26 +138,27 @@ enum PatternType {
     Dynamic(Regex, Vec<String>),
 }
 
+#[derive(Debug, Copy, Clone, PartialEq)]
+/// Resource type
+pub enum ResourceType {
+    /// Normal resource
+    Normal,
+    /// Resource for applicaiton default handler
+    Default,
+    /// External resource
+    External,
+    /// Unknown resource type
+    Unset,
+}
+
 /// Reslource type describes an entry in resources table
 #[derive(Clone)]
 pub struct Resource {
     tp: PatternType,
+    rtp: ResourceType,
     name: String,
     pattern: String,
     elements: Vec<PatternElement>,
-    external: bool,
-}
-
-impl Default for Resource {
-    fn default() -> Resource {
-        Resource {
-            tp: PatternType::Static("".to_owned()),
-            name: "".to_owned(),
-            pattern: "".to_owned(),
-            elements: Vec::new(),
-            external: false,
-        }
-    }
 }
 
 impl Resource {
@@ -175,10 +174,21 @@ impl Resource {
     /// Panics if path pattern is wrong.
     pub fn external(name: &str, path: &str) -> Self {
         let mut resource = Resource::with_prefix(name, path, "/");
-        resource.external = true;
+        resource.rtp = ResourceType::External;
         resource
     }
 
+    /// Unset resource type
+    pub(crate) fn unset() -> Resource {
+        Resource {
+            tp: PatternType::Static("".to_owned()),
+            rtp: ResourceType::Unset,
+            name: "".to_owned(),
+            pattern: "".to_owned(),
+            elements: Vec::new(),
+        }
+    }
+
     /// Parse path pattern and create new `Resource` instance with custom prefix
     pub fn with_prefix(name: &str, path: &str, prefix: &str) -> Self {
         let (pattern, elements, is_dynamic) = Resource::parse(path, prefix);
@@ -200,8 +210,8 @@ impl Resource {
             tp,
             elements,
             name: name.into(),
+            rtp: ResourceType::Normal,
             pattern: path.to_owned(),
-            external: false,
         }
     }
 
@@ -210,6 +220,11 @@ impl Resource {
         &self.name
     }
 
+    /// Resource type
+    pub fn rtype(&self) -> ResourceType {
+        self.rtp
+    }
+
     /// Path pattern of the resource
     pub fn pattern(&self) -> &str {
         &self.pattern
@@ -253,7 +268,7 @@ impl Resource {
               I: AsRef<str>,
     {
         let mut iter = elements.into_iter();
-        let mut path = if !self.external {
+        let mut path = if self.rtp != ResourceType::External {
             format!("{}/", router.prefix())
         } else {
             String::new()