oxihttp_client/
redirect.rs1#[derive(Debug, Clone)]
5pub enum RedirectPolicy {
6 None,
8 Limited(usize),
10 All,
12}
13
14impl RedirectPolicy {
15 pub fn max_redirects(&self) -> Option<usize> {
17 match self {
18 Self::None => Some(0),
19 Self::Limited(n) => Some(*n),
20 Self::All => None,
21 }
22 }
23
24 pub fn is_none(&self) -> bool {
26 matches!(self, Self::None)
27 }
28}
29
30impl Default for RedirectPolicy {
31 fn default() -> Self {
33 Self::Limited(10)
34 }
35}
36
37pub fn is_redirect_status(status: http::StatusCode) -> bool {
39 matches!(status.as_u16(), 301 | 302 | 303 | 307 | 308)
40}
41
42pub fn redirect_method(status: http::StatusCode, original: &http::Method) -> http::Method {
47 match status.as_u16() {
48 301..=303 => {
49 if *original == http::Method::HEAD {
50 http::Method::HEAD
51 } else {
52 http::Method::GET
53 }
54 }
55 _ => original.clone(),
57 }
58}
59
60pub fn should_preserve_body(status: http::StatusCode) -> bool {
64 matches!(status.as_u16(), 307 | 308)
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_default_policy() {
73 let policy = RedirectPolicy::default();
74 assert_eq!(policy.max_redirects(), Some(10));
75 }
76
77 #[test]
78 fn test_none_policy() {
79 let policy = RedirectPolicy::None;
80 assert!(policy.is_none());
81 assert_eq!(policy.max_redirects(), Some(0));
82 }
83
84 #[test]
85 fn test_is_redirect_status() {
86 assert!(is_redirect_status(http::StatusCode::MOVED_PERMANENTLY));
87 assert!(is_redirect_status(http::StatusCode::FOUND));
88 assert!(is_redirect_status(http::StatusCode::TEMPORARY_REDIRECT));
89 assert!(is_redirect_status(http::StatusCode::PERMANENT_REDIRECT));
90 assert!(!is_redirect_status(http::StatusCode::OK));
91 assert!(!is_redirect_status(http::StatusCode::NOT_FOUND));
92 }
93
94 #[test]
95 fn test_redirect_method_303() {
96 let method = redirect_method(http::StatusCode::SEE_OTHER, &http::Method::POST);
97 assert_eq!(method, http::Method::GET);
98 }
99
100 #[test]
101 fn test_redirect_method_307_preserves() {
102 let method = redirect_method(http::StatusCode::TEMPORARY_REDIRECT, &http::Method::POST);
103 assert_eq!(method, http::Method::POST);
104 }
105
106 #[test]
107 fn test_redirect_method_head_preserved() {
108 let method = redirect_method(http::StatusCode::FOUND, &http::Method::HEAD);
109 assert_eq!(method, http::Method::HEAD);
110 }
111
112 #[test]
113 fn test_should_preserve_body() {
114 assert!(!should_preserve_body(http::StatusCode::MOVED_PERMANENTLY));
115 assert!(!should_preserve_body(http::StatusCode::FOUND));
116 assert!(should_preserve_body(http::StatusCode::TEMPORARY_REDIRECT));
117 assert!(should_preserve_body(http::StatusCode::PERMANENT_REDIRECT));
118 }
119}