• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //! HTTP [`PseudoHeaders`], HTTP/2 uses a special pseudo-header file beginning
15 //! with the “:” character (ASCII 0x3a) to replace the message start line in
16 //! HTTP/1.x to convey the target URI, request method, and status code of the
17 //! response.
18 //!
19 //!
20 //! # Example
21 //! ```
22 //! use ylong_http::pseudo::PseudoHeaders;
23 //! let mut pseudo = PseudoHeaders::new();
24 //! pseudo.set_method(Some("GET".to_string()));
25 //! assert_eq!(pseudo.method(), Some("GET"));
26 //! ```
27 
28 /// [Pseudo-Header fields] that may appear in http2 and http3 header fields.
29 ///
30 /// [Pseudo-Header fields]: https://httpwg.org/specs/rfc9113.html#PseudoHeaderFields
31 ///
32 /// # Note
33 /// The current structure is not responsible for checking every value.
34 // TODO: 考虑将 PseudoHeaders 拆分成 `RequestPseudo` 和 `ResponsePseudo`.
35 #[derive(Clone, PartialEq, Eq, Debug)]
36 pub struct PseudoHeaders {
37     authority: Option<String>,
38     method: Option<String>,
39     path: Option<String>,
40     scheme: Option<String>,
41     status: Option<String>,
42 }
43 
44 // TODO: 去掉冗余的方法。
45 impl PseudoHeaders {
46     /// Create a new `PseudoHeaders`.
new() -> Self47     pub fn new() -> Self {
48         Self {
49             authority: None,
50             method: None,
51             path: None,
52             scheme: None,
53             status: None,
54         }
55     }
56 
is_empty(&self) -> bool57     pub(crate) fn is_empty(&self) -> bool {
58         self.authority.is_none()
59             && self.method.is_none()
60             && self.path.is_none()
61             && self.scheme.is_none()
62             && self.status.is_none()
63     }
64 
65     /// Check if it contains `Authority`.
contains_authority(&self) -> bool66     pub(crate) fn contains_authority(&self) -> bool {
67         self.authority.is_some()
68     }
69 
70     /// Get the `&str` value of `Authority`.
authority(&self) -> Option<&str>71     pub fn authority(&self) -> Option<&str> {
72         self.authority.as_deref()
73     }
74 
75     /// Set the value of `Authority`.
set_authority(&mut self, authority: Option<String>)76     pub fn set_authority(&mut self, authority: Option<String>) {
77         self.authority = authority;
78     }
79 
80     /// Take the `String` value of `Authority`.
take_authority(&mut self) -> Option<String>81     pub(crate) fn take_authority(&mut self) -> Option<String> {
82         self.authority.take()
83     }
84 
85     /// Check if it contains `Method`.
contains_method(&self) -> bool86     pub(crate) fn contains_method(&self) -> bool {
87         self.method.is_some()
88     }
89 
90     /// Get the `&str` value of `Method`.
method(&self) -> Option<&str>91     pub fn method(&self) -> Option<&str> {
92         self.method.as_deref()
93     }
94 
95     /// Set the value of `Method`.
set_method(&mut self, method: Option<String>)96     pub fn set_method(&mut self, method: Option<String>) {
97         self.method = method;
98     }
99 
100     /// Take the `String` value of `Method`.
take_method(&mut self) -> Option<String>101     pub(crate) fn take_method(&mut self) -> Option<String> {
102         self.method.take()
103     }
104 
105     /// Check if it contains `Path`.
contains_path(&self) -> bool106     pub(crate) fn contains_path(&self) -> bool {
107         self.path.is_some()
108     }
109 
110     /// Get the `&str` value of `Path`.
path(&self) -> Option<&str>111     pub fn path(&self) -> Option<&str> {
112         self.path.as_deref()
113     }
114 
115     /// Set the value of `Path`.
set_path(&mut self, path: Option<String>)116     pub fn set_path(&mut self, path: Option<String>) {
117         self.path = path;
118     }
119 
120     /// Take the `String` value of `Path`.
take_path(&mut self) -> Option<String>121     pub(crate) fn take_path(&mut self) -> Option<String> {
122         self.path.take()
123     }
124 
125     /// Check if it contains `Scheme`.
contains_scheme(&self) -> bool126     pub(crate) fn contains_scheme(&self) -> bool {
127         self.scheme.is_some()
128     }
129 
130     /// Get the `&str` value of `Scheme`.
scheme(&self) -> Option<&str>131     pub fn scheme(&self) -> Option<&str> {
132         self.scheme.as_deref()
133     }
134 
135     /// Set the value of `Scheme`.
set_scheme(&mut self, scheme: Option<String>)136     pub fn set_scheme(&mut self, scheme: Option<String>) {
137         self.scheme = scheme;
138     }
139 
140     /// Take the `String` value of `Scheme`.
take_scheme(&mut self) -> Option<String>141     pub(crate) fn take_scheme(&mut self) -> Option<String> {
142         self.scheme.take()
143     }
144 
145     /// Check if it contains `Status`.
contains_status(&self) -> bool146     pub(crate) fn contains_status(&self) -> bool {
147         self.status.is_some()
148     }
149 
150     /// Get the `&str` value of `Status`.
status(&self) -> Option<&str>151     pub fn status(&self) -> Option<&str> {
152         self.status.as_deref()
153     }
154 
155     /// Set the value of `Status`.
set_status(&mut self, status: Option<String>)156     pub fn set_status(&mut self, status: Option<String>) {
157         self.status = status;
158     }
159 
160     /// Take the `String` value of `Status`.
take_status(&mut self) -> Option<String>161     pub(crate) fn take_status(&mut self) -> Option<String> {
162         self.status.take()
163     }
164 }
165 
166 impl Default for PseudoHeaders {
default() -> Self167     fn default() -> Self {
168         PseudoHeaders::new()
169     }
170 }
171 
172 #[cfg(test)]
173 mod ut_pseudo_headers {
174     use crate::pseudo::PseudoHeaders;
175 
176     /// UT test cases for `PseudoHeaders::new`.
177     ///
178     /// # Brief
179     /// 1. Calls `PseudoHeaders::new` to create a `PseudoHeaders`.
180     /// 2. Checks if the result has a default value.
181     #[test]
ut_pseudo_headers_new()182     fn ut_pseudo_headers_new() {
183         let pseudo = PseudoHeaders::new();
184         assert!(pseudo.authority.is_none());
185         assert!(pseudo.method.is_none());
186         assert!(pseudo.path.is_none());
187         assert!(pseudo.scheme.is_none());
188         assert!(pseudo.status.is_none());
189     }
190 
191     /// UT test cases for `PseudoHeaders::contains_authority`.
192     ///
193     /// # Brief
194     /// 1. Creates a `PseudoHeaders`.
195     /// 2. Calls `PseudoHeaders::contains_authority` of it.
196     /// 3. Calls `PseudoHeaders::contains_authority` of it after its `authority`
197     ///    is set.
198     /// 4. Checks the results.
199     #[test]
ut_pseudo_headers_contains_authority()200     fn ut_pseudo_headers_contains_authority() {
201         let mut pseudo = PseudoHeaders::new();
202         assert!(!pseudo.contains_authority());
203 
204         pseudo.authority = Some(String::from("authority"));
205         assert!(pseudo.contains_authority());
206     }
207 
208     /// UT test cases for `PseudoHeaders::authority`.
209     ///
210     /// # Brief
211     /// 1. Creates a `PseudoHeaders`.
212     /// 2. Calls `PseudoHeaders::authority` of it.
213     /// 3. Calls `PseudoHeaders::authority` of it after its `authority` is set.
214     /// 4. Checks the results.
215     #[test]
ut_pseudo_headers_authority()216     fn ut_pseudo_headers_authority() {
217         let mut pseudo = PseudoHeaders::new();
218         assert!(pseudo.authority().is_none());
219 
220         pseudo.authority = Some(String::from("authority"));
221         assert_eq!(pseudo.authority(), Some("authority"));
222     }
223 
224     /// UT test cases for `PseudoHeaders::set_authority`.
225     ///
226     /// # Brief
227     /// 1. Creates a `PseudoHeaders`.
228     /// 2. Calls `PseudoHeaders::set_authority` of it to set `authority` a
229     ///    value.
230     /// 3. Checks the results.
231     #[test]
ut_pseudo_headers_set_authority()232     fn ut_pseudo_headers_set_authority() {
233         let mut pseudo = PseudoHeaders::new();
234         assert!(pseudo.authority().is_none());
235 
236         pseudo.set_authority(Some(String::from("authority")));
237         assert_eq!(pseudo.authority(), Some("authority"));
238 
239         pseudo.set_authority(None);
240         assert!(pseudo.authority().is_none());
241     }
242 
243     /// UT test cases for `PseudoHeaders::take_authority`.
244     ///
245     /// # Brief
246     /// 1. Creates a `PseudoHeaders`.
247     /// 2. Calls `PseudoHeaders::take_authority` of it.
248     /// 3. Calls `PseudoHeaders::take_authority` of it after its `authority` is
249     ///    set.
250     /// 4. Checks the results.
251     #[test]
ut_pseudo_headers_take_authority()252     fn ut_pseudo_headers_take_authority() {
253         let mut pseudo = PseudoHeaders::new();
254         assert!(pseudo.take_authority().is_none());
255 
256         pseudo.authority = Some(String::from("authority"));
257         assert_eq!(pseudo.take_authority(), Some(String::from("authority")));
258     }
259 
260     /// UT test cases for `PseudoHeaders::contains_method`.
261     ///
262     /// # Brief
263     /// 1. Creates a `PseudoHeaders`.
264     /// 2. Calls `PseudoHeaders::contains_method` of it.
265     /// 3. Calls `PseudoHeaders::contains_method` of it after its `method` is
266     ///    set.
267     /// 4. Checks the results.
268     #[test]
ut_pseudo_headers_contains_method()269     fn ut_pseudo_headers_contains_method() {
270         let mut pseudo = PseudoHeaders::new();
271         assert!(!pseudo.contains_method());
272 
273         pseudo.method = Some(String::from("method"));
274         assert!(pseudo.contains_method());
275     }
276 
277     /// UT test cases for `PseudoHeaders::method`.
278     ///
279     /// # Brief
280     /// 1. Creates a `PseudoHeaders`.
281     /// 2. Calls `PseudoHeaders::method` of it.
282     /// 3. Calls `PseudoHeaders::method` of it after its `method` is set.
283     /// 4. Checks the results.
284     #[test]
ut_pseudo_headers_method()285     fn ut_pseudo_headers_method() {
286         let mut pseudo = PseudoHeaders::new();
287         assert!(pseudo.method().is_none());
288 
289         pseudo.method = Some(String::from("method"));
290         assert_eq!(pseudo.method(), Some("method"));
291     }
292 
293     /// UT test cases for `PseudoHeaders::set_method`.
294     ///
295     /// # Brief
296     /// 1. Creates a `PseudoHeaders`.
297     /// 2. Calls `PseudoHeaders::set_method` of it to set `method` a value.
298     /// 3. Checks the results.
299     #[test]
ut_pseudo_headers_set_method()300     fn ut_pseudo_headers_set_method() {
301         let mut pseudo = PseudoHeaders::new();
302         assert!(pseudo.method().is_none());
303 
304         pseudo.set_method(Some(String::from("method")));
305         assert_eq!(pseudo.method(), Some("method"));
306 
307         pseudo.set_method(None);
308         assert!(pseudo.method().is_none());
309     }
310 
311     /// UT test cases for `PseudoHeaders::take_method`.
312     ///
313     /// # Brief
314     /// 1. Creates a `PseudoHeaders`.
315     /// 2. Calls `PseudoHeaders::take_method` of it.
316     /// 3. Calls `PseudoHeaders::take_method` of it after its `method` is set.
317     /// 4. Checks the results.
318     #[test]
ut_pseudo_headers_take_method()319     fn ut_pseudo_headers_take_method() {
320         let mut pseudo = PseudoHeaders::new();
321         assert!(pseudo.take_method().is_none());
322 
323         pseudo.method = Some(String::from("method"));
324         assert_eq!(pseudo.take_method(), Some(String::from("method")));
325     }
326 
327     /// UT test cases for `PseudoHeaders::contains_path`.
328     ///
329     /// # Brief
330     /// 1. Creates a `PseudoHeaders`.
331     /// 2. Calls `PseudoHeaders::contains_path` of it.
332     /// 3. Calls `PseudoHeaders::contains_path` of it after its `path` is set.
333     /// 4. Checks the results.
334     #[test]
ut_pseudo_headers_contains_path()335     fn ut_pseudo_headers_contains_path() {
336         let mut pseudo = PseudoHeaders::new();
337         assert!(!pseudo.contains_path());
338 
339         pseudo.path = Some(String::from("path"));
340         assert!(pseudo.contains_path());
341     }
342 
343     /// UT test cases for `PseudoHeaders::path`.
344     ///
345     /// # Brief
346     /// 1. Creates a `PseudoHeaders`.
347     /// 2. Calls `PseudoHeaders::path` of it.
348     /// 3. Calls `PseudoHeaders::path` of it after its `path` is set.
349     /// 4. Checks the results.
350     #[test]
ut_pseudo_headers_path()351     fn ut_pseudo_headers_path() {
352         let mut pseudo = PseudoHeaders::new();
353         assert!(pseudo.path().is_none());
354 
355         pseudo.path = Some(String::from("path"));
356         assert_eq!(pseudo.path(), Some("path"));
357     }
358 
359     /// UT test cases for `PseudoHeaders::set_path`.
360     ///
361     /// # Brief
362     /// 1. Creates a `PseudoHeaders`.
363     /// 2. Calls `PseudoHeaders::set_path` of it to set `path` a value.
364     /// 3. Checks the results.
365     #[test]
ut_pseudo_headers_set_path()366     fn ut_pseudo_headers_set_path() {
367         let mut pseudo = PseudoHeaders::new();
368         assert!(pseudo.path().is_none());
369 
370         pseudo.set_path(Some(String::from("path")));
371         assert_eq!(pseudo.path(), Some("path"));
372 
373         pseudo.set_path(None);
374         assert!(pseudo.path().is_none());
375     }
376 
377     /// UT test cases for `PseudoHeaders::take_path`.
378     ///
379     /// # Brief
380     /// 1. Creates a `PseudoHeaders`.
381     /// 2. Calls `PseudoHeaders::take_path` of it.
382     /// 3. Calls `PseudoHeaders::take_path` of it after its `path` is set.
383     /// 4. Checks the results.
384     #[test]
ut_pseudo_headers_take_path()385     fn ut_pseudo_headers_take_path() {
386         let mut pseudo = PseudoHeaders::new();
387         assert!(pseudo.take_path().is_none());
388 
389         pseudo.path = Some(String::from("path"));
390         assert_eq!(pseudo.take_path(), Some(String::from("path")));
391     }
392 
393     /// UT test cases for `PseudoHeaders::contains_scheme`.
394     ///
395     /// # Brief
396     /// 1. Creates a `PseudoHeaders`.
397     /// 2. Calls `PseudoHeaders::contains_scheme` of it.
398     /// 3. Calls `PseudoHeaders::contains_scheme` of it after its `scheme` is
399     ///    set.
400     /// 4. Checks the results.
401     #[test]
ut_pseudo_headers_contains_scheme()402     fn ut_pseudo_headers_contains_scheme() {
403         let mut pseudo = PseudoHeaders::new();
404         assert!(!pseudo.contains_scheme());
405 
406         pseudo.scheme = Some(String::from("scheme"));
407         assert!(pseudo.contains_scheme());
408     }
409 
410     /// UT test cases for `PseudoHeaders::scheme`.
411     ///
412     /// # Brief
413     /// 1. Creates a `PseudoHeaders`.
414     /// 2. Calls `PseudoHeaders::scheme` of it.
415     /// 3. Calls `PseudoHeaders::scheme` of it after its `scheme` is set.
416     /// 4. Checks the results.
417     #[test]
ut_pseudo_headers_scheme()418     fn ut_pseudo_headers_scheme() {
419         let mut pseudo = PseudoHeaders::new();
420         assert!(pseudo.scheme().is_none());
421 
422         pseudo.scheme = Some(String::from("scheme"));
423         assert_eq!(pseudo.scheme(), Some("scheme"));
424     }
425 
426     /// UT test cases for `PseudoHeaders::set_scheme`.
427     ///
428     /// # Brief
429     /// 1. Creates a `PseudoHeaders`.
430     /// 2. Calls `PseudoHeaders::set_scheme` of it to set `scheme` a value.
431     /// 3. Checks the results.
432     #[test]
ut_pseudo_headers_set_scheme()433     fn ut_pseudo_headers_set_scheme() {
434         let mut pseudo = PseudoHeaders::new();
435         assert!(pseudo.scheme().is_none());
436 
437         pseudo.set_scheme(Some(String::from("scheme")));
438         assert_eq!(pseudo.scheme(), Some("scheme"));
439 
440         pseudo.set_scheme(None);
441         assert!(pseudo.scheme().is_none());
442     }
443 
444     /// UT test cases for `PseudoHeaders::take_scheme`.
445     ///
446     /// # Brief
447     /// 1. Creates a `PseudoHeaders`.
448     /// 2. Calls `PseudoHeaders::take_scheme` of it.
449     /// 3. Calls `PseudoHeaders::take_scheme` of it after its `scheme` is set.
450     /// 4. Checks the results.
451     #[test]
ut_pseudo_headers_take_scheme()452     fn ut_pseudo_headers_take_scheme() {
453         let mut pseudo = PseudoHeaders::new();
454         assert!(pseudo.take_scheme().is_none());
455 
456         pseudo.scheme = Some(String::from("scheme"));
457         assert_eq!(pseudo.take_scheme(), Some(String::from("scheme")));
458     }
459 
460     /// UT test cases for `PseudoHeaders::contains_status`.
461     ///
462     /// # Brief
463     /// 1. Creates a `PseudoHeaders`.
464     /// 2. Calls `PseudoHeaders::contains_status` of it.
465     /// 3. Calls `PseudoHeaders::contains_status` of it after its `status` is
466     ///    set.
467     /// 4. Checks the results.
468     #[test]
ut_pseudo_headers_contains_status()469     fn ut_pseudo_headers_contains_status() {
470         let mut pseudo = PseudoHeaders::new();
471         assert!(!pseudo.contains_status());
472 
473         pseudo.status = Some(String::from("status"));
474         assert!(pseudo.contains_status());
475     }
476 
477     /// UT test cases for `PseudoHeaders::status`.
478     ///
479     /// # Brief
480     /// 1. Creates a `PseudoHeaders`.
481     /// 2. Calls `PseudoHeaders::status` of it.
482     /// 3. Calls `PseudoHeaders::status` of it after its `status` is set.
483     /// 4. Checks the results.
484     #[test]
ut_pseudo_headers_status()485     fn ut_pseudo_headers_status() {
486         let mut pseudo = PseudoHeaders::new();
487         assert!(pseudo.status().is_none());
488 
489         pseudo.status = Some(String::from("status"));
490         assert_eq!(pseudo.status(), Some("status"));
491     }
492 
493     /// UT test cases for `PseudoHeaders::set_status`.
494     ///
495     /// # Brief
496     /// 1. Creates a `PseudoHeaders`.
497     /// 2. Calls `PseudoHeaders::set_status` of it to set `status` a value.
498     /// 3. Checks the results.
499     #[test]
ut_pseudo_headers_set_status()500     fn ut_pseudo_headers_set_status() {
501         let mut pseudo = PseudoHeaders::new();
502         assert!(pseudo.status().is_none());
503 
504         pseudo.set_status(Some(String::from("status")));
505         assert_eq!(pseudo.status(), Some("status"));
506 
507         pseudo.set_status(None);
508         assert!(pseudo.status().is_none());
509     }
510 
511     /// UT test cases for `PseudoHeaders::take_status`.
512     ///
513     /// # Brief
514     /// 1. Creates a `PseudoHeaders`.
515     /// 2. Calls `PseudoHeaders::take_status` of it.
516     /// 3. Calls `PseudoHeaders::take_status` of it after its `status` is set.
517     /// 4. Checks the results.
518     #[test]
ut_pseudo_headers_take_status()519     fn ut_pseudo_headers_take_status() {
520         let mut pseudo = PseudoHeaders::new();
521         assert!(pseudo.take_status().is_none());
522 
523         pseudo.status = Some(String::from("status"));
524         assert_eq!(pseudo.take_status(), Some(String::from("status")));
525     }
526 }
527