mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-06 17:59:11 +00:00
feat: add X-Network-Name header to HTTP connector requests (#1839)
This allows HTTP redirect servers to provide network-specific node lists based on the client's network identity. Updated unit tests to verify the header is correctly sent.
This commit is contained in:
@@ -169,13 +169,19 @@ impl HttpTunnelConnector {
|
||||
|
||||
let original_url_clone = original_url.to_string();
|
||||
let body_clone = body.clone();
|
||||
let network_name = self.global_ctx.network.network_name.clone();
|
||||
let res = tokio::task::spawn_blocking(move || {
|
||||
let uri = http_req::uri::Uri::try_from(original_url_clone.as_ref())
|
||||
.with_context(|| format!("parsing url failed. url: {}", original_url_clone))?;
|
||||
|
||||
tracing::info!("sending http request to {}", uri);
|
||||
tracing::info!(
|
||||
"sending http request to {}, network_name: {}",
|
||||
uri,
|
||||
network_name
|
||||
);
|
||||
|
||||
Request::new(&uri)
|
||||
.header("X-Network-Name", &network_name)
|
||||
.redirect_policy(RedirectPolicy::Limit(0))
|
||||
.timeout(std::time::Duration::from_secs(20))
|
||||
.send(&mut *body_clone.write().unwrap())
|
||||
@@ -244,19 +250,39 @@ impl super::TunnelConnector for HttpTunnelConnector {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tokio::{io::AsyncWriteExt as _, net::TcpListener};
|
||||
use tokio::{io::AsyncReadExt as _, io::AsyncWriteExt as _, net::TcpListener};
|
||||
|
||||
use crate::{
|
||||
common::global_ctx::tests::get_mock_global_ctx,
|
||||
common::global_ctx::tests::get_mock_global_ctx_with_network,
|
||||
tunnel::{tcp::TcpTunnelListener, TunnelConnector, TunnelListener},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
async fn run_http_redirect_server(port: u16, test_type: HttpRedirectType) -> Result<(), Error> {
|
||||
let listener = TcpListener::bind(format!("0.0.0.0:{}", port)).await?;
|
||||
async fn run_http_redirect_server(
|
||||
port: u16,
|
||||
test_type: HttpRedirectType,
|
||||
) -> Result<String, Error> {
|
||||
let listener = TcpListener::bind(format!("127.0.0.1:{}", port)).await?;
|
||||
let (mut stream, _) = listener.accept().await?;
|
||||
|
||||
let mut buf = [0u8; 4096];
|
||||
let n = stream.read(&mut buf).await?;
|
||||
let req = String::from_utf8_lossy(&buf[..n]);
|
||||
|
||||
let mut captured_network_name = String::new();
|
||||
for line in req.lines() {
|
||||
if line.to_lowercase().starts_with("x-network-name:") {
|
||||
captured_network_name = line
|
||||
.split_once(':')
|
||||
.map(|x| x.1)
|
||||
.unwrap_or_default()
|
||||
.trim()
|
||||
.to_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
match test_type {
|
||||
HttpRedirectType::RedirectToQuery => {
|
||||
let resp = "HTTP/1.1 301 Moved Permanently\r\nLocation: http://test.com/?url=tcp://127.0.0.1:25888\r\n\r\n";
|
||||
@@ -276,7 +302,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(captured_network_name)
|
||||
}
|
||||
|
||||
#[rstest::rstest]
|
||||
@@ -292,10 +318,17 @@ mod tests {
|
||||
)]
|
||||
test_type: HttpRedirectType,
|
||||
) {
|
||||
let network_name = format!("net_{}", rand::random::<u32>());
|
||||
let http_task = tokio::spawn(run_http_redirect_server(35888, test_type));
|
||||
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
|
||||
let test_url: url::Url = "http://127.0.0.1:35888".parse().unwrap();
|
||||
let global_ctx = get_mock_global_ctx();
|
||||
|
||||
let identity = crate::common::config::NetworkIdentity {
|
||||
network_name: network_name.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
let global_ctx = get_mock_global_ctx_with_network(Some(identity));
|
||||
|
||||
let mut flags = global_ctx.config.get_flags();
|
||||
flags.bind_device = false;
|
||||
global_ctx.config.set_flags(flags);
|
||||
@@ -310,11 +343,14 @@ mod tests {
|
||||
|
||||
let t = connector.connect().await.unwrap();
|
||||
assert_eq!(connector.redirect_type, test_type);
|
||||
|
||||
let captured_name = http_task.await.unwrap().unwrap();
|
||||
assert_eq!(captured_name, network_name);
|
||||
|
||||
let info = t.info().unwrap();
|
||||
let remote_addr = info.remote_addr.unwrap();
|
||||
assert_eq!(remote_addr, test_url.into());
|
||||
|
||||
tokio::join!(task).0.unwrap();
|
||||
tokio::join!(http_task).0.unwrap().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user