Add history to response objects (#275)

This allows Error to report both the URL that caused an error, and the
original URL that was requested.

Change unit::connect to use the Response history for tracking number of
redirects, instead of passing the count as a separate parameter.

Incidentally, move handling of the `stream` fully inside `Response`.
Instead of `do_from_read` + `set_stream`, we now have `do_from_stream`,
which takes ownership of the stream and keeps it. We also have
`do_from_request`, which does all of `do_from_stream`, but also sets the
`previous` field.
This commit is contained in:
Jacob Hoffman-Andrews
2020-12-13 11:59:11 -08:00
committed by GitHub
parent 10baf7c051
commit 8cb4f401e3
4 changed files with 143 additions and 53 deletions

View File

@@ -2,7 +2,7 @@ use url::Url;
use std::error;
use std::fmt::{self, Display};
use std::io::{self};
use std::io;
use crate::Response;
@@ -67,6 +67,9 @@ impl Display for Error {
match self {
Error::Status(status, response) => {
write!(f, "{}: status code {}", response.get_url(), status)?;
if let Some(original) = response.history().last() {
write!(f, " (redirected from {})", original.get_url())?;
}
}
Error::Transport(err) => {
write!(f, "{}", err)?;
@@ -250,15 +253,32 @@ impl fmt::Display for ErrorKind {
}
}
// #[test]
// fn status_code_error() {
// let mut err = Error::new(ErrorKind::HTTP, None);
// err = err.response(Response::new(500, "Internal Server Error", "too much going on").unwrap());
// assert_eq!(err.to_string(), "status code 500");
#[test]
fn status_code_error() {
let mut response = Response::new(404, "NotFound", "").unwrap();
response.set_url("http://example.org/".parse().unwrap());
let err = Error::Status(response.status(), response);
// err = err.url("http://example.com/".parse().unwrap());
// assert_eq!(err.to_string(), "http://example.com/: status code 500");
// }
assert_eq!(err.to_string(), "http://example.org/: status code 404");
}
#[test]
fn status_code_error_redirect() {
use std::sync::Arc;
let mut response0 = Response::new(302, "Found", "").unwrap();
response0.set_url("http://example.org/".parse().unwrap());
let mut response1 = Response::new(302, "Found", "").unwrap();
response1.set_previous(Arc::new(response0));
let mut response2 = Response::new(500, "Internal Server Error", "server overloaded").unwrap();
response2.set_previous(Arc::new(response1));
response2.set_url("http://example.com/".parse().unwrap());
let err = Error::Status(response2.status(), response2);
assert_eq!(
err.to_string(),
"http://example.com/: status code 500 (redirected from http://example.org/)"
);
}
#[test]
fn io_error() {