acick_util/service/
mod.rs

1use anyhow::Context as _;
2use reqwest::blocking::Response;
3use reqwest::header::LOCATION;
4use reqwest::Url;
5
6use crate::Result;
7
8pub mod act;
9mod cookie;
10pub mod scrape;
11pub mod session;
12
13pub use self::cookie::CookieStorage;
14pub use act::Act;
15
16pub trait ResponseExt {
17    fn location_url(&self, base: &Url) -> Result<Url>;
18}
19
20impl ResponseExt for Response {
21    fn location_url(&self, base: &Url) -> Result<Url> {
22        let loc_str = self
23            .headers()
24            .get(LOCATION)
25            .context("Could not find location header in response")?
26            .to_str()?;
27        base.join(loc_str)
28            .context("Could not parse redirection url")
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use reqwest::blocking::Client;
35    use reqwest::redirect::Policy;
36
37    use super::*;
38
39    #[test]
40    fn test_location_url() -> anyhow::Result<()> {
41        let client = Client::builder()
42            .redirect(Policy::none()) // redirects manually
43            .build()
44            .unwrap();
45        let res = client.get("https://mail.google.com").send()?;
46        let actual = res.location_url(&Url::parse("https://mail.google.com").unwrap())?;
47        let expected = Url::parse("https://mail.google.com/mail/").unwrap();
48        assert_eq!(actual, expected);
49        Ok(())
50    }
51}