diff --git a/src/client/h2proto.rs b/src/client/h2proto.rs
index f2f18d935..ecd18cf82 100644
--- a/src/client/h2proto.rs
+++ b/src/client/h2proto.rs
@@ -1,3 +1,4 @@
+use std::cell::RefCell;
 use std::time;
 
 use actix_codec::{AsyncRead, AsyncWrite};
@@ -110,7 +111,7 @@ where
 
             Ok(ClientResponse {
                 head,
-                payload: Some(Box::new(Payload::new(body))),
+                payload: RefCell::new(Some(Box::new(Payload::new(body)))),
             })
         })
         .from_err()
diff --git a/src/client/response.rs b/src/client/response.rs
index 65c59f2a6..7a83d825d 100644
--- a/src/client/response.rs
+++ b/src/client/response.rs
@@ -1,3 +1,4 @@
+use std::cell::RefCell;
 use std::fmt;
 
 use bytes::Bytes;
@@ -13,7 +14,7 @@ use crate::message::{Head, ResponseHead};
 #[derive(Default)]
 pub struct ClientResponse {
     pub(crate) head: ResponseHead,
-    pub(crate) payload: Option<PayloadStream>,
+    pub(crate) payload: RefCell<Option<PayloadStream>>,
 }
 
 impl HttpMessage for ClientResponse {
@@ -24,8 +25,8 @@ impl HttpMessage for ClientResponse {
     }
 
     #[inline]
-    fn payload(&mut self) -> Option<Self::Stream> {
-        self.payload.take()
+    fn payload(&self) -> Option<Self::Stream> {
+        self.payload.borrow_mut().take()
     }
 }
 
@@ -34,7 +35,7 @@ impl ClientResponse {
     pub fn new() -> ClientResponse {
         ClientResponse {
             head: ResponseHead::default(),
-            payload: None,
+            payload: RefCell::new(None),
         }
     }
 
@@ -80,7 +81,7 @@ impl ClientResponse {
 
     /// Set response payload
     pub fn set_payload(&mut self, payload: PayloadStream) {
-        self.payload = Some(payload);
+        *self.payload.get_mut() = Some(payload);
     }
 }
 
@@ -89,7 +90,7 @@ impl Stream for ClientResponse {
     type Error = PayloadError;
 
     fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
-        if let Some(ref mut payload) = self.payload {
+        if let Some(ref mut payload) = self.payload.get_mut() {
             payload.poll()
         } else {
             Ok(Async::Ready(None))
diff --git a/src/httpmessage.rs b/src/httpmessage.rs
index 39aa1b689..47fc57d6c 100644
--- a/src/httpmessage.rs
+++ b/src/httpmessage.rs
@@ -25,7 +25,7 @@ pub trait HttpMessage: Sized {
     fn headers(&self) -> &HeaderMap;
 
     /// Message payload stream
-    fn payload(&mut self) -> Option<Self::Stream>;
+    fn payload(&self) -> Option<Self::Stream>;
 
     #[doc(hidden)]
     /// Get a header
diff --git a/src/lib.rs b/src/lib.rs
index 715823930..f34da84c1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -75,7 +75,7 @@ mod extensions;
 mod header;
 mod helpers;
 mod httpcodes;
-mod httpmessage;
+pub mod httpmessage;
 mod json;
 mod message;
 mod request;
diff --git a/src/request.rs b/src/request.rs
index f6be69ddb..519cc38ed 100644
--- a/src/request.rs
+++ b/src/request.rs
@@ -1,4 +1,4 @@
-use std::cell::{Ref, RefMut};
+use std::cell::{Ref, RefCell, RefMut};
 use std::fmt;
 use std::rc::Rc;
 
@@ -14,7 +14,7 @@ use crate::payload::Payload;
 
 /// Request
 pub struct Request<P = Payload> {
-    pub(crate) payload: Option<P>,
+    pub(crate) payload: RefCell<Option<P>>,
     pub(crate) inner: Rc<Message<RequestHead>>,
 }
 
@@ -29,8 +29,8 @@ where
     }
 
     #[inline]
-    fn payload(&mut self) -> Option<P> {
-        self.payload.take()
+    fn payload(&self) -> Option<P> {
+        self.payload.borrow_mut().take()
     }
 }
 
@@ -38,7 +38,7 @@ impl Request<Payload> {
     /// Create new Request instance
     pub fn new() -> Request<Payload> {
         Request {
-            payload: None,
+            payload: RefCell::new(None),
             inner: MessagePool::get_message(),
         }
     }
@@ -48,7 +48,7 @@ impl<Payload> Request<Payload> {
     /// Create new Request instance
     pub fn with_payload(payload: Payload) -> Request<Payload> {
         Request {
-            payload: Some(payload),
+            payload: RefCell::new(Some(payload.into())),
             inner: MessagePool::get_message(),
         }
     }
@@ -59,7 +59,7 @@ impl<Payload> Request<Payload> {
         I: Into<P>,
     {
         Request {
-            payload: Some(payload.into()),
+            payload: RefCell::new(Some(payload.into())),
             inner: self.inner.clone(),
         }
     }
@@ -67,9 +67,9 @@ impl<Payload> Request<Payload> {
     /// Take request's payload
     pub fn take_payload(mut self) -> (Option<Payload>, Request<()>) {
         (
-            self.payload.take(),
+            self.payload.get_mut().take(),
             Request {
-                payload: Some(()),
+                payload: RefCell::new(None),
                 inner: self.inner.clone(),
             },
         )