ureq/response.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use http::Uri;
use crate::body::Body;
use crate::http;
#[derive(Debug, Clone)]
pub(crate) struct ResponseUri(pub http::Uri);
#[derive(Debug, Clone)]
pub(crate) struct RedirectHistory(pub Vec<Uri>);
/// Extension trait for [`http::Response<Body>`].
///
/// Adds additional convenience methods to the `Response` that are not available
/// in the plain http API.
pub trait ResponseExt {
/// The Uri that ultimately this Response is about.
///
/// This can differ from the request uri when we have followed redirects.
///
/// ```
/// use ureq::ResponseExt;
///
/// let res = ureq::get("https://httpbin.org/redirect-to?url=%2Fget")
/// .call().unwrap();
///
/// assert_eq!(res.get_uri(), "https://httpbin.org/get");
/// ```
fn get_uri(&self) -> &Uri;
/// The full history of uris, including the request and final uri.
///
/// Returns `None` when [`Config::save_redirect_history`][crate::config::Config::save_redirect_history]
/// is `false`.
///
///
/// ```
/// # use ureq::http::Uri;
/// use ureq::ResponseExt;
///
/// let uri1: Uri = "https://httpbin.org/redirect-to?url=%2Fget".parse().unwrap();
/// let uri2: Uri = "https://httpbin.org/get".parse::<Uri>().unwrap();
///
/// let res = ureq::get(&uri1)
/// .config()
/// .save_redirect_history(true)
/// .build()
/// .call().unwrap();
///
/// let history = res.get_redirect_history().unwrap();
///
/// assert_eq!(history, &[uri1, uri2]);
/// ```
fn get_redirect_history(&self) -> Option<&[Uri]>;
}
impl ResponseExt for http::Response<Body> {
fn get_uri(&self) -> &Uri {
&self
.extensions()
.get::<ResponseUri>()
.expect("uri to have been set")
.0
}
fn get_redirect_history(&self) -> Option<&[Uri]> {
self.extensions()
.get::<RedirectHistory>()
.map(|r| r.0.as_ref())
}
}