From cbb90bcead7c5d1a837ac6b0df718b10d0214d73 Mon Sep 17 00:00:00 2001 From: fqwert Date: Fri, 31 May 2024 15:00:13 +0800 Subject: [PATCH] fchown Signed-off-by: fqwert Change-Id: I07944653b7b72c7725fb4623b816db55b659ed52 --- ylong_http_client/src/async_impl/client.rs | 27 +++++++++++++++++++ .../src/async_impl/connector/mod.rs | 24 +++++++++++++++-- .../src/util/config/connector.rs | 5 ++++ ylong_http_client/src/util/config/fchown.rs | 26 ++++++++++++++++++ ylong_http_client/src/util/config/mod.rs | 4 +++ 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 ylong_http_client/src/util/config/fchown.rs diff --git a/ylong_http_client/src/async_impl/client.rs b/ylong_http_client/src/async_impl/client.rs index e0c2268..3b408dd 100644 --- a/ylong_http_client/src/async_impl/client.rs +++ b/ylong_http_client/src/async_impl/client.rs @@ -24,6 +24,8 @@ use crate::error::HttpClientError; use crate::runtime::timeout; #[cfg(feature = "__c_openssl")] use crate::util::c_openssl::verify::PubKeyPins; +#[cfg(all(target_os = "linux", feature = "ylong_base"))] +use crate::util::config::FchownConfig; use crate::util::config::{ ClientConfig, ConnectorConfig, HttpConfig, HttpVersion, Proxy, Redirect, Timeout, }; @@ -257,6 +259,10 @@ pub struct ClientBuilder { /// Options and flags that is related to `Proxy`. proxies: Proxies, + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + /// Fchown configuration. + fchown: Option, + interceptors: Arc, /// Options and flags that is related to `TLS`. @@ -279,6 +285,8 @@ impl ClientBuilder { http: HttpConfig::default(), client: ClientConfig::default(), proxies: Proxies::default(), + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + fchown: None, interceptors: Arc::new(IdleInterceptor), #[cfg(feature = "__tls")] tls: crate::util::TlsConfig::builder(), @@ -352,6 +360,23 @@ impl ClientBuilder { self } + /// Sets a `Fchown` for this client. + /// + /// Default will not set the owner of the file descriptor. + /// + /// # Examples + /// + /// ``` + /// use ylong_http_client::async_impl::ClientBuilder; + /// + /// let builder = ClientBuilder::new().sockets_owner(1000, 1000); + /// ``` + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + pub fn sockets_owner(mut self, uid: u32, gid: u32) -> Self { + self.fchown = Some(FchownConfig::new(uid, gid)); + self + } + /// Sets retry times for this client. /// /// The Retry is the number of times the client will retry the request if @@ -441,6 +466,8 @@ impl ClientBuilder { let config = ConnectorConfig { proxies: self.proxies, + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + fchown: self.fchown, #[cfg(feature = "__tls")] tls: tls_builder.build()?, }; diff --git a/ylong_http_client/src/async_impl/connector/mod.rs b/ylong_http_client/src/async_impl/connector/mod.rs index 92f9d13..a5fd08b 100644 --- a/ylong_http_client/src/async_impl/connector/mod.rs +++ b/ylong_http_client/src/async_impl/connector/mod.rs @@ -124,6 +124,8 @@ mod tls { use crate::async_impl::connector::stream::HttpStream; use crate::async_impl::interceptor::{ConnDetail, ConnProtocol}; use crate::async_impl::ssl_stream::{AsyncSslStream, MixStream}; + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + use crate::config::FchownConfig; use crate::runtime::{AsyncReadExt, AsyncWriteExt, TcpStream}; use crate::TlsConfig; @@ -149,10 +151,16 @@ mod tls { .and_then(|v| v.to_string().ok()); is_proxy = true; } - + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + let fchown = self.config.fchown.clone(); match *uri.scheme().unwrap() { Scheme::HTTP => Box::pin(async move { let stream = tcp_stream(&addr).await?; + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + if let Some(fchown) = fchown { + let _ = stream.fchown(fchown.uid, fchown.gid); + } + let local = stream.local_addr()?; let peer = stream.peer_addr()?; let detail = ConnDetail { @@ -171,7 +179,14 @@ mod tls { let port = uri.port().unwrap().as_u16().unwrap(); let config = self.config.tls.clone(); Box::pin(async move { - https_connect(config, addr, is_proxy, auth, host, port).await + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + { + https_connect(config, addr, is_proxy, auth, host, port, fchown).await + } + #[cfg(not(all(target_os = "linux", feature = "ylong_base")))] + { + https_connect(config, addr, is_proxy, auth, host, port).await + } }) } } @@ -185,8 +200,13 @@ mod tls { auth: Option, host: String, port: u16, + #[cfg(all(target_os = "linux", feature = "ylong_base"))] fchown: Option, ) -> Result>, Error> { let mut tcp = tcp_stream(addr.as_str()).await?; + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + if let Some(fchown) = fchown { + let _ = tcp.fchown(fchown.uid, fchown.gid); + } let local = tcp.local_addr()?; let peer = tcp.peer_addr()?; if is_proxy { diff --git a/ylong_http_client/src/util/config/connector.rs b/ylong_http_client/src/util/config/connector.rs index ec40566..80de0ee 100644 --- a/ylong_http_client/src/util/config/connector.rs +++ b/ylong_http_client/src/util/config/connector.rs @@ -13,12 +13,17 @@ //! Connector configure module. + #[cfg(all(target_os = "linux", feature = "ylong_base"))] +use super::FchownConfig; use crate::util::proxy::Proxies; #[derive(Default)] pub(crate) struct ConnectorConfig { pub(crate) proxies: Proxies, + #[cfg(all(target_os = "linux", feature = "ylong_base"))] + pub(crate) fchown: Option, + #[cfg(feature = "__tls")] pub(crate) tls: crate::util::TlsConfig, } diff --git a/ylong_http_client/src/util/config/fchown.rs b/ylong_http_client/src/util/config/fchown.rs new file mode 100644 index 0000000..73c23e3 --- /dev/null +++ b/ylong_http_client/src/util/config/fchown.rs @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use libc::{gid_t, uid_t}; + +#[derive(Clone, Default)] +pub(crate) struct FchownConfig { + pub(crate) uid: uid_t, + pub(crate) gid: gid_t, +} + +impl FchownConfig { + pub(crate) fn new(uid: uid_t, gid: gid_t) -> Self { + Self { uid, gid } + } +} diff --git a/ylong_http_client/src/util/config/mod.rs b/ylong_http_client/src/util/config/mod.rs index 66b7921..3e766d5 100644 --- a/ylong_http_client/src/util/config/mod.rs +++ b/ylong_http_client/src/util/config/mod.rs @@ -30,3 +30,7 @@ pub(crate) use tls::{AlpnProtocol, AlpnProtocolList}; pub use tls::{CertVerifier, ServerCerts}; #[cfg(feature = "tls_rust_ssl")] pub use tls::{Certificate, PrivateKey, TlsConfig, TlsConfigBuilder, TlsFileType, TlsVersion}; + #[cfg(all(target_os = "linux", feature = "ylong_base"))] +mod fchown; + #[cfg(all(target_os = "linux", feature = "ylong_base"))] +pub(crate) use fchown::FchownConfig; -- Gitee