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 [`Request`][http_request]. 15 //! 16 //! This module provides [`Request`][my_request], [`RequestBuilder`] and 17 //! [`RequestPart`]. 18 //! 19 //! [http_request]: https://www.rfc-editor.org/rfc/rfc9112.html#request.line 20 //! [my_request]: Request 21 //! [`RequestBuilder`]: RequestBuilder 22 //! [`RequestPart`]: RequestPart 23 //! 24 //! # Examples 25 //! 26 //! ``` 27 //! use ylong_http::request::method::Method; 28 //! use ylong_http::request::{Request, RequestBuilder}; 29 //! use ylong_http::version::Version; 30 //! 31 //! // Uses `RequestBuilder` to construct a `Request`. 32 //! let request = Request::builder() 33 //! .method("GET") 34 //! .url("www.example.com") 35 //! .version("HTTP/1.1") 36 //! .header("ACCEPT", "text/html") 37 //! .append_header("ACCEPT", "application/xml") 38 //! .body(()) 39 //! .unwrap(); 40 //! 41 //! assert_eq!(request.method(), &Method::GET); 42 //! assert_eq!(request.uri().to_string(), "www.example.com"); 43 //! assert_eq!(request.version(), &Version::HTTP1_1); 44 //! assert_eq!( 45 //! request 46 //! .headers() 47 //! .get("accept") 48 //! .unwrap() 49 //! .to_string() 50 //! .unwrap(), 51 //! "text/html, application/xml" 52 //! ); 53 //! ``` 54 55 pub mod method; 56 pub mod uri; 57 58 use core::convert::TryFrom; 59 60 use method::Method; 61 use uri::Uri; 62 63 #[cfg(any(feature = "ylong_base", feature = "tokio_base"))] 64 use crate::body::{MultiPart, MultiPartBase}; 65 use crate::error::{ErrorKind, HttpError}; 66 use crate::headers::{Header, HeaderName, HeaderValue, Headers}; 67 use crate::version::Version; 68 69 /// HTTP `Request`. A `Request` consists of a request line and a body. 70 /// 71 /// # Examples 72 /// 73 /// ``` 74 /// use ylong_http::request::Request; 75 /// 76 /// let request = Request::new("this is a body"); 77 /// assert_eq!(request.body(), &"this is a body"); 78 /// ``` 79 pub struct Request<T> { 80 part: RequestPart, 81 body: T, 82 } 83 84 impl Request<()> { 85 /// Creates a new, default `RequestBuilder`. 86 /// 87 /// # Examples 88 /// 89 /// ``` 90 /// use ylong_http::request::Request; 91 /// 92 /// let builder = Request::builder(); 93 /// ``` builder() -> RequestBuilder94 pub fn builder() -> RequestBuilder { 95 RequestBuilder::new() 96 } 97 98 /// Creates a `RequestBuilder` for the given `Uri` with method set to `GET`. 99 /// 100 /// # Examples 101 /// 102 /// ``` 103 /// use ylong_http::request::Request; 104 /// 105 /// let request = Request::get("www.example.com").body(()).unwrap(); 106 /// ``` get<T>(uri: T) -> RequestBuilder where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<HttpError>,107 pub fn get<T>(uri: T) -> RequestBuilder 108 where 109 Uri: TryFrom<T>, 110 <Uri as TryFrom<T>>::Error: Into<HttpError>, 111 { 112 RequestBuilder::new().method(Method::GET).url(uri) 113 } 114 115 /// Creates a `RequestBuilder` for the given `Uri` with method set to 116 /// `HEAD`. 117 /// 118 /// # Examples 119 /// 120 /// ``` 121 /// use ylong_http::request::Request; 122 /// 123 /// let request = Request::head("www.example.com").body(()).unwrap(); 124 /// ``` head<T>(uri: T) -> RequestBuilder where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<HttpError>,125 pub fn head<T>(uri: T) -> RequestBuilder 126 where 127 Uri: TryFrom<T>, 128 <Uri as TryFrom<T>>::Error: Into<HttpError>, 129 { 130 RequestBuilder::new().method(Method::HEAD).url(uri) 131 } 132 133 /// Creates a `RequestBuilder` for the given `Uri` with method set to 134 /// `POST`. 135 /// 136 /// # Examples 137 /// 138 /// ``` 139 /// use ylong_http::request::Request; 140 /// 141 /// let request = Request::post("www.example.com").body(()).unwrap(); 142 /// ``` post<T>(uri: T) -> RequestBuilder where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<HttpError>,143 pub fn post<T>(uri: T) -> RequestBuilder 144 where 145 Uri: TryFrom<T>, 146 <Uri as TryFrom<T>>::Error: Into<HttpError>, 147 { 148 RequestBuilder::new().method(Method::POST).url(uri) 149 } 150 151 /// Creates a `RequestBuilder` for the given `Uri` with method set to `PUT`. 152 /// 153 /// # Examples 154 /// 155 /// ``` 156 /// use ylong_http::request::Request; 157 /// 158 /// let request = Request::put("www.example.com").body(()).unwrap(); 159 /// ``` put<T>(uri: T) -> RequestBuilder where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<HttpError>,160 pub fn put<T>(uri: T) -> RequestBuilder 161 where 162 Uri: TryFrom<T>, 163 <Uri as TryFrom<T>>::Error: Into<HttpError>, 164 { 165 RequestBuilder::new().method(Method::PUT).url(uri) 166 } 167 168 /// Creates a `RequestBuilder` for the given `Uri` with method set to 169 /// `DELETE`. 170 /// 171 /// # Examples 172 /// 173 /// ``` 174 /// use ylong_http::request::Request; 175 /// 176 /// let request = Request::delete("www.example.com").body(()).unwrap(); 177 /// ``` delete<T>(uri: T) -> RequestBuilder where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<HttpError>,178 pub fn delete<T>(uri: T) -> RequestBuilder 179 where 180 Uri: TryFrom<T>, 181 <Uri as TryFrom<T>>::Error: Into<HttpError>, 182 { 183 RequestBuilder::new().method(Method::DELETE).url(uri) 184 } 185 186 /// Creates a `RequestBuilder` for the given `Uri` with method set to 187 /// `CONNECT`. 188 /// 189 /// # Examples 190 /// 191 /// ``` 192 /// use ylong_http::request::Request; 193 /// 194 /// let request = Request::connect("www.example.com").body(()).unwrap(); 195 /// ``` connect<T>(uri: T) -> RequestBuilder where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<HttpError>,196 pub fn connect<T>(uri: T) -> RequestBuilder 197 where 198 Uri: TryFrom<T>, 199 <Uri as TryFrom<T>>::Error: Into<HttpError>, 200 { 201 RequestBuilder::new().method(Method::CONNECT).url(uri) 202 } 203 204 /// Creates a `RequestBuilder` for the given `Uri` with method set to 205 /// `OPTIONS`. 206 /// 207 /// # Examples 208 /// 209 /// ``` 210 /// use ylong_http::request::Request; 211 /// 212 /// let request = Request::options("www.example.com").body(()).unwrap(); 213 /// ``` options<T>(uri: T) -> RequestBuilder where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<HttpError>,214 pub fn options<T>(uri: T) -> RequestBuilder 215 where 216 Uri: TryFrom<T>, 217 <Uri as TryFrom<T>>::Error: Into<HttpError>, 218 { 219 RequestBuilder::new().method(Method::OPTIONS).url(uri) 220 } 221 222 /// Creates a `RequestBuilder` for the given `Uri` with method set to 223 /// `TRACE`. 224 /// 225 /// # Examples 226 /// 227 /// ``` 228 /// use ylong_http::request::Request; 229 /// 230 /// let request = Request::trace("www.example.com").body(()).unwrap(); 231 /// ``` trace<T>(uri: T) -> RequestBuilder where Uri: TryFrom<T>, HttpError: From<<Uri as TryFrom<T>>::Error>,232 pub fn trace<T>(uri: T) -> RequestBuilder 233 where 234 Uri: TryFrom<T>, 235 HttpError: From<<Uri as TryFrom<T>>::Error>, 236 { 237 RequestBuilder::new().method(Method::TRACE).url(uri) 238 } 239 } 240 241 impl<T> Request<T> { 242 /// Creates a new, default `Request` with options set default. 243 /// 244 /// # Examples 245 /// 246 /// ``` 247 /// use ylong_http::request::RequestBuilder; 248 /// 249 /// let builder = RequestBuilder::new(); 250 /// ``` new(body: T) -> Self251 pub fn new(body: T) -> Self { 252 Request { 253 part: Default::default(), 254 body, 255 } 256 } 257 258 /// Gets an immutable reference to the `Method`. 259 /// 260 /// # Examples 261 /// 262 /// ``` 263 /// use ylong_http::request::Request; 264 /// 265 /// let request = Request::new(()); 266 /// let method = request.method(); 267 /// ``` method(&self) -> &Method268 pub fn method(&self) -> &Method { 269 &self.part.method 270 } 271 272 /// Gets a mutable reference to the `Method`. 273 /// 274 /// # Examples 275 /// 276 /// ``` 277 /// use ylong_http::request::Request; 278 /// 279 /// let mut request = Request::new(()); 280 /// let method = request.method_mut(); 281 /// ``` method_mut(&mut self) -> &mut Method282 pub fn method_mut(&mut self) -> &mut Method { 283 &mut self.part.method 284 } 285 286 /// Gets an immutable reference to the `Uri`. 287 /// 288 /// # Examples 289 /// 290 /// ``` 291 /// use ylong_http::request::Request; 292 /// 293 /// let request = Request::new(()); 294 /// let uri = request.uri(); 295 /// ``` uri(&self) -> &Uri296 pub fn uri(&self) -> &Uri { 297 &self.part.uri 298 } 299 300 /// Gets a mutable reference to the `Uri`. 301 /// 302 /// # Examples 303 /// 304 /// ``` 305 /// use ylong_http::request::Request; 306 /// 307 /// let mut request = Request::new(()); 308 /// let uri = request.uri_mut(); 309 /// ``` uri_mut(&mut self) -> &mut Uri310 pub fn uri_mut(&mut self) -> &mut Uri { 311 &mut self.part.uri 312 } 313 314 /// Gets an immutable reference to the `Version`. 315 /// 316 /// # Examples 317 /// 318 /// ``` 319 /// use ylong_http::request::Request; 320 /// 321 /// let request = Request::new(()); 322 /// let version = request.version(); 323 /// ``` version(&self) -> &Version324 pub fn version(&self) -> &Version { 325 &self.part.version 326 } 327 328 /// Gets a mutable reference to the `Version`. 329 /// 330 /// # Examples 331 /// 332 /// ``` 333 /// use ylong_http::request::Request; 334 /// 335 /// let mut request = Request::new(()); 336 /// let version = request.version_mut(); 337 /// ``` version_mut(&mut self) -> &mut Version338 pub fn version_mut(&mut self) -> &mut Version { 339 &mut self.part.version 340 } 341 342 /// Gets an immutable reference to the `Headers`. 343 /// 344 /// # Examples 345 /// 346 /// ``` 347 /// use ylong_http::request::Request; 348 /// 349 /// let request = Request::new(()); 350 /// let headers = request.headers(); 351 /// ``` headers(&self) -> &Headers352 pub fn headers(&self) -> &Headers { 353 &self.part.headers 354 } 355 356 /// Gets a mutable reference to the `Headers`. 357 /// 358 /// # Examples 359 /// 360 /// ``` 361 /// use ylong_http::request::Request; 362 /// 363 /// let mut request = Request::new(()); 364 /// let headers = request.headers_mut(); 365 /// ``` headers_mut(&mut self) -> &mut Headers366 pub fn headers_mut(&mut self) -> &mut Headers { 367 &mut self.part.headers 368 } 369 370 /// Gets an immutable reference to the `RequestPart`. 371 /// 372 /// # Examples 373 /// 374 /// ``` 375 /// use ylong_http::request::Request; 376 /// 377 /// let request = Request::new(()); 378 /// let part = request.part(); 379 /// ``` part(&self) -> &RequestPart380 pub fn part(&self) -> &RequestPart { 381 &self.part 382 } 383 384 /// Gets a mutable reference to the `RequestPart`. 385 /// 386 /// # Examples 387 /// 388 /// ``` 389 /// use ylong_http::request::Request; 390 /// 391 /// let mut request = Request::new(()); 392 /// let part = request.part_mut(); 393 /// ``` part_mut(&mut self) -> &RequestPart394 pub fn part_mut(&mut self) -> &RequestPart { 395 &mut self.part 396 } 397 398 /// Gets an immutable reference to the `Body`. 399 /// 400 /// # Examples 401 /// 402 /// ``` 403 /// use ylong_http::request::Request; 404 /// 405 /// let request = Request::new(()); 406 /// let body = request.body(); 407 /// ``` body(&self) -> &T408 pub fn body(&self) -> &T { 409 &self.body 410 } 411 412 /// Gets a mutable reference to the `Body`. 413 /// 414 /// # Examples 415 /// 416 /// ``` 417 /// use ylong_http::request::Request; 418 /// 419 /// let mut request = Request::new(()); 420 /// let body = request.body_mut(); 421 /// ``` body_mut(&mut self) -> &mut T422 pub fn body_mut(&mut self) -> &mut T { 423 &mut self.body 424 } 425 426 /// Splits `Request` into `RequestPart` and `Body`. 427 /// 428 /// # Examples 429 /// ``` 430 /// use ylong_http::request::{Request, RequestPart}; 431 /// 432 /// let request = Request::new(()); 433 /// let (part, body) = request.into_parts(); 434 /// ``` into_parts(self) -> (RequestPart, T)435 pub fn into_parts(self) -> (RequestPart, T) { 436 (self.part, self.body) 437 } 438 439 /// Combines `RequestPart` and `Body` into a `Request`. 440 /// 441 /// # Examples 442 /// 443 /// ``` 444 /// use ylong_http::request::{Request, RequestPart}; 445 /// 446 /// let part = RequestPart::default(); 447 /// let body = (); 448 /// let request = Request::from_raw_parts(part, body); 449 /// ``` from_raw_parts(part: RequestPart, body: T) -> Request<T>450 pub fn from_raw_parts(part: RequestPart, body: T) -> Request<T> { 451 Request { part, body } 452 } 453 } 454 455 impl<T: Clone> Clone for Request<T> { clone(&self) -> Self456 fn clone(&self) -> Self { 457 Request::from_raw_parts(self.part.clone(), self.body.clone()) 458 } 459 } 460 461 /// A builder which is used to construct `Request`. 462 /// 463 /// # Examples 464 /// 465 /// ``` 466 /// use ylong_http::headers::Headers; 467 /// use ylong_http::request::method::Method; 468 /// use ylong_http::request::RequestBuilder; 469 /// use ylong_http::version::Version; 470 /// 471 /// let request = RequestBuilder::new() 472 /// .method("GET") 473 /// .url("www.example.com") 474 /// .version("HTTP/1.1") 475 /// .header("ACCEPT", "text/html") 476 /// .append_header("ACCEPT", "application/xml") 477 /// .body(()) 478 /// .unwrap(); 479 /// 480 /// assert_eq!(request.method(), &Method::GET); 481 /// assert_eq!(request.uri().to_string(), "www.example.com"); 482 /// assert_eq!(request.version(), &Version::HTTP1_1); 483 /// assert_eq!( 484 /// request 485 /// .headers() 486 /// .get("accept") 487 /// .unwrap() 488 /// .to_string() 489 /// .unwrap(), 490 /// "text/html, application/xml" 491 /// ); 492 /// ``` 493 pub struct RequestBuilder { 494 part: Result<RequestPart, HttpError>, 495 } 496 497 impl RequestBuilder { 498 /// Creates a new, default `RequestBuilder`. 499 /// 500 /// # Examples 501 /// 502 /// ``` 503 /// use ylong_http::request::RequestBuilder; 504 /// 505 /// let builder = RequestBuilder::new(); 506 /// ``` new() -> Self507 pub fn new() -> Self { 508 RequestBuilder { 509 part: Ok(RequestPart::default()), 510 } 511 } 512 513 /// Sets the `Method` of the `Request`. 514 /// 515 /// # Examples 516 /// 517 /// ``` 518 /// use ylong_http::request::RequestBuilder; 519 /// 520 /// let builder = RequestBuilder::new().method("GET"); 521 /// ``` method<T>(mut self, method: T) -> Self where Method: TryFrom<T>, <Method as TryFrom<T>>::Error: Into<HttpError>,522 pub fn method<T>(mut self, method: T) -> Self 523 where 524 Method: TryFrom<T>, 525 <Method as TryFrom<T>>::Error: Into<HttpError>, 526 { 527 self.part = self.part.and_then(move |mut part| { 528 part.method = Method::try_from(method).map_err(Into::into)?; 529 Ok(part) 530 }); 531 self 532 } 533 534 /// Sets the `Uri` of the `Request`. `Uri` does not provide a default value, 535 /// so it must be set. 536 /// 537 /// # Examples 538 /// 539 /// ``` 540 /// use ylong_http::request::RequestBuilder; 541 /// 542 /// let builder = RequestBuilder::new().url("www.example.com"); 543 /// ``` url<T>(mut self, uri: T) -> Self where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<HttpError>,544 pub fn url<T>(mut self, uri: T) -> Self 545 where 546 Uri: TryFrom<T>, 547 <Uri as TryFrom<T>>::Error: Into<HttpError>, 548 { 549 self.part = self.part.and_then(move |mut part| { 550 part.uri = Uri::try_from(uri).map_err(Into::into)?; 551 Ok(part) 552 }); 553 self 554 } 555 556 /// Sets the `Version` of the `Request`. Uses `Version::HTTP1_1` by default. 557 /// 558 /// # Examples 559 /// 560 /// ``` 561 /// use ylong_http::request::RequestBuilder; 562 /// 563 /// let request = RequestBuilder::new().version("HTTP/1.1"); 564 /// ``` version<T>(mut self, version: T) -> Self where Version: TryFrom<T>, <Version as TryFrom<T>>::Error: Into<HttpError>,565 pub fn version<T>(mut self, version: T) -> Self 566 where 567 Version: TryFrom<T>, 568 <Version as TryFrom<T>>::Error: Into<HttpError>, 569 { 570 self.part = self.part.and_then(move |mut part| { 571 part.version = Version::try_from(version).map_err(Into::into)?; 572 Ok(part) 573 }); 574 self 575 } 576 577 /// Adds a `Header` to `Request`. Overwrites `HeaderValue` if the 578 /// `HeaderName` already exists. 579 /// 580 /// # Examples 581 /// 582 /// ``` 583 /// use ylong_http::headers::Headers; 584 /// use ylong_http::request::RequestBuilder; 585 /// 586 /// let request = RequestBuilder::new().header("ACCEPT", "text/html"); 587 /// ``` header<N, V>(mut self, name: N, value: V) -> Self where HeaderName: TryFrom<N>, <HeaderName as TryFrom<N>>::Error: Into<HttpError>, HeaderValue: TryFrom<V>, <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,588 pub fn header<N, V>(mut self, name: N, value: V) -> Self 589 where 590 HeaderName: TryFrom<N>, 591 <HeaderName as TryFrom<N>>::Error: Into<HttpError>, 592 HeaderValue: TryFrom<V>, 593 <HeaderValue as TryFrom<V>>::Error: Into<HttpError>, 594 { 595 self.part = self.part.and_then(move |mut part| { 596 part.headers.insert(name, value)?; 597 Ok(part) 598 }); 599 self 600 } 601 602 /// Adds a `Header` to `Request`. Appends `HeaderValue` to the end of 603 /// previous `HeaderValue` if the `HeaderName` already exists. 604 /// 605 /// # Examples 606 /// 607 /// ``` 608 /// use ylong_http::headers::Headers; 609 /// use ylong_http::request::RequestBuilder; 610 /// 611 /// let request = RequestBuilder::new().append_header("ACCEPT", "text/html"); 612 /// ``` append_header<N, V>(mut self, name: N, value: V) -> Self where HeaderName: TryFrom<N>, <HeaderName as TryFrom<N>>::Error: Into<HttpError>, HeaderValue: TryFrom<V>, <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,613 pub fn append_header<N, V>(mut self, name: N, value: V) -> Self 614 where 615 HeaderName: TryFrom<N>, 616 <HeaderName as TryFrom<N>>::Error: Into<HttpError>, 617 HeaderValue: TryFrom<V>, 618 <HeaderValue as TryFrom<V>>::Error: Into<HttpError>, 619 { 620 self.part = self.part.and_then(move |mut part| { 621 part.headers.append(name, value)?; 622 Ok(part) 623 }); 624 self 625 } 626 627 /// Try to create a `Request` based on the incoming `body`. 628 /// 629 /// # Examples 630 /// 631 /// ``` 632 /// use ylong_http::request::RequestBuilder; 633 /// 634 /// let request = RequestBuilder::new().body(()).unwrap(); 635 /// ``` body<T>(self, body: T) -> Result<Request<T>, HttpError>636 pub fn body<T>(self, body: T) -> Result<Request<T>, HttpError> { 637 Ok(Request { 638 part: self.part?, 639 body, 640 }) 641 } 642 } 643 644 impl Default for RequestBuilder { default() -> Self645 fn default() -> Self { 646 Self::new() 647 } 648 } 649 650 /// `RequestPart`, which is called [`Request Line`] in [`RFC9112`]. 651 /// 652 /// A request-line begins with a method token, followed by a single space (SP), 653 /// the request-target, and another single space (SP), and ends with the 654 /// protocol version. 655 /// 656 /// [`RFC9112`]: https://httpwg.org/specs/rfc9112.html 657 /// [`Request Line`]: https://httpwg.org/specs/rfc9112.html#request.line 658 /// 659 /// # Examples 660 /// 661 /// ``` 662 /// use ylong_http::request::Request; 663 /// 664 /// let request = Request::new(()); 665 /// 666 /// // Uses `Request::into_parts` to get a `RequestPart`. 667 /// let (part, _) = request.into_parts(); 668 /// ``` 669 #[derive(Clone, Debug)] 670 pub struct RequestPart { 671 /// HTTP URI implementation 672 pub uri: Uri, 673 /// HTTP Method implementation 674 pub method: Method, 675 /// HTTP Version implementation 676 pub version: Version, 677 /// HTTP Headers, which is called Fields in RFC9110. 678 pub headers: Headers, 679 } 680 681 impl Default for RequestPart { default() -> Self682 fn default() -> Self { 683 Self { 684 uri: Uri::http(), 685 method: Method::GET, 686 version: Version::HTTP1_1, 687 headers: Headers::new(), 688 } 689 } 690 } 691 692 #[cfg(test)] 693 mod ut_request { 694 use core::convert::TryFrom; 695 696 use super::{Method, Request, RequestBuilder, RequestPart, Uri}; 697 use crate::headers::Headers; 698 use crate::version::Version; 699 700 /// UT test cases for `RequestBuilder::build`. 701 /// 702 /// # Brief 703 /// 1. Creates a `Request` by calling `RequestBuilder::build`. 704 /// 2. Sets method by calling `RequestBuilder::method`. 705 /// 3. Sets uri by calling `RequestBuilder::uri`. 706 /// 4. Sets version by calling `RequestBuilder::version`. 707 /// 5. Sets header by calling `RequestBuilder::insert_header`. 708 /// 6. Sets header by calling `RequestBuilder::append_header`. 709 /// 7. Gets method by calling `Request::method`. 710 /// 8. Gets uri by calling `Request::uri`. 711 /// 9. Gets version by calling `Request::version`. 712 /// 10. Gets headers by calling `Request::headers`. 713 /// 11. Checks if the test result is correct. 714 #[test] ut_request_builder_build()715 fn ut_request_builder_build() { 716 let request = RequestBuilder::new() 717 .method("GET") 718 .url("www.baidu.com") 719 .version("HTTP/1.1") 720 .header("ACCEPT", "text/html") 721 .append_header("ACCEPT", "application/xml") 722 .body(()) 723 .unwrap(); 724 725 let mut new_headers = Headers::new(); 726 let _ = new_headers.insert("accept", "text/html"); 727 let _ = new_headers.append("accept", "application/xml"); 728 729 assert_eq!(request.method().as_str(), "GET"); 730 assert_eq!(request.uri().to_string().as_str(), "www.baidu.com"); 731 assert_eq!(request.version().as_str(), "HTTP/1.1"); 732 assert_eq!(request.headers(), &new_headers); 733 } 734 735 /// UT test cases for `RequestBuilder::build`. 736 /// 737 /// # Brief 738 /// 1. Creates a `Request` by calling `RequestBuilder::build`. 739 /// 2. Sets method by calling `RequestBuilder.method`. 740 /// 3. Sets uri by calling `RequestBuilder.uri`. 741 /// 4. Sets version by calling `RequestBuilder.version`. 742 /// 5. Sets header by calling `RequestBuilder.insert_header`. 743 /// 6. Sets header by calling `RequestBuilder.append_header`. 744 /// 7. Changes method by calling `Request.method_mut`. 745 /// 8. Changes uri by calling `Request.uri_mut`. 746 /// 9. Changes version by calling `Request.version_mut`. 747 /// 10. Changes headers by calling `Request.headers_mut`. 748 /// 11. Gets method by calling `Request.method`. 749 /// 12. Gets uri by calling `Request.uri`. 750 /// 13. Gets version by calling `Request.version`. 751 /// 14. Gets headers by calling `Request.headers`. 752 /// 15. Checks if the test result is correct. 753 #[test] ut_request_builder_build_2()754 fn ut_request_builder_build_2() { 755 let mut request = RequestBuilder::new() 756 .method("GET") 757 .url("www.example.com") 758 .version("HTTP/1.1") 759 .header("ACCEPT", "text/html") 760 .body(()) 761 .unwrap(); 762 763 *request.method_mut() = Method::POST; 764 *request.uri_mut() = Uri::try_from("www.test.com").unwrap(); 765 *request.version_mut() = Version::HTTP2; 766 let _ = request.headers_mut().insert("accept", "application/xml"); 767 768 let mut new_headers = Headers::new(); 769 let _ = new_headers.insert("accept", "application/xml"); 770 771 assert_eq!(request.method().as_str(), "POST"); 772 assert_eq!(request.uri().to_string().as_str(), "www.test.com"); 773 assert_eq!(request.version().as_str(), "HTTP/2.0"); 774 assert_eq!(request.headers(), &new_headers); 775 } 776 777 /// UT test cases for `Request::new`. 778 /// 779 /// # Brief 780 /// 1. Creates a `Request` by calling `Request::new`. 781 /// 2. Gets body by calling `Request.body`. 782 /// 3. Checks if the test result is correct. 783 #[test] ut_request_new()784 fn ut_request_new() { 785 let request = Request::new(String::from("<body><div></div></body>")); 786 assert_eq!( 787 request.body().to_owned().as_str(), 788 "<body><div></div></body>" 789 ); 790 } 791 792 /// UT test cases for `Request::into_parts`. 793 /// 794 /// # Brief 795 /// 1. Creates a `Request` by calling `Request::new`. 796 /// 2. Gets request part and body by calling `Request.into_parts`. 797 /// 3. Checks if the test result is correct. 798 #[test] ut_request_into_parts()799 fn ut_request_into_parts() { 800 let request = Request::new(String::from("<body><div></div></body>")); 801 let (part, body) = request.into_parts(); 802 assert_eq!(part.method.as_str(), "GET"); 803 assert_eq!(body.as_str(), "<body><div></div></body>"); 804 } 805 806 /// UT test cases for `Request::part`. 807 /// 808 /// # Brief 809 /// 1. Creates a `Request` by calling `Request::new`. 810 /// 2. Gets request part and body by calling `Request.part`. 811 /// 3. Checks if the test result is correct. 812 #[test] ut_request_part()813 fn ut_request_part() { 814 let request = Request::new(()); 815 let part = request.part(); 816 assert_eq!(part.method.as_str(), "GET"); 817 assert_eq!(part.version.as_str(), "HTTP/1.1"); 818 } 819 820 /// UT test cases for `Request::from_raw_parts`. 821 /// 822 /// # Brief 823 /// 1. Creates a `RequestPart` and a body. 824 /// 2. Gets the request by calling `Request::from_raw_parts`. 825 /// 3. Checks if the test result is correct. 826 #[test] ut_request_from_raw_parts()827 fn ut_request_from_raw_parts() { 828 let part = RequestPart::default(); 829 let body = String::from("<body><div></div></body>"); 830 let request = Request::from_raw_parts(part, body); 831 assert_eq!(request.part.method.as_str(), "GET"); 832 assert_eq!(request.body, "<body><div></div></body>"); 833 } 834 835 /// UT test cases for `Request::get`. 836 /// 837 /// # Brief 838 /// 1. Creates a `Request` by calling `Request::get`. 839 /// 3. Checks if the test result is correct. 840 #[test] ut_request_get()841 fn ut_request_get() { 842 let request = Request::get("www.example.com").body("".as_bytes()).unwrap(); 843 assert_eq!(request.part.uri.to_string(), "www.example.com"); 844 assert_eq!(request.part.method.as_str(), "GET"); 845 assert_eq!(request.part.version.as_str(), "HTTP/1.1"); 846 } 847 } 848