Fix bug in http proxy where response headers would be deduplicated

The fix was, ultimately, to upgrade hyper-reverse-proxy to an unreleased
version.
This commit is contained in:
Brian Picciano 2024-01-14 16:43:33 +01:00
parent 92254047b2
commit 658ac62347
4 changed files with 87 additions and 18 deletions

75
Cargo.lock generated
View File

@ -511,6 +511,7 @@ dependencies = [
"http", "http",
"hyper", "hyper",
"hyper-reverse-proxy", "hyper-reverse-proxy",
"hyper-trust-dns",
"log", "log",
"mime_guess", "mime_guess",
"mockall", "mockall",
@ -519,7 +520,7 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
"reqwest", "reqwest",
"rust-embed", "rust-embed",
"rustls", "rustls 0.21.1",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
@ -531,7 +532,7 @@ dependencies = [
"thiserror", "thiserror",
"tls-listener", "tls-listener",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls 0.24.1",
"tokio-util", "tokio-util",
"trust-dns-client", "trust-dns-client",
] ]
@ -1608,13 +1609,27 @@ dependencies = [
[[package]] [[package]]
name = "hyper-reverse-proxy" name = "hyper-reverse-proxy"
version = "0.5.1" version = "0.5.2-dev"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/felipenoris/hyper-reverse-proxy.git?rev=e73a76600ce9e51e962de5266b03be596e6c1d50#e73a76600ce9e51e962de5266b03be596e6c1d50"
checksum = "cc1af9b1b483fb9f33bd1cda26b35eacf902f0d116fcf0d56075ea5e5923b935"
dependencies = [ dependencies = [
"hyper", "hyper",
"lazy_static", "lazy_static",
"unicase", "tokio",
"tracing",
]
[[package]]
name = "hyper-rustls"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c"
dependencies = [
"http",
"hyper",
"rustls 0.20.9",
"tokio",
"tokio-rustls 0.23.4",
"webpki-roots",
] ]
[[package]] [[package]]
@ -1626,9 +1641,9 @@ dependencies = [
"futures-util", "futures-util",
"http", "http",
"hyper", "hyper",
"rustls", "rustls 0.21.1",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls 0.24.1",
] ]
[[package]] [[package]]
@ -1644,6 +1659,18 @@ dependencies = [
"tokio-native-tls", "tokio-native-tls",
] ]
[[package]]
name = "hyper-trust-dns"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0deaf08b5c5409c0c74011f696a82bdadae4c6d70b7a71edf8378b29bdd840bd"
dependencies = [
"hyper",
"hyper-rustls 0.23.2",
"tokio",
"trust-dns-resolver",
]
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.56" version = "0.1.56"
@ -2526,7 +2553,7 @@ dependencies = [
"http", "http",
"http-body", "http-body",
"hyper", "hyper",
"hyper-rustls", "hyper-rustls 0.24.1",
"hyper-tls", "hyper-tls",
"ipnet", "ipnet",
"js-sys", "js-sys",
@ -2536,14 +2563,14 @@ dependencies = [
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"rustls", "rustls 0.21.1",
"rustls-pemfile", "rustls-pemfile",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"tokio", "tokio",
"tokio-native-tls", "tokio-native-tls",
"tokio-rustls", "tokio-rustls 0.24.1",
"tower-service", "tower-service",
"trust-dns-resolver", "trust-dns-resolver",
"url", "url",
@ -2633,6 +2660,17 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "rustls"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99"
dependencies = [
"ring",
"sct",
"webpki",
]
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.21.1" version = "0.21.1"
@ -3041,7 +3079,7 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls 0.24.1",
] ]
[[package]] [[package]]
@ -3084,12 +3122,23 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tokio-rustls"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
dependencies = [
"rustls 0.20.9",
"tokio",
"webpki",
]
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.24.1" version = "0.24.1"
source = "git+https://code.betamike.com/micropelago/tokio-rustls.git?branch=start-handshake-into-inner#3d462a1d97836cdb0600f0bc69c5e3b3310f6d8c" source = "git+https://code.betamike.com/micropelago/tokio-rustls.git?branch=start-handshake-into-inner#3d462a1d97836cdb0600f0bc69c5e3b3310f6d8c"
dependencies = [ dependencies = [
"rustls", "rustls 0.21.1",
"tokio", "tokio",
] ]

