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