fix http_connector
1. use ipv4 first when connect to http server. 2. allow redirect to url like: http://tcp://p.com:11010 3. dns should also use long timeout
This commit is contained in:
Generated
+2
-1
@@ -3139,9 +3139,10 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "http_req"
|
name = "http_req"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
source = "git+https://github.com/EasyTier/http_req.git#e6d9e93c43c940f56f45e91b0923bcea53a718ea"
|
source = "git+https://github.com/EasyTier/http_req.git#b10aa9fc0db3067cc3d2174683a87250b80a1ea9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
"rand 0.8.5",
|
||||||
"rustls",
|
"rustls",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
use std::{
|
use std::{net::SocketAddr, sync::Arc};
|
||||||
net::SocketAddr,
|
|
||||||
pin::Pin,
|
|
||||||
sync::{Arc, RwLock},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{error::Error, global_ctx::ArcGlobalCtx},
|
common::{error::Error, global_ctx::ArcGlobalCtx},
|
||||||
tunnel::{
|
tunnel::{Tunnel, TunnelConnector, TunnelError, PROTO_PORT_OFFSET},
|
||||||
Tunnel, TunnelConnector, TunnelError, ZCPacketSink, ZCPacketStream, PROTO_PORT_OFFSET,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use dashmap::DashSet;
|
use dashmap::DashSet;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use std::{
|
|||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use http_req::request::{RedirectPolicy, Request};
|
use http_req::request::{RedirectPolicy, Request};
|
||||||
use rand::seq::SliceRandom as _;
|
use rand::seq::SliceRandom as _;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{error::Error, global_ctx::ArcGlobalCtx},
|
common::{error::Error, global_ctx::ArcGlobalCtx},
|
||||||
@@ -73,10 +74,12 @@ impl HttpTunnelConnector {
|
|||||||
async fn handle_302_redirect(
|
async fn handle_302_redirect(
|
||||||
&mut self,
|
&mut self,
|
||||||
new_url: url::Url,
|
new_url: url::Url,
|
||||||
|
url_str: &str,
|
||||||
) -> Result<Box<dyn TunnelConnector>, Error> {
|
) -> Result<Box<dyn TunnelConnector>, Error> {
|
||||||
// the url should be in following format:
|
// the url should be in following format:
|
||||||
// 1: http(s)://easytier.cn/?url=tcp://10.147.22.22:11010 (scheme is http, domain is ignored, path is splitted into proto type and addr)
|
// 1: http(s)://easytier.cn/?url=tcp://10.147.22.22:11010 (scheme is http, domain is ignored, path is splitted into proto type and addr)
|
||||||
// 2: tcp://10.137.22.22:11010 (scheme is protocol type, the url is used to construct a connector directly)
|
// 2: http(s)://tcp://10.137.22.22:11010 (connector url is appended to the scheme)
|
||||||
|
// 3: tcp://10.137.22.22:11010 (scheme is protocol type, the url is used to construct a connector directly)
|
||||||
tracing::info!("redirect to {}", new_url);
|
tracing::info!("redirect to {}", new_url);
|
||||||
let url = url::Url::parse(new_url.as_str())
|
let url = url::Url::parse(new_url.as_str())
|
||||||
.with_context(|| format!("parsing redirect url failed. url: {}", new_url))?;
|
.with_context(|| format!("parsing redirect url failed. url: {}", new_url))?;
|
||||||
@@ -86,15 +89,22 @@ impl HttpTunnelConnector {
|
|||||||
.filter_map(|x| url::Url::parse(&x.1).ok())
|
.filter_map(|x| url::Url::parse(&x.1).ok())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
query.shuffle(&mut rand::thread_rng());
|
query.shuffle(&mut rand::thread_rng());
|
||||||
if query.is_empty() {
|
if !query.is_empty() {
|
||||||
return Err(Error::InvalidUrl(format!(
|
tracing::info!("try to create connector by url: {}", query[0]);
|
||||||
"no valid connector url found in url: {}",
|
self.redirect_type = HttpRedirectType::RedirectToQuery;
|
||||||
url
|
return create_connector_by_url(&query[0].to_string(), &self.global_ctx).await;
|
||||||
)));
|
} else if let Some(new_url) = url_str
|
||||||
|
.strip_prefix(format!("{}://", url.scheme()).as_str())
|
||||||
|
.and_then(|x| Url::parse(x).ok())
|
||||||
|
{
|
||||||
|
// stripe the scheme and create connector by url
|
||||||
|
self.redirect_type = HttpRedirectType::RedirectToUrl;
|
||||||
|
return create_connector_by_url(new_url.as_str(), &self.global_ctx).await;
|
||||||
}
|
}
|
||||||
tracing::info!("try to create connector by url: {}", query[0]);
|
return Err(Error::InvalidUrl(format!(
|
||||||
self.redirect_type = HttpRedirectType::RedirectToQuery;
|
"no valid connector url found in url: {}",
|
||||||
return create_connector_by_url(&query[0].to_string(), &self.global_ctx).await;
|
url
|
||||||
|
)));
|
||||||
} else {
|
} else {
|
||||||
self.redirect_type = HttpRedirectType::RedirectToUrl;
|
self.redirect_type = HttpRedirectType::RedirectToUrl;
|
||||||
return create_connector_by_url(new_url.as_str(), &self.global_ctx).await;
|
return create_connector_by_url(new_url.as_str(), &self.global_ctx).await;
|
||||||
@@ -156,7 +166,7 @@ impl HttpTunnelConnector {
|
|||||||
|
|
||||||
Request::new(&uri)
|
Request::new(&uri)
|
||||||
.redirect_policy(RedirectPolicy::Limit(0))
|
.redirect_policy(RedirectPolicy::Limit(0))
|
||||||
.timeout(std::time::Duration::from_secs(60))
|
.timeout(std::time::Duration::from_secs(20))
|
||||||
.send(&mut *body_clone.write().unwrap())
|
.send(&mut *body_clone.write().unwrap())
|
||||||
.with_context(|| format!("sending http request failed. url: {}", uri))
|
.with_context(|| format!("sending http request failed. url: {}", uri))
|
||||||
})
|
})
|
||||||
@@ -172,7 +182,7 @@ impl HttpTunnelConnector {
|
|||||||
.ok_or_else(|| Error::InvalidUrl("no redirect address found".to_string()))?;
|
.ok_or_else(|| Error::InvalidUrl("no redirect address found".to_string()))?;
|
||||||
let new_url = url::Url::parse(redirect_url.as_str())
|
let new_url = url::Url::parse(redirect_url.as_str())
|
||||||
.with_context(|| format!("parsing redirect url failed. url: {}", redirect_url))?;
|
.with_context(|| format!("parsing redirect url failed. url: {}", redirect_url))?;
|
||||||
return self.handle_302_redirect(new_url).await;
|
return self.handle_302_redirect(new_url, &redirect_url).await;
|
||||||
} else if res.status_code().is_success() {
|
} else if res.status_code().is_success() {
|
||||||
return self.handle_200_success(&body).await;
|
return self.handle_200_success(&body).await;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -365,9 +365,12 @@ impl ManualConnectorManager {
|
|||||||
"cannot get ip from url"
|
"cannot get ip from url"
|
||||||
)));
|
)));
|
||||||
for ip_version in ip_versions {
|
for ip_version in ip_versions {
|
||||||
|
let use_long_timeout = dead_url.starts_with("http")
|
||||||
|
|| dead_url.starts_with("srv")
|
||||||
|
|| dead_url.starts_with("txt");
|
||||||
let ret = timeout(
|
let ret = timeout(
|
||||||
// allow http connector to wait longer
|
// allow http connector to wait longer
|
||||||
std::time::Duration::from_secs(if dead_url.starts_with("http") { 20 } else { 2 }),
|
std::time::Duration::from_secs(if use_long_timeout { 20 } else { 2 }),
|
||||||
Self::conn_reconnect_with_ip_version(
|
Self::conn_reconnect_with_ip_version(
|
||||||
data.clone(),
|
data.clone(),
|
||||||
dead_url.clone(),
|
dead_url.clone(),
|
||||||
|
|||||||
Reference in New Issue
Block a user