wisegate_core/
headers.rs

1//! HTTP header constants for WiseGate.
2//!
3//! This module centralizes all HTTP header names used throughout the codebase,
4//! avoiding magic strings and ensuring consistency.
5
6/// X-Forwarded-For header - contains the originating client IP.
7pub const X_FORWARDED_FOR: &str = "x-forwarded-for";
8
9/// X-Real-IP header - injected by WiseGate for upstream services.
10pub const X_REAL_IP: &str = "x-real-ip";
11
12/// Forwarded header (RFC 7239) - standardized proxy header.
13pub const FORWARDED: &str = "forwarded";
14
15/// Content-Type header.
16pub const CONTENT_TYPE: &str = "content-type";
17
18/// Host header.
19pub const HOST: &str = "host";
20
21/// Content-Length header.
22pub const CONTENT_LENGTH: &str = "content-length";
23
24/// Connection header (hop-by-hop).
25pub const CONNECTION: &str = "connection";
26
27/// Keep-Alive header (hop-by-hop).
28pub const KEEP_ALIVE: &str = "keep-alive";
29
30/// Proxy-Authenticate header (hop-by-hop).
31pub const PROXY_AUTHENTICATE: &str = "proxy-authenticate";
32
33/// Proxy-Authorization header (hop-by-hop).
34pub const PROXY_AUTHORIZATION: &str = "proxy-authorization";
35
36/// TE header (hop-by-hop).
37pub const TE: &str = "te";
38
39/// Trailers header (hop-by-hop).
40pub const TRAILERS: &str = "trailers";
41
42/// Transfer-Encoding header (hop-by-hop).
43pub const TRANSFER_ENCODING: &str = "transfer-encoding";
44
45/// Upgrade header (hop-by-hop).
46pub const UPGRADE: &str = "upgrade";
47
48/// List of all hop-by-hop headers that should not be forwarded.
49pub const HOP_BY_HOP_HEADERS: &[&str] = &[
50    CONNECTION,
51    KEEP_ALIVE,
52    PROXY_AUTHENTICATE,
53    PROXY_AUTHORIZATION,
54    TE,
55    TRAILERS,
56    TRANSFER_ENCODING,
57    UPGRADE,
58];
59
60/// Check if a header is a hop-by-hop header that shouldn't be forwarded.
61///
62/// # Arguments
63///
64/// * `header_name` - The header name to check (lowercase).
65///
66/// # Returns
67///
68/// `true` if the header is a hop-by-hop header, `false` otherwise.
69///
70/// # Example
71///
72/// ```
73/// use wisegate_core::headers::is_hop_by_hop;
74///
75/// assert!(is_hop_by_hop("connection"));
76/// assert!(is_hop_by_hop("transfer-encoding"));
77/// assert!(!is_hop_by_hop("content-type"));
78/// ```
79pub fn is_hop_by_hop(header_name: &str) -> bool {
80    HOP_BY_HOP_HEADERS.contains(&header_name)
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn test_hop_by_hop_headers() {
89        assert!(is_hop_by_hop(CONNECTION));
90        assert!(is_hop_by_hop(KEEP_ALIVE));
91        assert!(is_hop_by_hop(PROXY_AUTHENTICATE));
92        assert!(is_hop_by_hop(PROXY_AUTHORIZATION));
93        assert!(is_hop_by_hop(TE));
94        assert!(is_hop_by_hop(TRAILERS));
95        assert!(is_hop_by_hop(TRANSFER_ENCODING));
96        assert!(is_hop_by_hop(UPGRADE));
97    }
98
99    #[test]
100    fn test_not_hop_by_hop_headers() {
101        assert!(!is_hop_by_hop(CONTENT_TYPE));
102        assert!(!is_hop_by_hop(HOST));
103        assert!(!is_hop_by_hop(CONTENT_LENGTH));
104        assert!(!is_hop_by_hop(X_FORWARDED_FOR));
105        assert!(!is_hop_by_hop(X_REAL_IP));
106        assert!(!is_hop_by_hop(FORWARDED));
107        assert!(!is_hop_by_hop("authorization"));
108        assert!(!is_hop_by_hop("accept"));
109    }
110
111    #[test]
112    fn test_header_constants_lowercase() {
113        // All header constants should be lowercase for consistent matching
114        assert_eq!(X_FORWARDED_FOR, X_FORWARDED_FOR.to_lowercase());
115        assert_eq!(X_REAL_IP, X_REAL_IP.to_lowercase());
116        assert_eq!(FORWARDED, FORWARDED.to_lowercase());
117        assert_eq!(CONTENT_TYPE, CONTENT_TYPE.to_lowercase());
118        assert_eq!(HOST, HOST.to_lowercase());
119        assert_eq!(CONTENT_LENGTH, CONTENT_LENGTH.to_lowercase());
120    }
121}