• 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 [`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