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 network interceptor. 15 16 use std::net::SocketAddr; 17 18 use ylong_http::response::Response as HttpResp; 19 20 use crate::async_impl::{HttpBody, Request, Response}; 21 use crate::HttpClientError; 22 23 pub(crate) type Interceptors = dyn Interceptor + Sync + Send + 'static; 24 25 /// Transport layer protocol type. 26 #[derive(Clone)] 27 pub enum ConnProtocol { 28 /// Tcp protocol. 29 Tcp, 30 /// Udp Protocol. 31 Udp, 32 } 33 34 /// Tcp connection information. 35 #[derive(Clone)] 36 pub struct ConnDetail { 37 /// Transport layer protocol type. 38 pub(crate) protocol: ConnProtocol, 39 pub(crate) alpn: Option<Vec<u8>>, 40 /// local socket address. 41 pub(crate) local: SocketAddr, 42 /// peer socket address. 43 pub(crate) peer: SocketAddr, 44 /// peer domain information. 45 pub(crate) addr: String, 46 /// Whether to use proxy. 47 pub(crate) proxy: bool, 48 } 49 50 impl ConnDetail { 51 /// Gets the transport layer protocol for the connection. protocol(&self) -> &ConnProtocol52 pub fn protocol(&self) -> &ConnProtocol { 53 &self.protocol 54 } 55 56 /// Gets the local socket address of the connection. local(&self) -> SocketAddr57 pub fn local(&self) -> SocketAddr { 58 self.local 59 } 60 61 /// Gets the peer socket address of the connection. peer(&self) -> SocketAddr62 pub fn peer(&self) -> SocketAddr { 63 self.peer 64 } 65 66 /// Gets the peer domain address of the connection. addr(&self) -> &str67 pub fn addr(&self) -> &str { 68 &self.addr 69 } 70 71 /// Whether to use proxy. proxy(&self) -> bool72 pub fn proxy(&self) -> bool { 73 self.proxy 74 } 75 76 /// Whether to use tls. alpn(&self) -> Option<&[u8]>77 pub fn alpn(&self) -> Option<&[u8]> { 78 self.alpn.as_deref() 79 } 80 } 81 82 /// Network interceptor. 83 /// 84 /// Provides intercepting behavior at various stages of http message passing. 85 pub trait Interceptor { 86 /// Intercepts the created transport layer protocol. 87 // TODO add cache and response interceptor. 88 // Is it necessary to add a response interceptor? 89 // Does the input and output interceptor need to be added to http2 or http3 90 // encoded packets? intercept_connection(&self, _info: ConnDetail) -> Result<(), HttpClientError>91 fn intercept_connection(&self, _info: ConnDetail) -> Result<(), HttpClientError> { 92 Ok(()) 93 } 94 95 /// Intercepts the input of transport layer io. intercept_input(&self, _bytes: &[u8]) -> Result<(), HttpClientError>96 fn intercept_input(&self, _bytes: &[u8]) -> Result<(), HttpClientError> { 97 Ok(()) 98 } 99 100 /// Intercepts the output of transport layer io. intercept_output(&self, _bytes: &[u8]) -> Result<(), HttpClientError>101 fn intercept_output(&self, _bytes: &[u8]) -> Result<(), HttpClientError> { 102 Ok(()) 103 } 104 105 /// Intercepts the Request that is eventually transmitted to the peer end. intercept_request(&self, _request: &Request) -> Result<(), HttpClientError>106 fn intercept_request(&self, _request: &Request) -> Result<(), HttpClientError> { 107 Ok(()) 108 } 109 110 /// Intercepts the response that is eventually returned. intercept_response(&self, _response: &Response) -> Result<(), HttpClientError>111 fn intercept_response(&self, _response: &Response) -> Result<(), HttpClientError> { 112 Ok(()) 113 } 114 115 /// Intercepts the error cause of the retry. intercept_retry(&self, _error: &HttpClientError) -> Result<(), HttpClientError>116 fn intercept_retry(&self, _error: &HttpClientError) -> Result<(), HttpClientError> { 117 Ok(()) 118 } 119 120 /// Intercepts the redirect request. intercept_redirect_request(&self, _request: &Request) -> Result<(), HttpClientError>121 fn intercept_redirect_request(&self, _request: &Request) -> Result<(), HttpClientError> { 122 Ok(()) 123 } 124 125 /// Intercepts the response returned by the redirect intercept_redirect_response( &self, _response: &HttpResp<HttpBody>, ) -> Result<(), HttpClientError>126 fn intercept_redirect_response( 127 &self, 128 _response: &HttpResp<HttpBody>, 129 ) -> Result<(), HttpClientError> { 130 Ok(()) 131 } 132 } 133 134 /// The default Interceptor does not do any intercepting. 135 pub(crate) struct IdleInterceptor; 136 137 impl Interceptor for IdleInterceptor {} 138