add Response::remote_addr() method
The new `remote_addr` method returns an `Option<SocketAddr>`, which is `Some` if the underlying transport uses socket addresses. Closes #373
This commit is contained in:
@@ -15,7 +15,7 @@ bytes = "0.4"
|
|||||||
encoding_rs = "0.8"
|
encoding_rs = "0.8"
|
||||||
futures = "0.1.23"
|
futures = "0.1.23"
|
||||||
http = "0.1.10"
|
http = "0.1.10"
|
||||||
hyper = "0.12.7"
|
hyper = "0.12.13"
|
||||||
hyper-old-types = { version = "0.11", optional = true, features = ["compat"] }
|
hyper-old-types = { version = "0.11", optional = true, features = ["compat"] }
|
||||||
hyper-tls = "0.3"
|
hyper-tls = "0.3"
|
||||||
libflate = "0.1.18"
|
libflate = "0.1.18"
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use futures::{Async, Future, Poll, Stream};
|
use futures::{Async, Future, Poll, Stream};
|
||||||
use futures::stream::Concat2;
|
use futures::stream::Concat2;
|
||||||
use hyper::{HeaderMap, StatusCode, Version};
|
use hyper::{HeaderMap, StatusCode, Version};
|
||||||
|
use hyper::client::connect::HttpInfo;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
@@ -23,14 +25,19 @@ pub struct Response {
|
|||||||
url: Box<Url>,
|
url: Box<Url>,
|
||||||
body: Decoder,
|
body: Decoder,
|
||||||
version: Version,
|
version: Version,
|
||||||
|
extensions: http::Extensions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Response {
|
impl Response {
|
||||||
pub(super) fn new(mut res: ::hyper::Response<::hyper::Body>, url: Url, gzip: bool) -> Response {
|
pub(super) fn new(res: ::hyper::Response<::hyper::Body>, url: Url, gzip: bool) -> Response {
|
||||||
let status = res.status();
|
let (parts, body) = res.into_parts();
|
||||||
let version = res.version();
|
let status = parts.status;
|
||||||
let mut headers = mem::replace(res.headers_mut(), HeaderMap::new());
|
let version = parts.version;
|
||||||
let decoder = Decoder::detect(&mut headers, Body::wrap(res.into_body()), gzip);
|
let extensions = parts.extensions;
|
||||||
|
|
||||||
|
let mut headers = parts.headers;
|
||||||
|
let decoder = Decoder::detect(&mut headers, Body::wrap(body), gzip);
|
||||||
|
|
||||||
debug!("Response: '{}' for {}", status, url);
|
debug!("Response: '{}' for {}", status, url);
|
||||||
Response {
|
Response {
|
||||||
status,
|
status,
|
||||||
@@ -38,6 +45,7 @@ impl Response {
|
|||||||
url: Box::new(url),
|
url: Box::new(url),
|
||||||
body: decoder,
|
body: decoder,
|
||||||
version,
|
version,
|
||||||
|
extensions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +55,14 @@ impl Response {
|
|||||||
&self.url
|
&self.url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the remote address used to get this `Response`.
|
||||||
|
pub fn remote_addr(&self) -> Option<SocketAddr> {
|
||||||
|
self
|
||||||
|
.extensions
|
||||||
|
.get::<HttpInfo>()
|
||||||
|
.map(|info| info.remote_addr())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the `StatusCode` of this `Response`.
|
/// Get the `StatusCode` of this `Response`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn status(&self) -> StatusCode {
|
pub fn status(&self) -> StatusCode {
|
||||||
@@ -161,6 +177,7 @@ impl<T: Into<Body>> From<http::Response<T>> for Response {
|
|||||||
url: Box::new(url),
|
url: Box::new(url),
|
||||||
body: body,
|
body: body,
|
||||||
version: parts.version,
|
version: parts.version,
|
||||||
|
extensions: parts.extensions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
|
use std::net::SocketAddr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
@@ -61,6 +62,22 @@ impl Response {
|
|||||||
self.inner.url()
|
self.inner.url()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the remote address used to get this `Response`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # fn run() -> Result<(), Box<::std::error::Error>> {
|
||||||
|
/// let resp = reqwest::get("http://httpbin.org/redirect/1")?;
|
||||||
|
/// println!("httpbin.org address: {:?}", resp.remote_addr());
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub fn remote_addr(&self) -> Option<SocketAddr> {
|
||||||
|
self.inner.remote_addr()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the `StatusCode` of this `Response`.
|
/// Get the `StatusCode` of this `Response`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ fn test_get() {
|
|||||||
assert_eq!(res.status(), reqwest::StatusCode::OK);
|
assert_eq!(res.status(), reqwest::StatusCode::OK);
|
||||||
assert_eq!(res.headers().get(reqwest::header::SERVER).unwrap(), &"test");
|
assert_eq!(res.headers().get(reqwest::header::SERVER).unwrap(), &"test");
|
||||||
assert_eq!(res.headers().get(reqwest::header::CONTENT_LENGTH).unwrap(), &"0");
|
assert_eq!(res.headers().get(reqwest::header::CONTENT_LENGTH).unwrap(), &"0");
|
||||||
|
assert_eq!(res.remote_addr(), Some(server.addr()));
|
||||||
|
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 1024];
|
||||||
let n = res.read(&mut buf).unwrap();
|
let n = res.read(&mut buf).unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user