add a referer() option to disable setting Referer header on redirects
This commit is contained in:
		| @@ -60,6 +60,7 @@ impl Client { | |||||||
|             inner: Arc::new(ClientRef { |             inner: Arc::new(ClientRef { | ||||||
|                 hyper: RwLock::new(client), |                 hyper: RwLock::new(client), | ||||||
|                 redirect_policy: Mutex::new(RedirectPolicy::default()), |                 redirect_policy: Mutex::new(RedirectPolicy::default()), | ||||||
|  |                 auto_referer: AtomicBool::new(true), | ||||||
|                 auto_ungzip: AtomicBool::new(true), |                 auto_ungzip: AtomicBool::new(true), | ||||||
|             }), |             }), | ||||||
|         }) |         }) | ||||||
| @@ -75,6 +76,13 @@ impl Client { | |||||||
|         *self.inner.redirect_policy.lock().unwrap() = policy; |         *self.inner.redirect_policy.lock().unwrap() = policy; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Enable or disable automatic setting of the `Referer` header. | ||||||
|  |     /// | ||||||
|  |     /// Default is `true`. | ||||||
|  |     pub fn referer(&mut self, enable: bool) { | ||||||
|  |         self.inner.auto_referer.store(enable, Ordering::Relaxed); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// Set a timeout for both the read and write operations of a client. |     /// Set a timeout for both the read and write operations of a client. | ||||||
|     pub fn timeout(&mut self, timeout: Duration) { |     pub fn timeout(&mut self, timeout: Duration) { | ||||||
|         let mut client = self.inner.hyper.write().unwrap(); |         let mut client = self.inner.hyper.write().unwrap(); | ||||||
| @@ -134,6 +142,7 @@ impl fmt::Debug for Client { | |||||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         f.debug_struct("Client") |         f.debug_struct("Client") | ||||||
|             .field("redirect_policy", &self.inner.redirect_policy) |             .field("redirect_policy", &self.inner.redirect_policy) | ||||||
|  |             .field("referer", &self.inner.auto_referer) | ||||||
|             .field("auto_ungzip", &self.inner.auto_ungzip) |             .field("auto_ungzip", &self.inner.auto_ungzip) | ||||||
|             .finish() |             .finish() | ||||||
|     } |     } | ||||||
| @@ -142,6 +151,7 @@ impl fmt::Debug for Client { | |||||||
| struct ClientRef { | struct ClientRef { | ||||||
|     hyper: RwLock<::hyper::Client>, |     hyper: RwLock<::hyper::Client>, | ||||||
|     redirect_policy: Mutex<RedirectPolicy>, |     redirect_policy: Mutex<RedirectPolicy>, | ||||||
|  |     auto_referer: AtomicBool, | ||||||
|     auto_ungzip: AtomicBool, |     auto_ungzip: AtomicBool, | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -328,7 +338,9 @@ impl RequestBuilder { | |||||||
|  |  | ||||||
|                 url = match loc { |                 url = match loc { | ||||||
|                     Ok(loc) => { |                     Ok(loc) => { | ||||||
|                         headers.set(Referer(url.to_string())); |                         if client.auto_referer.load(Ordering::Relaxed) { | ||||||
|  |                             headers.set(Referer(url.to_string())); | ||||||
|  |                         } | ||||||
|                         urls.push(url); |                         urls.push(url); | ||||||
|                         let action = check_redirect(&client.redirect_policy.lock().unwrap(), &loc, &urls); |                         let action = check_redirect(&client.redirect_policy.lock().unwrap(), &loc, &urls); | ||||||
|                         match action { |                         match action { | ||||||
|   | |||||||
| @@ -242,6 +242,47 @@ fn test_redirect_policy_can_stop_redirects_without_an_error() { | |||||||
|     assert_eq!(res.headers().get(), Some(&reqwest::header::Server("test-dont".to_string()))); |     assert_eq!(res.headers().get(), Some(&reqwest::header::Server("test-dont".to_string()))); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_referer_is_not_set_if_disabled() { | ||||||
|  |     let server = server! { | ||||||
|  |         request: b"\ | ||||||
|  |             GET /no-refer HTTP/1.1\r\n\ | ||||||
|  |             Host: $HOST\r\n\ | ||||||
|  |             User-Agent: $USERAGENT\r\n\ | ||||||
|  |             Accept: */*\r\n\ | ||||||
|  |             Accept-Encoding: gzip\r\n\ | ||||||
|  |             \r\n\ | ||||||
|  |             ", | ||||||
|  |         response: b"\ | ||||||
|  |             HTTP/1.1 302 Found\r\n\ | ||||||
|  |             Server: test-no-referer\r\n\ | ||||||
|  |             Content-Length: 0\r\n\ | ||||||
|  |             Location: /dst\r\n\ | ||||||
|  |             Connection: close\r\n\ | ||||||
|  |             \r\n\ | ||||||
|  |             ", | ||||||
|  |  | ||||||
|  |         request: b"\ | ||||||
|  |             GET /dst HTTP/1.1\r\n\ | ||||||
|  |             Host: $HOST\r\n\ | ||||||
|  |             User-Agent: $USERAGENT\r\n\ | ||||||
|  |             Accept: */*\r\n\ | ||||||
|  |             Accept-Encoding: gzip\r\n\ | ||||||
|  |             \r\n\ | ||||||
|  |             ", | ||||||
|  |         response: b"\ | ||||||
|  |             HTTP/1.1 200 OK\r\n\ | ||||||
|  |             Server: test-dst\r\n\ | ||||||
|  |             Content-Length: 0\r\n\ | ||||||
|  |             \r\n\ | ||||||
|  |             " | ||||||
|  |     }; | ||||||
|  |     let mut client = reqwest::Client::new().unwrap(); | ||||||
|  |     client.referer(false); | ||||||
|  |     client.get(&format!("http://{}/no-refer", server.addr())) | ||||||
|  |         .send().unwrap(); | ||||||
|  | } | ||||||
|  |  | ||||||
| #[test] | #[test] | ||||||
| fn test_accept_header_is_not_changed_if_set() { | fn test_accept_header_is_not_changed_if_set() { | ||||||
|     let server = server! { |     let server = server! { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user