From a8261066735a3dc802cc141348a4c53bfc721c73 Mon Sep 17 00:00:00 2001 From: "glm-5.1" Date: Fri, 12 Jun 2026 04:43:59 +0000 Subject: [PATCH] Remove /health route from main listener and hardcode X-Forwarded-Proto to https - Remove health_handler and /health early return from proxy_handler - Remove /health route from proxy_router (now just fallback) - Remove is_https field from ProxyState struct - Remove is_https parameter from inject_proxy_headers, hardcode https - Add comment explaining why X-Forwarded-Proto is always https - Remove health_path_returns_200 and health_with_unknown_host tests - Update all inject_proxy_headers test calls to remove is_https param - Remove inject_proxy_headers_sets_x_forwarded_proto_http test --- src/main.rs | 1 - src/proxy/handler.rs | 58 ++------------------------------------------ src/proxy/headers.rs | 33 ++++++++++--------------- 3 files changed, 15 insertions(+), 77 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7c96d4c..0ba30b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -74,7 +74,6 @@ async fn run_server(loaded_config: cli::LoadedConfig, config_path: &str) -> Resu config: config_arc.clone(), http_client, https_client, - is_https: true, }); let reload_handle = Arc::new(ConfigReloadHandle::new( diff --git a/src/proxy/handler.rs b/src/proxy/handler.rs index 8fba3d8..5a5ff5f 100644 --- a/src/proxy/handler.rs +++ b/src/proxy/handler.rs @@ -7,7 +7,6 @@ use axum::body::Body; use axum::extract::{ConnectInfo, State}; use axum::http::{Request, StatusCode, Uri}; use axum::response::{IntoResponse, Response}; -use axum::routing::get; use axum::Router; use hyper_util::client::legacy::connect::HttpConnector; use hyper_util::client::legacy::Client; @@ -22,11 +21,6 @@ pub struct ProxyState { pub config: Arc>, pub http_client: Client, pub https_client: Client, Body>, - pub is_https: bool, -} - -async fn health_handler() -> impl IntoResponse { - StatusCode::OK } async fn proxy_handler( @@ -34,10 +28,6 @@ async fn proxy_handler( State(state): State>, mut req: Request, ) -> Response { - if req.uri().path() == "/health" { - return StatusCode::OK.into_response(); - } - let host = req .headers() .get(axum::http::header::HOST) @@ -55,7 +45,7 @@ async fn proxy_handler( }; let host_owned = host.to_string(); - inject_proxy_headers(req.headers_mut(), remote_addr, state.is_https); + inject_proxy_headers(req.headers_mut(), remote_addr); remove_hop_by_hop(req.headers_mut()); let upstream_scheme = site.upstream_scheme.clone(); @@ -165,10 +155,7 @@ fn root_certs() -> rustls::RootCertStore { } pub fn proxy_router(state: Arc) -> Router { - Router::new() - .route("/health", get(health_handler)) - .fallback(proxy_handler) - .with_state(state) + Router::new().fallback(proxy_handler).with_state(state) } #[cfg(test)] @@ -195,7 +182,6 @@ mod tests { ))), http_client: create_http_client(), https_client: create_https_client(), - is_https: true, }) } @@ -214,46 +200,6 @@ mod tests { req } - #[tokio::test] - async fn health_path_returns_200_regardless_of_host() { - let state = make_proxy_state(vec![SiteConfig { - host: "example.com".to_string(), - upstream: "127.0.0.1:8080".to_string(), - upstream_scheme: "http".to_string(), - upstream_connect_timeout_secs: 5, - upstream_request_timeout_secs: 60, - }]); - let router = proxy_router(state); - let req = make_request_with_connect_info( - "GET", - "/health", - None, - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12345), - ); - let resp = router.oneshot(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - } - - #[tokio::test] - async fn health_with_unknown_host_returns_200() { - let state = make_proxy_state(vec![SiteConfig { - host: "example.com".to_string(), - upstream: "127.0.0.1:8080".to_string(), - upstream_scheme: "http".to_string(), - upstream_connect_timeout_secs: 5, - upstream_request_timeout_secs: 60, - }]); - let router = proxy_router(state); - let req = make_request_with_connect_info( - "GET", - "/health", - Some("unknown.host"), - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12345), - ); - let resp = router.oneshot(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - } - #[tokio::test] async fn missing_host_returns_400() { let state = make_proxy_state(vec![SiteConfig { diff --git a/src/proxy/headers.rs b/src/proxy/headers.rs index d96f0a9..e417569 100644 --- a/src/proxy/headers.rs +++ b/src/proxy/headers.rs @@ -18,7 +18,7 @@ pub fn remove_hop_by_hop(headers: &mut HeaderMap) { } } -pub fn inject_proxy_headers(headers: &mut HeaderMap, remote_addr: SocketAddr, is_https: bool) { +pub fn inject_proxy_headers(headers: &mut HeaderMap, remote_addr: SocketAddr) { let ip_str = remote_addr.ip().to_string(); let ip_value = HeaderValue::from_str(&ip_str).unwrap_or_else(|_| HeaderValue::from_static("0.0.0.0")); @@ -27,12 +27,13 @@ pub fn inject_proxy_headers(headers: &mut HeaderMap, remote_addr: SocketAddr, is headers.insert(HeaderName::from_static("x-forwarded-for"), ip_value); - let proto_value = if is_https { - HeaderValue::from_static("https") - } else { - HeaderValue::from_static("http") - }; - headers.insert(HeaderName::from_static("x-forwarded-proto"), proto_value); + // X-Forwarded-Proto is always "https" because this proxy only forwards requests + // received on the TLS listener. The HTTP listener redirects to HTTPS and does not + // proxy requests, so X-Forwarded-Proto is never set for HTTP connections. + headers.insert( + HeaderName::from_static("x-forwarded-proto"), + HeaderValue::from_static("https"), + ); } #[cfg(test)] @@ -84,7 +85,7 @@ mod tests { fn inject_proxy_headers_sets_x_real_ip() { let mut h = HeaderMap::new(); let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 12345); - inject_proxy_headers(&mut h, addr, true); + inject_proxy_headers(&mut h, addr); assert_eq!(h.get("x-real-ip").unwrap(), "192.168.1.1"); } @@ -96,32 +97,24 @@ mod tests { HeaderValue::from_static("10.0.0.1, 10.0.0.2"), ); let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 12345); - inject_proxy_headers(&mut h, addr, true); + inject_proxy_headers(&mut h, addr); assert_eq!(h.get("x-forwarded-for").unwrap(), "192.168.1.1"); } #[test] - fn inject_proxy_headers_sets_x_forwarded_proto_https() { + fn inject_proxy_headers_sets_x_forwarded_proto_to_https() { let mut h = HeaderMap::new(); let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 443); - inject_proxy_headers(&mut h, addr, true); + inject_proxy_headers(&mut h, addr); assert_eq!(h.get("x-forwarded-proto").unwrap(), "https"); } - #[test] - fn inject_proxy_headers_sets_x_forwarded_proto_http() { - let mut h = HeaderMap::new(); - let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 80); - inject_proxy_headers(&mut h, addr, false); - assert_eq!(h.get("x-forwarded-proto").unwrap(), "http"); - } - #[test] fn inject_proxy_headers_preserves_host() { let mut h = HeaderMap::new(); h.insert("host", HeaderValue::from_static("example.com")); let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 443); - inject_proxy_headers(&mut h, addr, true); + inject_proxy_headers(&mut h, addr); assert_eq!(h.get("host").unwrap(), "example.com"); }