tower_http/follow_redirect/policy/
limited.rs1use super::{Action, Attempt, Policy};
2
3#[derive(Clone, Copy, Debug)]
5pub struct Limited {
6 remaining: usize,
7}
8
9impl Limited {
10 pub fn new(max: usize) -> Self {
12 Limited { remaining: max }
13 }
14}
15
16impl Default for Limited {
17 fn default() -> Self {
19 Limited::new(20)
23 }
24}
25
26impl<B, E> Policy<B, E> for Limited {
27 fn redirect(&mut self, _: &Attempt<'_>) -> Result<Action, E> {
28 if self.remaining > 0 {
29 self.remaining -= 1;
30 Ok(Action::Follow)
31 } else {
32 Ok(Action::Stop)
33 }
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use http::{Method, Request, Uri};
40
41 use super::*;
42
43 #[test]
44 fn works() {
45 let uri = Uri::from_static("https://example.com/");
46 let mut policy = Limited::new(2);
47
48 for _ in 0..2 {
49 let mut request = Request::builder().uri(uri.clone()).body(()).unwrap();
50 Policy::<(), ()>::on_request(&mut policy, &mut request);
51
52 let attempt = Attempt {
53 status: Default::default(),
54 method: &Method::GET,
55 location: &uri,
56 previous_method: &Method::GET,
57 previous: &uri,
58 };
59 assert!(Policy::<(), ()>::redirect(&mut policy, &attempt)
60 .unwrap()
61 .is_follow());
62 }
63
64 let mut request = Request::builder().uri(uri.clone()).body(()).unwrap();
65 Policy::<(), ()>::on_request(&mut policy, &mut request);
66
67 let attempt = Attempt {
68 status: Default::default(),
69 method: &Method::GET,
70 location: &uri,
71 previous_method: &Method::GET,
72 previous: &uri,
73 };
74 assert!(Policy::<(), ()>::redirect(&mut policy, &attempt)
75 .unwrap()
76 .is_stop());
77 }
78}