feat(server): make Http compatible with TcpServer

This implements `From<Message> for Request` and `Into<Message> for
Response`, allowing an `Http` instance to be used with a `TcpServer`
from tokio-proto.

Closes #1036

BREAKING CHANGE: This makes `Request.remote_addr` an
  `Option<SocketAddr>`, instead of `SocketAddr`.
This commit is contained in:
Sean McArthur
2017-02-03 16:16:09 -08:00
parent 3cf3b75159
commit e04bcc12a7
2 changed files with 42 additions and 15 deletions

View File

@@ -265,20 +265,32 @@ impl<T: Io + 'static, B> Future for __ProtoBindTransport<T, B> {
}
}
impl From<Message<__ProtoRequest, http::TokioBody>> for Request {
fn from(message: Message<__ProtoRequest, http::TokioBody>) -> Request {
let (head, body) = match message {
Message::WithoutBody(head) => (head.0, http::Body::empty()),
Message::WithBody(head, body) => (head.0, body.into()),
};
request::new(None, head, body)
}
}
impl<B> Into<Message<__ProtoResponse, B>> for Response<B> {
fn into(self) -> Message<__ProtoResponse, B> {
let (head, body) = response::split(self);
if let Some(body) = body {
Message::WithBody(__ProtoResponse(head), body.into())
} else {
Message::WithoutBody(__ProtoResponse(head))
}
}
}
struct HttpService<T> {
inner: T,
remote_addr: SocketAddr,
}
fn map_response_to_message<B>(res: Response<B>) -> Message<__ProtoResponse, B> {
let (head, body) = response::split(res);
if let Some(body) = body {
Message::WithBody(__ProtoResponse(head), body.into())
} else {
Message::WithoutBody(__ProtoResponse(head))
}
}
type ResponseHead = http::MessageHead<::StatusCode>;
impl<T, B> Service for HttpService<T>
@@ -296,8 +308,8 @@ impl<T, B> Service for HttpService<T>
Message::WithoutBody(head) => (head.0, http::Body::empty()),
Message::WithBody(head, body) => (head.0, body.into()),
};
let req = request::new(self.remote_addr, head, body);
self.inner.call(req).map(map_response_to_message)
let req = request::new(Some(self.remote_addr), head, body);
self.inner.call(req).map(Into::into)
}
}