mirror of
https://github.com/sadoyan/aralez.git
synced 2026-06-10 01:04:20 +08:00
Move to RusTLS, Static binary build, performance improvements.
This commit is contained in:
@@ -2,7 +2,7 @@ use crate::utils::structs::{UpstreamsDashMap, UpstreamsIdMap};
|
||||
use crate::utils::tools::*;
|
||||
use dashmap::DashMap;
|
||||
use log::{error, info, warn};
|
||||
use reqwest::Client;
|
||||
use reqwest::{Client, Version};
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
@@ -20,32 +20,50 @@ pub async fn hc2(upslist: Arc<UpstreamsDashMap>, fullist: Arc<UpstreamsDashMap>,
|
||||
for val in fclone.iter() {
|
||||
let host = val.key();
|
||||
let inner = DashMap::new();
|
||||
let mut _scheme: (String, u16, bool) = ("".to_string(), 0, false);
|
||||
let mut _scheme: (String, u16, bool, bool) = ("".to_string(), 0, false, false);
|
||||
for path_entry in val.value().iter() {
|
||||
// let inner = DashMap::new();
|
||||
let path = path_entry.key();
|
||||
let mut innervec= Vec::new();
|
||||
for k in path_entry.value().0 .iter().enumerate() {
|
||||
let (ip, port, _ssl) = k.1;
|
||||
let mut _pref = "";
|
||||
let (ip, port, _ssl, _version) = k.1;
|
||||
let mut _link = String::new();
|
||||
let tls = detect_tls(ip, port).await;
|
||||
match tls {
|
||||
true => _pref = "https://",
|
||||
false => _pref = "http://",
|
||||
let mut is_h2 = false;
|
||||
|
||||
// if tls.1 == Some(Version::HTTP_11) {
|
||||
// println!(" V1: ==> {:?}", tls.1)
|
||||
// }else if tls.1 == Some(Version::HTTP_2) {
|
||||
// is_h2 = true;
|
||||
// println!(" V2: ==> {:?}", tls.1)
|
||||
// }
|
||||
|
||||
if tls.1 == Some(Version::HTTP_2) {
|
||||
is_h2 = true;
|
||||
// println!(" V2: ==> {} ==> {:?}", tls.0, tls.1)
|
||||
}
|
||||
if _pref == "https://" {
|
||||
_scheme = (ip.to_string(), *port, true);
|
||||
}else {
|
||||
_scheme = (ip.to_string(), *port, false);
|
||||
|
||||
match tls.0 {
|
||||
true => _link = format!("https://{}:{}{}", ip, port, path),
|
||||
false => _link = format!("http://{}:{}{}", ip, port, path),
|
||||
}
|
||||
let link = format!("{}{}:{}{}", _pref, ip, port, path);
|
||||
let resp = http_request(link.as_str(), params.0, "").await;
|
||||
match resp {
|
||||
// if _pref == "https://" {
|
||||
// _scheme = (ip.to_string(), *port, true);
|
||||
// }else {
|
||||
// _scheme = (ip.to_string(), *port, false);
|
||||
// }
|
||||
_scheme = (ip.to_string(), *port, tls.0, is_h2);
|
||||
// let link = format!("{}{}:{}{}", _pref, ip, port, path);
|
||||
let resp = http_request(_link.as_str(), params.0, "").await;
|
||||
match resp.0 {
|
||||
true => {
|
||||
if resp.1 {
|
||||
_scheme = (ip.to_string(), *port, tls.0, true);
|
||||
}
|
||||
innervec.push(_scheme.clone());
|
||||
}
|
||||
false => {
|
||||
warn!("Dead Upstream : {}", link);
|
||||
warn!("Dead Upstream : {}", _link);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,12 +91,12 @@ pub async fn hc2(upslist: Arc<UpstreamsDashMap>, fullist: Arc<UpstreamsDashMap>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
async fn http_request(url: &str, method: &str, payload: &str) -> bool {
|
||||
async fn http_request(url: &str, method: &str, payload: &str) -> (bool, bool) {
|
||||
let client = Client::builder().danger_accept_invalid_certs(true).build().unwrap();
|
||||
let timeout = Duration::from_secs(1);
|
||||
if !["POST", "GET", "HEAD"].contains(&method) {
|
||||
error!("Method {} not supported. Only GET|POST|HEAD are supported ", method);
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
async fn send_request(client: &Client, method: &str, url: &str, payload: &str, timeout: Duration) -> Option<reqwest::Response> {
|
||||
match method {
|
||||
@@ -92,11 +110,12 @@ async fn http_request(url: &str, method: &str, payload: &str) -> bool {
|
||||
match send_request(&client, method, url, payload, timeout).await {
|
||||
Some(response) => {
|
||||
let status = response.status().as_u16();
|
||||
(99..499).contains(&status)
|
||||
((99..499).contains(&status), false)
|
||||
}
|
||||
None => {
|
||||
let fallback_url = url.replace("https", "http");
|
||||
ping_grpc(&fallback_url).await
|
||||
// let fallback_url = url.replace("https", "http");
|
||||
// ping_grpc(&fallback_url).await
|
||||
(ping_grpc(&url).await, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,7 +127,10 @@ pub async fn ping_grpc(addr: &str) -> bool {
|
||||
let endpoint = endpoint.timeout(Duration::from_secs(2));
|
||||
|
||||
match tokio::time::timeout(Duration::from_secs(3), endpoint.connect()).await {
|
||||
Ok(Ok(_channel)) => true,
|
||||
Ok(Ok(_channel)) => {
|
||||
// println!("{:?} ==> {:?} ==> {}", endpoint, _channel, addr);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
@@ -116,20 +138,17 @@ pub async fn ping_grpc(addr: &str) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
async fn detect_tls(ip: &str, port: &u16) -> bool {
|
||||
async fn detect_tls(ip: &str, port: &u16) -> (bool, Option<Version>) {
|
||||
let url = format!("https://{}:{}", ip, port);
|
||||
let client = Client::builder()
|
||||
.timeout(Duration::from_secs(2))
|
||||
.danger_accept_invalid_certs(true) // skip cert validation for testing
|
||||
.build()
|
||||
.unwrap();
|
||||
// let url = format!("{}:{}", ip, port);
|
||||
let client = Client::builder().timeout(Duration::from_secs(2)).danger_accept_invalid_certs(true).build().unwrap();
|
||||
match client.get(&url).send().await {
|
||||
Ok(_) => true,
|
||||
Ok(response) => (true, Some(response.version())),
|
||||
Err(e) => {
|
||||
if e.is_builder() || e.is_connect() || e.to_string().contains("tls") {
|
||||
false
|
||||
(false, None)
|
||||
} else {
|
||||
false
|
||||
(false, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user