Skip to content

Commit e04bcc1

Browse files
committed
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`.
1 parent 3cf3b75 commit e04bcc1

2 files changed

Lines changed: 42 additions & 15 deletions

File tree

src/server/mod.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -265,20 +265,32 @@ impl<T: Io + 'static, B> Future for __ProtoBindTransport<T, B> {
265265
}
266266
}
267267

268-
struct HttpService<T> {
269-
inner: T,
270-
remote_addr: SocketAddr,
268+
impl From<Message<__ProtoRequest, http::TokioBody>> for Request {
269+
fn from(message: Message<__ProtoRequest, http::TokioBody>) -> Request {
270+
let (head, body) = match message {
271+
Message::WithoutBody(head) => (head.0, http::Body::empty()),
272+
Message::WithBody(head, body) => (head.0, body.into()),
273+
};
274+
request::new(None, head, body)
275+
}
271276
}
272277

273-
fn map_response_to_message<B>(res: Response<B>) -> Message<__ProtoResponse, B> {
274-
let (head, body) = response::split(res);
275-
if let Some(body) = body {
276-
Message::WithBody(__ProtoResponse(head), body.into())
277-
} else {
278-
Message::WithoutBody(__ProtoResponse(head))
278+
impl<B> Into<Message<__ProtoResponse, B>> for Response<B> {
279+
fn into(self) -> Message<__ProtoResponse, B> {
280+
let (head, body) = response::split(self);
281+
if let Some(body) = body {
282+
Message::WithBody(__ProtoResponse(head), body.into())
283+
} else {
284+
Message::WithoutBody(__ProtoResponse(head))
285+
}
279286
}
280287
}
281288

289+
struct HttpService<T> {
290+
inner: T,
291+
remote_addr: SocketAddr,
292+
}
293+
282294
type ResponseHead = http::MessageHead<::StatusCode>;
283295

284296
impl<T, B> Service for HttpService<T>
@@ -296,8 +308,8 @@ impl<T, B> Service for HttpService<T>
296308
Message::WithoutBody(head) => (head.0, http::Body::empty()),
297309
Message::WithBody(head, body) => (head.0, body.into()),
298310
};
299-
let req = request::new(self.remote_addr, head, body);
300-
self.inner.call(req).map(map_response_to_message)
311+
let req = request::new(Some(self.remote_addr), head, body);
312+
self.inner.call(req).map(Into::into)
301313
}
302314
}
303315

src/server/request.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub struct Request {
1818
uri: Uri,
1919
version: HttpVersion,
2020
headers: Headers,
21-
remote_addr: SocketAddr,
21+
remote_addr: Option<SocketAddr>,
2222
body: Body,
2323
}
2424

@@ -40,8 +40,11 @@ impl Request {
4040
pub fn version(&self) -> &HttpVersion { &self.version }
4141

4242
/// The remote socket address of this request
43+
///
44+
/// This is an `Option`, because some underlying transports may not have
45+
/// a socket address, such as Unix Sockets.
4346
#[inline]
44-
pub fn remote_addr(&self) -> &SocketAddr { &self.remote_addr }
47+
pub fn remote_addr(&self) -> Option<&SocketAddr> { self.remote_addr.as_ref() }
4548

4649
/// The target path of this Request.
4750
#[inline]
@@ -82,9 +85,9 @@ impl fmt::Debug for Request {
8285
}
8386
}
8487

85-
pub fn new(addr: SocketAddr, incoming: RequestHead, body: Body) -> Request {
88+
pub fn new(addr: Option<SocketAddr>, incoming: RequestHead, body: Body) -> Request {
8689
let MessageHead { version, subject: RequestLine(method, uri), headers } = incoming;
87-
debug!("Request::new: addr={}, req=\"{} {} {}\"", addr, method, uri, version);
90+
debug!("Request::new: addr={}, req=\"{} {} {}\"", MaybeAddr(&addr), method, uri, version);
8891
debug!("Request::new: headers={:?}", headers);
8992

9093
Request {
@@ -96,3 +99,15 @@ pub fn new(addr: SocketAddr, incoming: RequestHead, body: Body) -> Request {
9699
body: body,
97100
}
98101
}
102+
103+
struct MaybeAddr<'a>(&'a Option<SocketAddr>);
104+
105+
impl<'a> fmt::Display for MaybeAddr<'a> {
106+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107+
match *self.0 {
108+
Some(ref addr) => fmt::Display::fmt(addr, f),
109+
None => f.write_str("None"),
110+
}
111+
}
112+
}
113+

0 commit comments

Comments
 (0)