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