fix(server): add remote_addr back to Request when using Http::bind
The `Request::remote_addr()` method has been deprecated. Closes #1410
This commit is contained in:
@@ -58,13 +58,9 @@ impl<B> Request<B> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn body_ref(&self) -> Option<&B> { self.body.as_ref() }
|
pub fn body_ref(&self) -> Option<&B> { self.body.as_ref() }
|
||||||
|
|
||||||
/// The remote socket address of this request
|
#[doc(hidden)]
|
||||||
///
|
|
||||||
/// This is an `Option`, because some underlying transports may not have
|
|
||||||
/// a socket address, such as Unix Sockets.
|
|
||||||
///
|
|
||||||
/// This field is not used for outgoing requests.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[deprecated(since="0.11.12", note="This method will be gone in future versions.")]
|
||||||
pub fn remote_addr(&self) -> Option<SocketAddr> { self.remote_addr }
|
pub fn remote_addr(&self) -> Option<SocketAddr> { self.remote_addr }
|
||||||
|
|
||||||
/// The target path of this Request.
|
/// The target path of this Request.
|
||||||
@@ -196,6 +192,10 @@ pub fn split<B>(req: Request<B>) -> (RequestHead, Option<B>) {
|
|||||||
(head, req.body)
|
(head, req.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn addr<B>(req: &mut Request<B>, addr: SocketAddr) {
|
||||||
|
req.remote_addr = Some(addr);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -352,8 +352,9 @@ impl<S, B> Server<S, B>
|
|||||||
|
|
||||||
// Future for our server's execution
|
// Future for our server's execution
|
||||||
let srv = listener.incoming().for_each(|(socket, addr)| {
|
let srv = listener.incoming().for_each(|(socket, addr)| {
|
||||||
|
let addr_service = SocketAddrService::new(addr, new_service.new_service()?);
|
||||||
let s = NotifyService {
|
let s = NotifyService {
|
||||||
inner: try!(new_service.new_service()),
|
inner: addr_service,
|
||||||
info: Rc::downgrade(&info),
|
info: Rc::downgrade(&info),
|
||||||
};
|
};
|
||||||
info.borrow_mut().active += 1;
|
info.borrow_mut().active += 1;
|
||||||
@@ -644,6 +645,41 @@ mod addr_stream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== SocketAddrService
|
||||||
|
|
||||||
|
// This is used from `Server::run`, which captures the remote address
|
||||||
|
// in this service, and then injects it into each `Request`.
|
||||||
|
struct SocketAddrService<S> {
|
||||||
|
addr: SocketAddr,
|
||||||
|
inner: S,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> SocketAddrService<S> {
|
||||||
|
fn new(addr: SocketAddr, service: S) -> SocketAddrService<S> {
|
||||||
|
SocketAddrService {
|
||||||
|
addr: addr,
|
||||||
|
inner: service,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Service for SocketAddrService<S>
|
||||||
|
where
|
||||||
|
S: Service<Request=Request>,
|
||||||
|
{
|
||||||
|
type Request = S::Request;
|
||||||
|
type Response = S::Response;
|
||||||
|
type Error = S::Error;
|
||||||
|
type Future = S::Future;
|
||||||
|
|
||||||
|
fn call(&self, mut req: Self::Request) -> Self::Future {
|
||||||
|
proto::request::addr(&mut req, self.addr);
|
||||||
|
self.inner.call(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== NotifyService =====
|
||||||
|
|
||||||
struct NotifyService<S> {
|
struct NotifyService<S> {
|
||||||
inner: S,
|
inner: S,
|
||||||
info: Weak<RefCell<Info>>,
|
info: Weak<RefCell<Info>>,
|
||||||
|
|||||||
@@ -712,6 +712,22 @@ fn nonempty_parse_eof_returns_error() {
|
|||||||
core.run(fut).unwrap_err();
|
core.run(fut).unwrap_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remote_addr() {
|
||||||
|
let server = serve();
|
||||||
|
|
||||||
|
let mut req = connect(server.addr());
|
||||||
|
req.write_all(b"\
|
||||||
|
GET / HTTP/1.1\r\n\
|
||||||
|
Host: example.domain\r\n\
|
||||||
|
\r\n\
|
||||||
|
").unwrap();
|
||||||
|
req.read(&mut [0; 256]).unwrap();
|
||||||
|
|
||||||
|
let client_addr = req.local_addr().unwrap();
|
||||||
|
assert_eq!(server.remote_addr(), client_addr);
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
// the Server that is used to run all the tests with
|
// the Server that is used to run all the tests with
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
@@ -729,10 +745,23 @@ impl Serve {
|
|||||||
&self.addr
|
&self.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remote_addr(&self) -> SocketAddr {
|
||||||
|
match self.msg_rx.try_recv() {
|
||||||
|
Ok(Msg::Addr(addr)) => addr,
|
||||||
|
other => panic!("expected remote addr, found: {:?}", other),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn body(&self) -> Vec<u8> {
|
fn body(&self) -> Vec<u8> {
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
while let Ok(Msg::Chunk(msg)) = self.msg_rx.try_recv() {
|
loop {
|
||||||
buf.extend(&msg);
|
match self.msg_rx.try_recv() {
|
||||||
|
Ok(Msg::Chunk(msg)) => {
|
||||||
|
buf.extend(&msg);
|
||||||
|
},
|
||||||
|
Ok(Msg::Addr(_)) => {},
|
||||||
|
Err(_) => break,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
@@ -787,8 +816,10 @@ enum Reply {
|
|||||||
Body(Vec<u8>),
|
Body(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum Msg {
|
enum Msg {
|
||||||
//Head(Request),
|
//Head(Request),
|
||||||
|
Addr(SocketAddr),
|
||||||
Chunk(Vec<u8>),
|
Chunk(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,6 +842,11 @@ impl Service for TestService {
|
|||||||
type Future = Box<Future<Item=Response, Error=hyper::Error>>;
|
type Future = Box<Future<Item=Response, Error=hyper::Error>>;
|
||||||
fn call(&self, req: Request) -> Self::Future {
|
fn call(&self, req: Request) -> Self::Future {
|
||||||
let tx = self.tx.clone();
|
let tx = self.tx.clone();
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
|
let remote_addr = req.remote_addr().expect("remote_addr");
|
||||||
|
tx.lock().unwrap().send(Msg::Addr(remote_addr)).unwrap();
|
||||||
|
|
||||||
let replies = self.reply.clone();
|
let replies = self.reply.clone();
|
||||||
Box::new(req.body().for_each(move |chunk| {
|
Box::new(req.body().for_each(move |chunk| {
|
||||||
tx.lock().unwrap().send(Msg::Chunk(chunk.to_vec())).unwrap();
|
tx.lock().unwrap().send(Msg::Chunk(chunk.to_vec())).unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user