summaryrefslogtreecommitdiff
path: root/ext/fetch
diff options
context:
space:
mode:
authorSean McArthur <sean@seanmonstar.com>2024-07-31 15:44:03 -0700
committerGitHub <noreply@github.com>2024-08-01 00:44:03 +0200
commitfbcd250bc8ffb3b577afca7131d1d37f55eb47a2 (patch)
tree8e69ebaaa21c3850128f40bddf996ed1e429e7d4 /ext/fetch
parentd3419f7d147b8c362a3795c8284d55ff6f4f3492 (diff)
fix(ext/fetch): use correct ALPN to socks5 proxies (#24817)
Closes #24632 Closes #24719
Diffstat (limited to 'ext/fetch')
-rw-r--r--ext/fetch/Cargo.toml3
-rw-r--r--ext/fetch/proxy.rs9
-rw-r--r--ext/fetch/tests.rs52
3 files changed, 58 insertions, 6 deletions
diff --git a/ext/fetch/Cargo.toml b/ext/fetch/Cargo.toml
index d3448d671..f0e06c87f 100644
--- a/ext/fetch/Cargo.toml
+++ b/ext/fetch/Cargo.toml
@@ -38,3 +38,6 @@ tokio-util = { workspace = true, features = ["io"] }
tower.workspace = true
tower-http.workspace = true
tower-service.workspace = true
+
+[dev-dependencies]
+fast-socks5.workspace = true
diff --git a/ext/fetch/proxy.rs b/ext/fetch/proxy.rs
index f23df5dd0..32a445d8b 100644
--- a/ext/fetch/proxy.rs
+++ b/ext/fetch/proxy.rs
@@ -727,7 +727,14 @@ where
}
}
Proxied::Socks(ref p) => p.connected(),
- Proxied::SocksTls(ref p) => p.inner().get_ref().0.connected(),
+ Proxied::SocksTls(ref p) => {
+ let tunneled_tls = p.inner().get_ref();
+ if tunneled_tls.1.alpn_protocol() == Some(b"h2") {
+ tunneled_tls.0.connected().negotiated_h2()
+ } else {
+ tunneled_tls.0.connected()
+ }
+ }
}
}
}
diff --git a/ext/fetch/tests.rs b/ext/fetch/tests.rs
index c99a08d34..dad1b34a9 100644
--- a/ext/fetch/tests.rs
+++ b/ext/fetch/tests.rs
@@ -4,6 +4,8 @@ use std::net::SocketAddr;
use std::sync::Arc;
use bytes::Bytes;
+use fast_socks5::server::Config as Socks5Config;
+use fast_socks5::server::Socks5Socket;
use http_body_util::BodyExt;
use tokio::io::AsyncReadExt;
use tokio::io::AsyncWriteExt;
@@ -19,27 +21,41 @@ static EXAMPLE_KEY: &[u8] =
async fn test_https_proxy_http11() {
let src_addr = create_https_server(false).await;
let prx_addr = create_http_proxy(src_addr).await;
- run_test_client(prx_addr, src_addr, false, http::Version::HTTP_11).await;
+ run_test_client(prx_addr, src_addr, "http", http::Version::HTTP_11).await;
}
#[tokio::test]
async fn test_https_proxy_h2() {
let src_addr = create_https_server(true).await;
let prx_addr = create_http_proxy(src_addr).await;
- run_test_client(prx_addr, src_addr, false, http::Version::HTTP_2).await;
+ run_test_client(prx_addr, src_addr, "http", http::Version::HTTP_2).await;
}
#[tokio::test]
async fn test_https_proxy_https_h2() {
let src_addr = create_https_server(true).await;
let prx_addr = create_https_proxy(src_addr).await;
- run_test_client(prx_addr, src_addr, true, http::Version::HTTP_2).await;
+ run_test_client(prx_addr, src_addr, "https", http::Version::HTTP_2).await;
+}
+
+#[tokio::test]
+async fn test_socks_proxy_http11() {
+ let src_addr = create_https_server(false).await;
+ let prx_addr = create_socks_proxy(src_addr).await;
+ run_test_client(prx_addr, src_addr, "socks5", http::Version::HTTP_11).await;
+}
+
+#[tokio::test]
+async fn test_socks_proxy_h2() {
+ let src_addr = create_https_server(true).await;
+ let prx_addr = create_socks_proxy(src_addr).await;
+ run_test_client(prx_addr, src_addr, "socks5", http::Version::HTTP_2).await;
}
async fn run_test_client(
prx_addr: SocketAddr,
src_addr: SocketAddr,
- https: bool,
+ proto: &str,
ver: http::Version,
) {
let client = create_http_client(
@@ -48,7 +64,7 @@ async fn run_test_client(
root_cert_store: None,
ca_certs: vec![],
proxy: Some(deno_tls::Proxy {
- url: format!("http{}://{}", if https { "s" } else { "" }, prx_addr),
+ url: format!("{}://{}", proto, prx_addr),
basic_auth: None,
}),
unsafely_ignore_certificate_errors: Some(vec![]),
@@ -186,3 +202,29 @@ async fn create_https_proxy(src_addr: SocketAddr) -> SocketAddr {
prx_addr
}
+
+async fn create_socks_proxy(src_addr: SocketAddr) -> SocketAddr {
+ let prx_tcp = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
+ let prx_addr = prx_tcp.local_addr().unwrap();
+
+ tokio::spawn(async move {
+ while let Ok((sock, _)) = prx_tcp.accept().await {
+ let cfg: Socks5Config = Default::default();
+ let mut socks_conn = Socks5Socket::new(sock, cfg.into())
+ .upgrade_to_socks5()
+ .await
+ .unwrap();
+
+ let fut = async move {
+ let mut dst_tcp =
+ tokio::net::TcpStream::connect(src_addr).await.unwrap();
+ tokio::io::copy_bidirectional(&mut socks_conn, &mut dst_tcp)
+ .await
+ .unwrap();
+ };
+ tokio::spawn(fut);
+ }
+ });
+
+ prx_addr
+}