/rust/registry/src/index.crates.io-1949cf8c6b5b557f/headers-0.4.1/src/common/connection.rs
Line | Count | Source |
1 | | use std::iter::FromIterator; |
2 | | |
3 | | use http::{HeaderName, HeaderValue}; |
4 | | |
5 | | use self::sealed::AsConnectionOption; |
6 | | use crate::util::FlatCsv; |
7 | | |
8 | | /// `Connection` header, defined in |
9 | | /// [RFC7230](https://datatracker.ietf.org/doc/html/rfc7230#section-6.1) |
10 | | /// |
11 | | /// The `Connection` header field allows the sender to indicate desired |
12 | | /// control options for the current connection. In order to avoid |
13 | | /// confusing downstream recipients, a proxy or gateway MUST remove or |
14 | | /// replace any received connection options before forwarding the |
15 | | /// message. |
16 | | /// |
17 | | /// # ABNF |
18 | | /// |
19 | | /// ```text |
20 | | /// Connection = 1#connection-option |
21 | | /// connection-option = token |
22 | | /// |
23 | | /// # Example values |
24 | | /// * `close` |
25 | | /// * `keep-alive` |
26 | | /// * `upgrade` |
27 | | /// ``` |
28 | | /// |
29 | | /// # Examples |
30 | | /// |
31 | | /// ``` |
32 | | /// use headers::Connection; |
33 | | /// |
34 | | /// let keep_alive = Connection::keep_alive(); |
35 | | /// ``` |
36 | | // This is frequently just 1 or 2 values, so optimize for that case. |
37 | | #[derive(Clone, Debug)] |
38 | | pub struct Connection(FlatCsv); |
39 | | |
40 | | derive_header! { |
41 | | Connection(_), |
42 | | name: CONNECTION |
43 | | } |
44 | | |
45 | | impl Connection { |
46 | | /// A constructor to easily create a `Connection: close` header. |
47 | | #[inline] |
48 | 0 | pub fn close() -> Connection { |
49 | 0 | Connection(HeaderValue::from_static("close").into()) |
50 | 0 | } |
51 | | |
52 | | /// A constructor to easily create a `Connection: keep-alive` header. |
53 | | #[inline] |
54 | 0 | pub fn keep_alive() -> Connection { |
55 | 0 | Connection(HeaderValue::from_static("keep-alive").into()) |
56 | 0 | } |
57 | | |
58 | | /// A constructor to easily create a `Connection: Upgrade` header. |
59 | | #[inline] |
60 | 0 | pub fn upgrade() -> Connection { |
61 | 0 | Connection(HeaderValue::from_static("upgrade").into()) |
62 | 0 | } |
63 | | |
64 | | /// Check if this header contains a given "connection option". |
65 | | /// |
66 | | /// This can be used with various argument types: |
67 | | /// |
68 | | /// - `&str` |
69 | | /// - `&HeaderName` |
70 | | /// - `HeaderName` |
71 | | /// |
72 | | /// # Example |
73 | | /// |
74 | | /// ``` |
75 | | /// extern crate http; |
76 | | /// |
77 | | /// use http::header::UPGRADE; |
78 | | /// use headers::Connection; |
79 | | /// |
80 | | /// let conn = Connection::keep_alive(); |
81 | | /// |
82 | | /// assert!(!conn.contains("close")); |
83 | | /// assert!(!conn.contains(UPGRADE)); |
84 | | /// assert!(conn.contains("keep-alive")); |
85 | | /// assert!(conn.contains("Keep-Alive")); |
86 | | /// ``` |
87 | 0 | pub fn contains(&self, name: impl AsConnectionOption) -> bool { |
88 | 0 | let s = name.as_connection_option(); |
89 | 0 | self.0.iter().any(|opt| opt.eq_ignore_ascii_case(s)) |
90 | 0 | } |
91 | | } |
92 | | |
93 | | impl FromIterator<HeaderName> for Connection { |
94 | 0 | fn from_iter<I>(iter: I) -> Self |
95 | 0 | where |
96 | 0 | I: IntoIterator<Item = HeaderName>, |
97 | | { |
98 | 0 | let flat = iter.into_iter().map(HeaderValue::from).collect(); |
99 | 0 | Connection(flat) |
100 | 0 | } |
101 | | } |
102 | | |
103 | | mod sealed { |
104 | | use http::HeaderName; |
105 | | |
106 | | pub trait AsConnectionOption: Sealed { |
107 | | fn as_connection_option(&self) -> &str; |
108 | | } |
109 | | pub trait Sealed {} |
110 | | |
111 | | impl AsConnectionOption for &str { |
112 | 0 | fn as_connection_option(&self) -> &str { |
113 | 0 | self |
114 | 0 | } |
115 | | } |
116 | | |
117 | | impl Sealed for &str {} |
118 | | |
119 | | impl AsConnectionOption for &HeaderName { |
120 | 0 | fn as_connection_option(&self) -> &str { |
121 | 0 | self.as_ref() |
122 | 0 | } |
123 | | } |
124 | | |
125 | | impl Sealed for &HeaderName {} |
126 | | |
127 | | impl AsConnectionOption for HeaderName { |
128 | 0 | fn as_connection_option(&self) -> &str { |
129 | 0 | self.as_ref() |
130 | 0 | } |
131 | | } |
132 | | |
133 | | impl Sealed for HeaderName {} |
134 | | } |