使用 DNS 分流

This commit is contained in:
2024-02-07 22:19:43 +08:00
parent 95b4b8b947
commit 9ee02e9312
13 changed files with 247 additions and 70 deletions

View File

@ -39,4 +39,8 @@ pub async fn fetch(method: MyMethod,
headers: Option<HashMap<String, String>>,
input_data: Option<Vec<u8>>) -> RustHttpResponse {
http_package::fetch(_my_method_to_hyper_method(method), url, headers, input_data).await.unwrap()
}
pub async fn dns_lookup_txt(host: String) -> Vec<String> {
http_package::dns_lookup_txt(host).await.unwrap()
}

View File

@ -94,6 +94,41 @@ let api_connection_count = <u8>::sse_decode(&mut deserializer);deserializer.end(
})().await)
} })
}
fn wire_dns_lookup_txt_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "dns_lookup_txt",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_host = <String>::sse_decode(&mut deserializer);
deserializer.end();
move |context| async move {
transform_result_sse(
(move || async move {
Result::<_, ()>::Ok(crate::api::http_api::dns_lookup_txt(api_host).await)
})()
.await,
)
}
},
)
}
fn wire_fetch_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
@ -244,6 +279,18 @@ impl SseDecode for i32 {
}
}
impl SseDecode for Vec<String> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut len_ = <i32>::sse_decode(deserializer);
let mut ans_ = vec![];
for idx_ in 0..len_ {
ans_.push(<String>::sse_decode(deserializer));
}
return ans_;
}
}
impl SseDecode for Vec<u8> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@ -448,6 +495,7 @@ fn pde_ffi_dispatcher_primary_impl(
match func_id {
2 => wire_cancel_download_impl(port, ptr, rust_vec_len, data_len),
1 => wire_start_download_impl(port, ptr, rust_vec_len, data_len),
5 => wire_dns_lookup_txt_impl(port, ptr, rust_vec_len, data_len),
4 => wire_fetch_impl(port, ptr, rust_vec_len, data_len),
3 => wire_set_default_header_impl(port, ptr, rust_vec_len, data_len),
_ => unreachable!(),
@ -675,6 +723,16 @@ impl SseEncode for i32 {
}
}
impl SseEncode for Vec<String> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<i32>::sse_encode(self.len() as _, serializer);
for item in self {
<String>::sse_encode(item, serializer);
}
}
}
impl SseEncode for Vec<u8> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {

View File

@ -3,8 +3,6 @@ use hickory_resolver::{lookup_ip::LookupIpIntoIter, TokioAsyncResolver};
use hyper::client::connect::dns::Name;
use once_cell::sync::OnceCell;
use reqwest::dns::{Addrs, Resolve, Resolving};
use std::io;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use std::sync::Arc;
@ -35,6 +33,17 @@ impl Resolve for MyHickoryDnsResolver {
}
}
impl MyHickoryDnsResolver {
pub(crate) async fn lookup_txt(&self, name: String) -> anyhow::Result<Vec<String>> {
let resolver = self.state.get_or_try_init(new_resolver)?;
let txt = resolver.txt_lookup(name).await?;
let t = txt.iter()
.map(|rdata| rdata.to_string())
.collect::<Vec<_>>();
Ok(t)
}
}
impl Iterator for SocketAddrs {
type Item = SocketAddr;

View File

@ -21,12 +21,13 @@ pub struct RustHttpResponse {
lazy_static! {
static ref DEFAULT_HEADER: RwLock<HeaderMap> = RwLock::from(HeaderMap::new());
static ref DNS_CLIENT : Arc<dns::MyHickoryDnsResolver> = Arc::from(dns::MyHickoryDnsResolver::default());
static ref HTTP_CLIENT: reqwest::Client = {
reqwest::Client::builder()
.use_rustls_tls()
.connect_timeout(Duration::from_secs(10))
.timeout(Duration::from_secs(10))
.dns_resolver(Arc::from(dns::MyHickoryDnsResolver::default()))
.dns_resolver(DNS_CLIENT.clone())
.build()
.unwrap()
};
@ -83,6 +84,10 @@ pub async fn fetch(
Ok(resp)
}
pub async fn dns_lookup_txt(name: String) -> anyhow::Result<Vec<String>> {
DNS_CLIENT.lookup_txt(name).await
}
fn _reade_resp_header(r_header: &HeaderMap) -> HashMap<String, String> {
let mut resp_headers = HashMap::new();
for ele in r_header {