qiniu_http/
response.rs

1use super::{MapError, ResponseError};
2use assert_impl::assert_impl;
3use http::{
4    header::{AsHeaderName, HeaderMap, HeaderValue, IntoHeaderName},
5    response::{Parts as HttpResponseParts, Response as HttpResponse},
6    status::StatusCode,
7    Extensions, Version,
8};
9use std::{
10    default::Default,
11    fmt::Debug,
12    mem::take,
13    net::IpAddr,
14    num::NonZeroU16,
15    ops::{Deref, DerefMut},
16    result,
17    time::Duration,
18};
19
20#[cfg(feature = "async")]
21use futures_lite::Future;
22
23/// HTTP 响应的指标信息
24#[derive(Debug, Clone, Default)]
25pub struct Metrics {
26    total_duration: Option<Duration>,
27    name_lookup_duration: Option<Duration>,
28    connect_duration: Option<Duration>,
29    secure_connect_duration: Option<Duration>,
30    redirect_duration: Option<Duration>,
31    transfer_duration: Option<Duration>,
32}
33
34impl Metrics {
35    /// 创建 HTTP 响应的指标信息构建器
36    #[inline]
37    pub fn builder() -> MetricsBuilder {
38        Default::default()
39    }
40
41    /// 获取总体请求耗时
42    #[inline]
43    pub fn total_duration(&self) -> Option<Duration> {
44        self.total_duration
45    }
46
47    /// 获取总体请求耗时的可变引用
48    #[inline]
49    pub fn total_duration_mut(&mut self) -> &mut Option<Duration> {
50        &mut self.total_duration
51    }
52
53    /// 获取域名查询的耗时
54    #[inline]
55    pub fn name_lookup_duration(&self) -> Option<Duration> {
56        self.name_lookup_duration
57    }
58
59    /// 获取域名查询的耗时的可变引用
60    #[inline]
61    pub fn name_lookup_duration_mut(&mut self) -> &mut Option<Duration> {
62        &mut self.name_lookup_duration
63    }
64
65    /// 获取建立连接的耗时
66    #[inline]
67    pub fn connect_duration(&self) -> Option<Duration> {
68        self.connect_duration
69    }
70
71    /// 获取建立连接的耗时的可变引用
72    #[inline]
73    pub fn connect_duration_mut(&mut self) -> &mut Option<Duration> {
74        &mut self.connect_duration
75    }
76
77    /// 获取建立安全连接的耗时
78    #[inline]
79    pub fn secure_connect_duration(&self) -> Option<Duration> {
80        self.secure_connect_duration
81    }
82
83    /// 获取建立安全连接的耗时的可变引用
84    #[inline]
85    pub fn secure_connect_duration_mut(&mut self) -> &mut Option<Duration> {
86        &mut self.secure_connect_duration
87    }
88
89    /// 获取重定向的耗时
90    #[inline]
91    pub fn redirect_duration(&self) -> Option<Duration> {
92        self.redirect_duration
93    }
94
95    /// 获取重定向的耗时的可变引用
96    #[inline]
97    pub fn redirect_duration_mut(&mut self) -> &mut Option<Duration> {
98        &mut self.redirect_duration
99    }
100
101    /// 获取请求和响应数据传输的耗时
102    #[inline]
103    pub fn transfer_duration(&self) -> Option<Duration> {
104        self.transfer_duration
105    }
106
107    /// 获取请求和响应数据传输的耗时的可变引用
108    #[inline]
109    pub fn transfer_duration_mut(&mut self) -> &mut Option<Duration> {
110        &mut self.transfer_duration
111    }
112}
113
114/// HTTP 响应的指标信息构建器
115#[derive(Debug, Clone, Default)]
116pub struct MetricsBuilder(Metrics);
117
118impl MetricsBuilder {
119    /// 设置总体请求耗时
120    #[inline]
121    pub fn total_duration(&mut self, duration: Duration) -> &mut Self {
122        self.0.total_duration = Some(duration);
123        self
124    }
125
126    /// 设置域名查询的耗时
127    #[inline]
128    pub fn name_lookup_duration(&mut self, duration: Duration) -> &mut Self {
129        self.0.name_lookup_duration = Some(duration);
130        self
131    }
132
133    /// 设置建立连接的耗时
134    #[inline]
135    pub fn connect_duration(&mut self, duration: Duration) -> &mut Self {
136        self.0.connect_duration = Some(duration);
137        self
138    }
139
140    /// 设置建立安全连接的耗时
141    #[inline]
142    pub fn secure_connect_duration(&mut self, duration: Duration) -> &mut Self {
143        self.0.secure_connect_duration = Some(duration);
144        self
145    }
146
147    /// 设置重定向的耗时
148    #[inline]
149    pub fn redirect_duration(&mut self, duration: Duration) -> &mut Self {
150        self.0.redirect_duration = Some(duration);
151        self
152    }
153
154    /// 设置请求和响应数据传输的耗时
155    #[inline]
156    pub fn transfer_duration(&mut self, duration: Duration) -> &mut Self {
157        self.0.transfer_duration = Some(duration);
158        self
159    }
160
161    /// 构建 HTTP 响应的指标信息
162    #[inline]
163    pub fn build(&mut self) -> Metrics {
164        take(&mut self.0)
165    }
166}
167
168#[derive(Debug, Default, Clone)]
169pub(super) struct ResponseInfo {
170    server_ip: Option<IpAddr>,
171    server_port: Option<NonZeroU16>,
172    metrics: Option<Metrics>,
173}
174
175impl ResponseInfo {
176    #[inline]
177    pub(super) fn server_ip(&self) -> Option<IpAddr> {
178        self.server_ip
179    }
180
181    #[inline]
182    pub(super) fn server_port(&self) -> Option<NonZeroU16> {
183        self.server_port
184    }
185
186    #[inline]
187    pub(super) fn metrics(&self) -> Option<&Metrics> {
188        self.metrics.as_ref()
189    }
190
191    pub(super) fn server_ip_mut(&mut self) -> &mut Option<IpAddr> {
192        &mut self.server_ip
193    }
194
195    pub(super) fn server_port_mut(&mut self) -> &mut Option<NonZeroU16> {
196        &mut self.server_port
197    }
198
199    pub(super) fn metrics_mut(&mut self) -> &mut Option<Metrics> {
200        &mut self.metrics
201    }
202}
203
204/// HTTP 响应信息
205///
206/// 不包含响应体信息
207#[derive(Debug)]
208pub struct ResponseParts {
209    inner: HttpResponseParts,
210    info: ResponseInfo,
211}
212
213impl ResponseParts {
214    /// 获取 HTTP 状态码
215    #[inline]
216    pub fn status_code(&self) -> StatusCode {
217        self.inner.status
218    }
219
220    /// 获取 HTTP 状态码 的可变引用
221    #[inline]
222    pub fn status_code_mut(&mut self) -> &mut StatusCode {
223        &mut self.inner.status
224    }
225
226    /// 获取 HTTP Headers
227    #[inline]
228    pub fn headers(&self) -> &HeaderMap {
229        &self.inner.headers
230    }
231
232    /// 获取 HTTP Headers 的可变引用
233    #[inline]
234    pub fn headers_mut(&mut self) -> &mut HeaderMap {
235        &mut self.inner.headers
236    }
237
238    /// 获取 HTTP 版本
239    #[inline]
240    pub fn version(&self) -> Version {
241        self.inner.version
242    }
243
244    /// 获取 HTTP 版本的可变引用
245    #[inline]
246    pub fn version_mut(&mut self) -> &mut Version {
247        &mut self.inner.version
248    }
249
250    /// 获取 扩展信息
251    #[inline]
252    pub fn extensions(&self) -> &Extensions {
253        &self.inner.extensions
254    }
255
256    /// 获取扩展信息的可变引用
257    #[inline]
258    pub fn extensions_mut(&mut self) -> &mut Extensions {
259        &mut self.inner.extensions
260    }
261
262    /// 获取 HTTP 响应 Header
263    #[inline]
264    pub fn header(&self, header_name: impl AsHeaderName) -> Option<&HeaderValue> {
265        self.headers().get(header_name)
266    }
267
268    pub(super) fn into_response_info(self) -> ResponseInfo {
269        self.info
270    }
271
272    /// 获取 HTTP 服务器 IP 地址
273    #[inline]
274    pub fn server_ip(&self) -> Option<IpAddr> {
275        self.info.server_ip()
276    }
277
278    /// 获取 HTTP 服务器 IP 地址的可变引用
279    #[inline]
280    pub fn server_ip_mut(&mut self) -> &mut Option<IpAddr> {
281        self.info.server_ip_mut()
282    }
283
284    /// 获取 HTTP 服务器端口号
285    #[inline]
286    pub fn server_port(&self) -> Option<NonZeroU16> {
287        self.info.server_port()
288    }
289
290    /// 获取 HTTP 服务器端口号的可变引用
291    #[inline]
292    pub fn server_port_mut(&mut self) -> &mut Option<NonZeroU16> {
293        self.info.server_port_mut()
294    }
295
296    /// 获取 HTTP 响应的指标信息
297    #[inline]
298    pub fn metrics(&self) -> Option<&Metrics> {
299        self.info.metrics()
300    }
301
302    /// 获取 HTTP 响应的指标信息的可变引用
303    #[inline]
304    pub fn metrics_mut(&mut self) -> &mut Option<Metrics> {
305        self.info.metrics_mut()
306    }
307}
308
309impl Default for ResponseParts {
310    #[inline]
311    fn default() -> Self {
312        let (parts, _) = HttpResponse::new(()).into_parts();
313        Self {
314            inner: parts,
315            info: Default::default(),
316        }
317    }
318}
319
320/// HTTP 响应
321///
322/// 封装 HTTP 响应相关字段
323#[derive(Debug, Default)]
324pub struct Response<B> {
325    parts: ResponseParts,
326    body: B,
327}
328
329impl<B: Default> Response<B> {
330    /// 返回 HTTP 响应构建器
331    #[inline]
332    pub fn builder() -> ResponseBuilder<B> {
333        ResponseBuilder::<B>::default()
334    }
335}
336
337impl<B> Response<B> {
338    /// 获取 HTTP 响应体
339    #[inline]
340    pub fn body(&self) -> &B {
341        &self.body
342    }
343
344    /// 获取 HTTP 响应体的可变引用
345    #[inline]
346    pub fn body_mut(&mut self) -> &mut B {
347        &mut self.body
348    }
349
350    /// HTTP 响应信息
351    #[inline]
352    pub fn parts(&self) -> &ResponseParts {
353        &self.parts
354    }
355
356    /// 获取 HTTP 响应信息的可变引用
357    #[inline]
358    pub fn parts_mut(&mut self) -> &mut ResponseParts {
359        &mut self.parts
360    }
361
362    /// 转换为 HTTP 响应体
363    #[inline]
364    pub fn into_body(self) -> B {
365        self.body
366    }
367
368    /// 转换为响应信息和响应体
369    #[inline]
370    pub fn into_parts_and_body(self) -> (ResponseParts, B) {
371        let Self { parts, body } = self;
372        (parts, body)
373    }
374
375    /// 通过响应信息和响应体创建 HTTP 响应
376    #[inline]
377    pub fn from_parts_and_body(parts: ResponseParts, body: B) -> Self {
378        Response { parts, body }
379    }
380
381    /// 对 HTTP 响应体进行映射
382    #[inline]
383    pub fn map_body<B2>(self, f: impl FnOnce(B) -> B2) -> Response<B2> {
384        let (parts, body) = self.into_parts_and_body();
385        let body = f(body);
386        Response::from_parts_and_body(parts, body)
387    }
388
389    /// 尝试对 HTTP 响应体进行映射
390    #[inline]
391    pub fn try_map_body<B2, E>(
392        self,
393        f: impl FnOnce(B) -> result::Result<B2, E>,
394    ) -> result::Result<Response<B2>, MapError<E>> {
395        let (parts, body) = self.into_parts_and_body();
396        match f(body) {
397            Ok(body) => Ok(Response::from_parts_and_body(parts, body)),
398            Err(err) => Err(MapError::new(err, parts)),
399        }
400    }
401
402    /// 尝试对 HTTP 响应体进行异步映射
403    #[inline]
404    #[cfg(feature = "async")]
405    pub async fn try_async_map_body<B2, E, F, Fut>(self, f: F) -> result::Result<Response<B2>, MapError<E>>
406    where
407        F: FnOnce(B) -> Fut,
408        Fut: Future<Output = result::Result<B2, E>>,
409    {
410        let (parts, body) = self.into_parts_and_body();
411        match f(body).await {
412            Ok(body) => Ok(Response::from_parts_and_body(parts, body)),
413            Err(err) => Err(MapError::new(err, parts)),
414        }
415    }
416}
417
418impl<B> Deref for Response<B> {
419    type Target = ResponseParts;
420
421    #[inline]
422    fn deref(&self) -> &Self::Target {
423        &self.parts
424    }
425}
426
427impl<B> DerefMut for Response<B> {
428    #[inline]
429    fn deref_mut(&mut self) -> &mut Self::Target {
430        &mut self.parts
431    }
432}
433
434impl<B: Send + Sync> Response<B> {
435    #[allow(dead_code)]
436    fn ignore() {
437        assert_impl!(Send: Self);
438        assert_impl!(Sync: Self);
439    }
440}
441
442/// HTTP 响应体构建器
443#[derive(Debug, Default)]
444pub struct ResponseBuilder<B> {
445    inner: Response<B>,
446}
447
448impl<B> ResponseBuilder<B> {
449    /// 设置 HTTP 状态码
450    #[inline]
451    pub fn status_code(&mut self, status_code: StatusCode) -> &mut Self {
452        *self.inner.status_code_mut() = status_code;
453        self
454    }
455
456    /// 设置 HTTP Headers
457    #[inline]
458    pub fn headers(&mut self, headers: HeaderMap) -> &mut Self {
459        *self.inner.headers_mut() = headers;
460        self
461    }
462
463    /// 设置 HTTP 版本
464    #[inline]
465    pub fn version(&mut self, version: Version) -> &mut Self {
466        *self.inner.version_mut() = version;
467        self
468    }
469
470    /// 设置 HTTP 服务器 IP 地址
471    #[inline]
472    pub fn server_ip(&mut self, server_ip: IpAddr) -> &mut Self {
473        *self.inner.info.server_ip_mut() = Some(server_ip);
474        self
475    }
476
477    /// 设置 HTTP 服务器端口号
478    #[inline]
479    pub fn server_port(&mut self, server_port: NonZeroU16) -> &mut Self {
480        *self.inner.info.server_port_mut() = Some(server_port);
481        self
482    }
483
484    /// 设置扩展信息
485    #[inline]
486    pub fn extensions(&mut self, extensions: Extensions) -> &mut Self {
487        *self.inner.extensions_mut() = extensions;
488        self
489    }
490
491    /// 添加 HTTP Header
492    #[inline]
493    pub fn header(&mut self, header_name: impl IntoHeaderName, header_value: impl Into<HeaderValue>) -> &mut Self {
494        self.inner.headers_mut().insert(header_name, header_value.into());
495        self
496    }
497
498    /// 添加 HTTP 响应体
499    #[inline]
500    pub fn body(&mut self, body: B) -> &mut Self {
501        *self.inner.body_mut() = body;
502        self
503    }
504
505    /// 设置 HTTP 响应的指标信息
506    #[inline]
507    pub fn metrics(&mut self, metrics: Metrics) -> &mut Self {
508        *self.inner.metrics_mut() = Some(metrics);
509        self
510    }
511}
512
513impl<B: Default> ResponseBuilder<B> {
514    /// 构建 HTTP 请求
515    #[inline]
516    pub fn build(&mut self) -> Response<B> {
517        take(&mut self.inner)
518    }
519}
520
521mod body {
522    use assert_impl::assert_impl;
523    use std::{
524        default::Default,
525        fmt::Debug,
526        io::{Cursor, Read, Result as IoResult},
527    };
528
529    trait ReadDebug: Read + Debug + Send {}
530    impl<T: Read + Debug + Send> ReadDebug for T {}
531
532    /// HTTP 响应体
533    #[derive(Debug)]
534    pub struct ResponseBody(ResponseBodyInner);
535
536    #[derive(Debug)]
537    enum ResponseBodyInner {
538        Reader(Box<dyn ReadDebug>),
539        Bytes(Cursor<Vec<u8>>),
540    }
541
542    impl ResponseBody {
543        /// 通过输入流创建 HTTP 响应体
544        #[inline]
545        pub fn from_reader(reader: impl Read + Debug + Send + 'static) -> Self {
546            Self(ResponseBodyInner::Reader(Box::new(reader)))
547        }
548
549        /// 通过二进制数据创建 HTTP 响应体
550        #[inline]
551        pub fn from_bytes(bytes: Vec<u8>) -> Self {
552            Self(ResponseBodyInner::Bytes(Cursor::new(bytes)))
553        }
554
555        #[allow(dead_code)]
556        fn ignore() {
557            assert_impl!(Send: Self);
558            // assert_impl!(Sync: Self);
559        }
560    }
561
562    impl Default for ResponseBody {
563        #[inline]
564        fn default() -> Self {
565            Self::from_bytes(Default::default())
566        }
567    }
568
569    impl Read for ResponseBody {
570        fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
571            match &mut self.0 {
572                ResponseBodyInner::Reader(reader) => reader.read(buf),
573                ResponseBodyInner::Bytes(bytes) => bytes.read(buf),
574            }
575        }
576    }
577
578    #[cfg(feature = "async")]
579    mod async_body {
580        use assert_impl::assert_impl;
581        use futures_lite::{
582            io::{AsyncRead, Cursor, Result as IoResult},
583            pin,
584        };
585        use std::{
586            fmt::Debug,
587            pin::Pin,
588            task::{Context, Poll},
589        };
590
591        trait AsyncReadDebug: AsyncRead + Unpin + Debug + Send + Sync {}
592        impl<T: AsyncRead + Unpin + Debug + Send + Sync> AsyncReadDebug for T {}
593
594        /// 异步 HTTP 响应体
595        #[derive(Debug)]
596        #[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
597        pub struct AsyncResponseBody(AsyncResponseBodyInner);
598
599        #[derive(Debug)]
600        enum AsyncResponseBodyInner {
601            Reader(Box<dyn AsyncReadDebug>),
602            Bytes(Cursor<Vec<u8>>),
603        }
604
605        impl AsyncResponseBody {
606            /// 通过异步输入流创建异步 HTTP 响应体
607            #[inline]
608            pub fn from_reader(reader: impl AsyncRead + Unpin + Debug + Send + Sync + 'static) -> Self {
609                Self(AsyncResponseBodyInner::Reader(Box::new(reader)))
610            }
611
612            /// 通过二进制数据创建异步 HTTP 响应体
613            #[inline]
614            pub fn from_bytes(bytes: Vec<u8>) -> Self {
615                Self(AsyncResponseBodyInner::Bytes(Cursor::new(bytes)))
616            }
617
618            #[allow(dead_code)]
619            fn ignore() {
620                assert_impl!(Send: Self);
621                assert_impl!(Sync: Self);
622            }
623        }
624
625        impl Default for AsyncResponseBody {
626            #[inline]
627            fn default() -> Self {
628                Self::from_bytes(Default::default())
629            }
630        }
631
632        impl AsyncRead for AsyncResponseBody {
633            fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll<IoResult<usize>> {
634                match &mut self.as_mut().0 {
635                    AsyncResponseBodyInner::Reader(reader) => {
636                        pin!(reader);
637                        reader.poll_read(cx, buf)
638                    }
639                    AsyncResponseBodyInner::Bytes(bytes) => {
640                        pin!(bytes);
641                        bytes.poll_read(cx, buf)
642                    }
643                }
644            }
645        }
646    }
647
648    #[cfg(feature = "async")]
649    pub use async_body::*;
650}
651
652pub use body::ResponseBody;
653
654#[cfg(feature = "async")]
655pub use body::AsyncResponseBody;
656
657/// HTTP 响应结果
658pub type Result<B> = result::Result<Response<B>, ResponseError>;