diff --git a/src/response.rs b/src/response.rs index 5df9a6f..67594b1 100644 --- a/src/response.rs +++ b/src/response.rs @@ -37,6 +37,7 @@ pub const DEFAULT_CHARACTER_SET: &str = "utf-8"; /// // response is consumed, and body has been read. /// ``` pub struct Response { + url: Option, error: Option, status_line: AsciiString, index: (usize, usize), // index into status_line where we split: HTTP/1.1 200 OK @@ -76,6 +77,12 @@ impl Response { .unwrap_or_else(|e| e.into()) } + /// The URL we ended up at. This can differ from the request url when + /// we have followed redirects. + pub fn get_url(&self) -> &str { + self.url.as_ref().map(|s| &s[..]).unwrap_or("") + } + /// The entire status line like: `HTTP/1.1 200 OK` pub fn status_line(&self) -> &str { self.status_line.as_str() @@ -411,6 +418,7 @@ impl Response { } Ok(Response { + url: None, error: None, status_line, index, @@ -475,7 +483,7 @@ impl FromStr for Response { let bytes = s.as_bytes().to_owned(); let mut cursor = Cursor::new(bytes); let mut resp = Self::do_from_read(&mut cursor)?; - set_stream(&mut resp, None, Stream::Cursor(cursor)); + set_stream(&mut resp, "".into(), None, Stream::Cursor(cursor)); Ok(resp) } } @@ -494,7 +502,8 @@ impl Into for Error { /// "Give away" Unit and Stream to the response. /// /// *Internal API* -pub fn set_stream(resp: &mut Response, unit: Option, stream: Stream) { +pub(crate) fn set_stream(resp: &mut Response, url: String, unit: Option, stream: Stream) { + resp.url = Some(url); resp.unit = unit; resp.stream = Some(stream); } diff --git a/src/test/redirect.rs b/src/test/redirect.rs index 3ea329c..705c672 100644 --- a/src/test/redirect.rs +++ b/src/test/redirect.rs @@ -51,6 +51,7 @@ fn redirect_head() { }); let resp = head("test://host/redirect_head1").call(); assert_eq!(resp.status(), 200); + assert_eq!(resp.get_url(), "test://host/redirect_head2"); assert!(resp.has("x-foo")); assert_eq!(resp.header("x-foo").unwrap(), "bar"); } @@ -70,6 +71,7 @@ fn redirect_get() { .set("Range", "bytes=10-50") .call(); assert_eq!(resp.status(), 200); + assert_eq!(resp.get_url(), "test://host/redirect_get2"); assert!(resp.has("x-foo")); assert_eq!(resp.header("x-foo").unwrap(), "bar"); } @@ -85,6 +87,7 @@ fn redirect_post() { }); let resp = post("test://host/redirect_post1").call(); assert_eq!(resp.status(), 200); + assert_eq!(resp.get_url(), "test://host/redirect_post2"); assert!(resp.has("x-foo")); assert_eq!(resp.header("x-foo").unwrap(), "bar"); } diff --git a/src/unit.rs b/src/unit.rs index 3278450..89cb559 100644 --- a/src/unit.rs +++ b/src/unit.rs @@ -182,7 +182,7 @@ pub(crate) fn connect( // since it is not a redirect, or we're not following redirects, // give away the incoming stream to the response object - response::set_stream(&mut resp, Some(unit), stream); + response::set_stream(&mut resp, unit.url.to_string(), Some(unit), stream); // release the response Ok(resp)