• 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 use std::convert::TryFrom;
15 use std::ops::{Deref, DerefMut};
16 
17 use ylong_http::body::async_impl::Body;
18 use ylong_http::body::MultiPart;
19 use ylong_http::error::HttpError;
20 use ylong_http::headers::{HeaderName, HeaderValue};
21 use ylong_http::request::method::Method;
22 use ylong_http::request::uri::Uri;
23 use ylong_http::request::{Request, RequestBuilder as ReqBuilder};
24 use ylong_http::response::Response as Resp;
25 use ylong_http::version::Version;
26 
27 use crate::async_impl::HttpBody;
28 use crate::{ErrorKind, HttpClientError};
29 
30 /// Response Adapter.
31 pub struct Response {
32     response: Resp<HttpBody>,
33 }
34 
35 impl Response {
new(response: Resp<HttpBody>) -> Self36     pub(crate) fn new(response: Resp<HttpBody>) -> Self {
37         Self { response }
38     }
39 
40     /// `text()` adapter.
text(self) -> Result<String, HttpClientError>41     pub async fn text(self) -> Result<String, HttpClientError> {
42         let mut buf = [0u8; 1024];
43         let mut vec = Vec::new();
44         let mut response = self.response;
45         loop {
46             let size = response.body_mut().data(&mut buf).await?;
47             if size == 0 {
48                 break;
49             }
50             vec.extend_from_slice(&buf[..size]);
51         }
52         String::from_utf8(vec).map_err(|_| {
53             HttpClientError::new_with_message(
54                 ErrorKind::BodyDecode,
55                 "The body content is not valid utf8.",
56             )
57         })
58     }
59 }
60 
61 impl Deref for Response {
62     type Target = Resp<HttpBody>;
63 
deref(&self) -> &Self::Target64     fn deref(&self) -> &Self::Target {
65         &self.response
66     }
67 }
68 
69 impl DerefMut for Response {
deref_mut(&mut self) -> &mut Self::Target70     fn deref_mut(&mut self) -> &mut Self::Target {
71         &mut self.response
72     }
73 }
74 
75 /// RequestBuilder Adapter
76 pub struct RequestBuilder(ReqBuilder);
77 
78 impl RequestBuilder {
79     /// Creates a new, default `RequestBuilder`.
new() -> Self80     pub fn new() -> Self {
81         Self(ReqBuilder::new())
82     }
83 
84     /// Sets the `Method` of the `Request`.
method<T>(self, method: T) -> Self where Method: TryFrom<T>, <Method as TryFrom<T>>::Error: Into<HttpError>,85     pub fn method<T>(self, method: T) -> Self
86     where
87         Method: TryFrom<T>,
88         <Method as TryFrom<T>>::Error: Into<HttpError>,
89     {
90         Self(self.0.method(method))
91     }
92 
93     /// Sets the `Uri` of the `Request`. `Uri` does not provide a default value,
94     /// so it must be set.
url<T>(self, uri: T) -> Self where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<HttpError>,95     pub fn url<T>(self, uri: T) -> Self
96     where
97         Uri: TryFrom<T>,
98         <Uri as TryFrom<T>>::Error: Into<HttpError>,
99     {
100         Self(self.0.url(uri))
101     }
102 
103     /// Sets the `Version` of the `Request`. Uses `Version::HTTP11` by default.
version<T>(mut self, version: T) -> Self where Version: TryFrom<T>, <Version as TryFrom<T>>::Error: Into<HttpError>,104     pub fn version<T>(mut self, version: T) -> Self
105     where
106         Version: TryFrom<T>,
107         <Version as TryFrom<T>>::Error: Into<HttpError>,
108     {
109         self.0 = self.0.version(version);
110         self
111     }
112 
113     /// Adds a `Header` to `Request`. Overwrites `HeaderValue` if the
114     /// `HeaderName` already exists.
115     ///
116     /// # Examples
117     ///
118     /// ```
119     /// use ylong_http::headers::Headers;
120     /// use ylong_http::request::RequestBuilder;
121     ///
122     /// let request = RequestBuilder::new().header("ACCEPT", "text/html");
123     /// ```
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>,124     pub fn header<N, V>(mut self, name: N, value: V) -> Self
125     where
126         HeaderName: TryFrom<N>,
127         <HeaderName as TryFrom<N>>::Error: Into<HttpError>,
128         HeaderValue: TryFrom<V>,
129         <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
130     {
131         self.0 = self.0.header(name, value);
132         self
133     }
134 
135     /// Adds a `Header` to `Request`. Appends `HeaderValue` to the end of
136     /// previous `HeaderValue` if the `HeaderName` already exists.
137     ///
138     /// # Examples
139     ///
140     /// ```
141     /// use ylong_http::headers::Headers;
142     /// use ylong_http::request::RequestBuilder;
143     ///
144     /// let request = RequestBuilder::new().append_header("ACCEPT", "text/html");
145     /// ```
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>,146     pub fn append_header<N, V>(mut self, name: N, value: V) -> Self
147     where
148         HeaderName: TryFrom<N>,
149         <HeaderName as TryFrom<N>>::Error: Into<HttpError>,
150         HeaderValue: TryFrom<V>,
151         <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
152     {
153         self.0 = self.0.append_header(name, value);
154         self
155     }
156 
157     /// Try to create a `Request` based on the incoming `body`.
body<T>(self, body: T) -> Result<Request<T>, HttpClientError>158     pub fn body<T>(self, body: T) -> Result<Request<T>, HttpClientError> {
159         self.0
160             .body(body)
161             .map_err(|e| HttpClientError::new_with_cause(ErrorKind::Build, Some(e)))
162     }
163 
164     /// Creates a `Request` that uses this `RequestBuilder` configuration and
165     /// the provided `Multipart`. You can also provide a `Uploader<Multipart>`
166     /// as the body.
167     ///
168     /// # Error
169     ///
170     /// This method fails if some configurations are wrong.
multipart<T>(self, body: T) -> Result<Request<T>, HttpClientError> where T: AsRef<MultiPart>,171     pub fn multipart<T>(self, body: T) -> Result<Request<T>, HttpClientError>
172     where
173         T: AsRef<MultiPart>,
174     {
175         self.0
176             .multipart(body)
177             .map_err(|e| HttpClientError::new_with_cause(ErrorKind::Build, Some(e)))
178     }
179 }
180 
181 impl Default for RequestBuilder {
default() -> Self182     fn default() -> Self {
183         Self::new()
184     }
185 }
186