92 lines
2.7 KiB
Rust
92 lines
2.7 KiB
Rust
// Copyright 2025 The Grim Developers
|
|
//
|
|
// 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 hyper::body::{Body, Incoming};
|
|
use hyper::{Request, Response};
|
|
use hyper_proxy2::{Intercept, Proxy, ProxyConnector};
|
|
use hyper_tls::HttpsConnector;
|
|
use hyper_util::client::legacy::{Client, Error};
|
|
use hyper_util::rt::TokioExecutor;
|
|
use serde::de::StdError;
|
|
|
|
use crate::AppConfig;
|
|
|
|
/// Handles http requests.
|
|
pub struct HttpClient {}
|
|
|
|
impl HttpClient {
|
|
/// Send request.
|
|
pub async fn send<B>(req: Request<B>) -> Result<Response<Incoming>, Error>
|
|
where
|
|
B: Body + Send + 'static + Unpin,
|
|
<B as Body>::Data: Send,
|
|
B::Data: Send,
|
|
B::Error: Into<Box<dyn StdError + Send + Sync>>,
|
|
{
|
|
if AppConfig::use_proxy() {
|
|
if let Some(url) = AppConfig::socks_proxy_url() {
|
|
Self::send_socks_proxy(url, req).await
|
|
} else {
|
|
Self::send_http_proxy(AppConfig::http_proxy_url().unwrap(), req).await
|
|
}
|
|
} else {
|
|
let client = Client::builder(TokioExecutor::new()).build::<_, B>(HttpsConnector::new());
|
|
client.request(req).await
|
|
}
|
|
}
|
|
|
|
/// Create socks proxy client.
|
|
pub async fn send_socks_proxy<B>(
|
|
proxy_url: String,
|
|
req: Request<B>,
|
|
) -> Result<Response<Incoming>, Error>
|
|
where
|
|
B: Body + Send + 'static + Unpin,
|
|
<B as Body>::Data: Send,
|
|
B::Data: Send,
|
|
B::Error: Into<Box<dyn StdError + Send + Sync>>,
|
|
{
|
|
let connector = HttpsConnector::new();
|
|
let uri = proxy_url.parse().unwrap();
|
|
let proxy = hyper_socks2::SocksConnector {
|
|
proxy_addr: uri,
|
|
auth: None,
|
|
connector,
|
|
}
|
|
.with_tls()
|
|
.unwrap();
|
|
let client = Client::builder(TokioExecutor::new()).build::<_, B>(proxy);
|
|
client.request(req).await
|
|
}
|
|
|
|
/// Create http proxy client.
|
|
pub async fn send_http_proxy<B>(
|
|
proxy_url: String,
|
|
req: Request<B>,
|
|
) -> Result<Response<Incoming>, Error>
|
|
where
|
|
B: Body + Send + 'static + Unpin,
|
|
<B as Body>::Data: Send,
|
|
B::Data: Send,
|
|
B::Error: Into<Box<dyn StdError + Send + Sync>>,
|
|
{
|
|
let uri = proxy_url.parse().unwrap();
|
|
let proxy = Proxy::new(Intercept::All, uri);
|
|
let connector = HttpsConnector::new();
|
|
let proxy_connector = ProxyConnector::from_proxy(connector, proxy).unwrap();
|
|
let client = Client::builder(TokioExecutor::new()).build::<_, B>(proxy_connector);
|
|
client.request(req).await
|
|
}
|
|
}
|