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 //! `ConnDetail` trait and `HttpStream` implementation.
15 
16 use std::pin::Pin;
17 use std::task::{Context, Poll};
18 
19 use crate::async_impl::interceptor::ConnDetail;
20 use crate::runtime::{AsyncRead, AsyncWrite, ReadBuf};
21 
22 /// `ConnDetail` trait, which is used to obtain information about the current
23 /// connection.
24 pub trait ConnInfo {
25     /// Whether the current connection is a proxy.
is_proxy(&self) -> bool26     fn is_proxy(&self) -> bool;
27 
conn_detail(&self) -> ConnDetail28     fn conn_detail(&self) -> ConnDetail;
29 }
30 
31 /// A connection wrapper containing io and io information.
32 pub struct HttpStream<T> {
33     detail: ConnDetail,
34     stream: T,
35 }
36 
37 impl<T> AsyncRead for HttpStream<T>
38 where
39     T: AsyncRead + AsyncWrite + Unpin,
40 {
41     // poll_read separately.
poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<std::io::Result<()>>42     fn poll_read(
43         mut self: Pin<&mut Self>,
44         cx: &mut Context<'_>,
45         buf: &mut ReadBuf<'_>,
46     ) -> Poll<std::io::Result<()>> {
47         Pin::new(&mut self.stream).poll_read(cx, buf)
48     }
49 }
50 
51 impl<T> AsyncWrite for HttpStream<T>
52 where
53     T: AsyncRead + AsyncWrite + Unpin,
54 {
55     // poll_write separately.
poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<std::io::Result<usize>>56     fn poll_write(
57         mut self: Pin<&mut Self>,
58         cx: &mut Context<'_>,
59         buf: &[u8],
60     ) -> Poll<std::io::Result<usize>> {
61         Pin::new(&mut self.stream).poll_write(cx, buf)
62     }
63 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>>64     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
65         Pin::new(&mut self.stream).poll_flush(cx)
66     }
67 
poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>>68     fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
69         Pin::new(&mut self.stream).poll_shutdown(cx)
70     }
71 }
72 
73 impl<T> ConnInfo for HttpStream<T> {
is_proxy(&self) -> bool74     fn is_proxy(&self) -> bool {
75         self.detail.proxy
76     }
77 
conn_detail(&self) -> ConnDetail78     fn conn_detail(&self) -> ConnDetail {
79         self.detail.clone()
80     }
81 }
82 
83 impl<T> HttpStream<T> {
84     /// HttpStream constructor.
new(io: T, detail: ConnDetail) -> HttpStream<T>85     pub fn new(io: T, detail: ConnDetail) -> HttpStream<T> {
86         HttpStream { detail, stream: io }
87     }
88 }
89