View File

@ -43,11 +43,13 @@ env_logger = "0.10.0"
serde_yaml = "0.9.22" serde_yaml = "0.9.22"
rand = "0.8.5" rand = "0.8.5"
reqwest = "0.11.18" reqwest = "0.11.18"
hyper-reverse-proxy = "0.5.1" hyper-reverse-proxy = "0.5.2-dev"
gemini = "0.0.5" gemini = "0.0.5"
bytes = "1.4.0" bytes = "1.4.0"
hyper-trust-dns = "0.5.0"
[patch.crates-io] [patch.crates-io]
# The micropelago fork of tokio-rustls allows for gemini proxying # The micropelago fork of tokio-rustls allows for gemini proxying
tokio-rustls = { git = "https://code.betamike.com/micropelago/tokio-rustls.git", branch = "start-handshake-into-inner" } tokio-rustls = { git = "https://code.betamike.com/micropelago/tokio-rustls.git", branch = "start-handshake-into-inner" }
hyper-reverse-proxy = { git = "https://github.com/felipenoris/hyper-reverse-proxy.git", rev = "e73a76600ce9e51e962de5266b03be596e6c1d50" }

View File

@ -196,11 +196,15 @@
(buildSystem: targetSystem: let (buildSystem: targetSystem: let
pkgs = mkPkgs buildSystem null; pkgs = mkPkgs buildSystem null;
toolchain = mkToolchain buildSystem targetSystem; toolchain = mkToolchain buildSystem targetSystem;
# make clippy available directly
clippy = pkgs.writeShellScriptBin "clippy" ''exec cargo clippy "$@"'';
in in
pkgs.mkShell ({ pkgs.mkShell ({
packages = [ clippy ]; # extra packages for dev shellHook = ''
export CARGO_HOME=$(pwd)/.cargo
if [ -f "config-dev.yml" ]; then
export DOMANI_CONFIG_PATH=config-dev.yml
fi
'';
} // (buildEnv buildSystem targetSystem)) } // (buildEnv buildSystem targetSystem))
); );
}; };

View File

@ -1,6 +1,20 @@
use crate::error::unexpected; use crate::error::unexpected;
use std::net; use std::net;
use hyper_reverse_proxy::ReverseProxy;
use hyper_trust_dns::{TrustDnsHttpConnector, TrustDnsResolver};
fn proxy_client() -> &'static ReverseProxy<TrustDnsHttpConnector> {
use std::sync::OnceLock;
static PROXY_CLIENT: OnceLock<ReverseProxy<TrustDnsHttpConnector>> = OnceLock::new();
PROXY_CLIENT.get_or_init(|| {
ReverseProxy::new(
hyper::Client::builder()
.build::<_, hyper::Body>(TrustDnsResolver::default().into_http_connector()),
)
})
}
pub async fn serve_http_request( pub async fn serve_http_request(
proxy_addr: &str, proxy_addr: &str,
headers: &http::header::HeaderMap, headers: &http::header::HeaderMap,
@ -24,7 +38,7 @@ pub async fn serve_http_request(
); );
} }
match hyper_reverse_proxy::call(client_ip, proxy_addr, req).await { match proxy_client().call(client_ip, proxy_addr, req).await {
Ok(res) => Ok(res), Ok(res) => Ok(res),
// ProxyError doesn't actually implement Error :facepalm: so we have to format the error // ProxyError doesn't actually implement Error :facepalm: so we have to format the error
// manually // manually