diff --git a/actix-http/src/message.rs b/actix-http/src/message.rs
index 1a5500c3..bccb4d53 100644
--- a/actix-http/src/message.rs
+++ b/actix-http/src/message.rs
@@ -34,7 +34,9 @@ bitflags! {
 pub trait Head: Default + 'static {
     fn clear(&mut self);
 
-    fn pool() -> &'static MessagePool<Self>;
+    fn with_pool<F, R>(f: F) -> R
+    where
+        F: FnOnce(&MessagePool<Self>) -> R;
 }
 
 #[derive(Debug)]
@@ -69,8 +71,11 @@ impl Head for RequestHead {
         self.extensions.get_mut().clear();
     }
 
-    fn pool() -> &'static MessagePool<Self> {
-        REQUEST_POOL.with(|p| *p)
+    fn with_pool<F, R>(f: F) -> R
+    where
+        F: FnOnce(&MessagePool<Self>) -> R,
+    {
+        REQUEST_POOL.with(|p| f(p))
     }
 }
 
@@ -344,7 +349,7 @@ pub struct Message<T: Head> {
 impl<T: Head> Message<T> {
     /// Get new message from the pool of objects
     pub fn new() -> Self {
-        T::pool().get_message()
+        T::with_pool(|p| p.get_message())
     }
 }
 
@@ -373,7 +378,7 @@ impl<T: Head> std::ops::DerefMut for Message<T> {
 impl<T: Head> Drop for Message<T> {
     fn drop(&mut self) {
         if Rc::strong_count(&self.head) == 1 {
-            T::pool().release(self.head.clone());
+            T::with_pool(|p| p.release(self.head.clone()))
         }
     }
 }
@@ -426,18 +431,17 @@ pub struct MessagePool<T: Head>(RefCell<Vec<Rc<T>>>);
 /// Request's objects pool
 pub struct BoxedResponsePool(RefCell<Vec<Box<ResponseHead>>>);
 
-thread_local!(static REQUEST_POOL: &'static MessagePool<RequestHead> = MessagePool::<RequestHead>::create());
-thread_local!(static RESPONSE_POOL: &'static BoxedResponsePool = BoxedResponsePool::create());
+thread_local!(static REQUEST_POOL: MessagePool<RequestHead> = MessagePool::<RequestHead>::create());
+thread_local!(static RESPONSE_POOL: BoxedResponsePool = BoxedResponsePool::create());
 
 impl<T: Head> MessagePool<T> {
-    fn create() -> &'static MessagePool<T> {
-        let pool = MessagePool(RefCell::new(Vec::with_capacity(128)));
-        Box::leak(Box::new(pool))
+    fn create() -> MessagePool<T> {
+        MessagePool(RefCell::new(Vec::with_capacity(128)))
     }
 
     /// Get message from the pool
     #[inline]
-    fn get_message(&'static self) -> Message<T> {
+    fn get_message(&self) -> Message<T> {
         if let Some(mut msg) = self.0.borrow_mut().pop() {
             // Message is put in pool only when it's the last copy.
             // which means it's guaranteed to be unique when popped out.
@@ -463,14 +467,13 @@ impl<T: Head> MessagePool<T> {
 }
 
 impl BoxedResponsePool {
-    fn create() -> &'static BoxedResponsePool {
-        let pool = BoxedResponsePool(RefCell::new(Vec::with_capacity(128)));
-        Box::leak(Box::new(pool))
+    fn create() -> BoxedResponsePool {
+        BoxedResponsePool(RefCell::new(Vec::with_capacity(128)))
     }
 
     /// Get message from the pool
     #[inline]
-    fn get_message(&'static self, status: StatusCode) -> BoxedResponseHead {
+    fn get_message(&self, status: StatusCode) -> BoxedResponseHead {
         if let Some(mut head) = self.0.borrow_mut().pop() {
             head.reason = None;
             head.status = status;