fix(rustproxy-http,rustproxy-metrics): fix domain-scoped request host detection and harden connection metrics cleanup
This commit is contained in:
@@ -11,8 +11,8 @@ use std::task::{Context, Poll};
|
||||
|
||||
use bytes::{Buf, Bytes};
|
||||
use http_body::Frame;
|
||||
use http_body_util::BodyExt;
|
||||
use http_body_util::combinators::BoxBody;
|
||||
use http_body_util::BodyExt;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use rustproxy_config::RouteConfig;
|
||||
@@ -49,7 +49,8 @@ impl H3ProxyService {
|
||||
debug!("HTTP/3 connection from {} on port {}", remote_addr, port);
|
||||
|
||||
// Track frontend H3 connection for the QUIC connection's lifetime.
|
||||
let _frontend_h3_guard = ProtocolGuard::frontend(Arc::clone(self.http_proxy.metrics()), "h3");
|
||||
let _frontend_h3_guard =
|
||||
ProtocolGuard::frontend(Arc::clone(self.http_proxy.metrics()), "h3");
|
||||
|
||||
let mut h3_conn: h3::server::Connection<h3_quinn::Connection, Bytes> =
|
||||
h3::server::builder()
|
||||
@@ -92,8 +93,15 @@ impl H3ProxyService {
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = handle_h3_request(
|
||||
request, stream, port, remote_addr, &http_proxy, request_cancel,
|
||||
).await {
|
||||
request,
|
||||
stream,
|
||||
port,
|
||||
remote_addr,
|
||||
&http_proxy,
|
||||
request_cancel,
|
||||
)
|
||||
.await
|
||||
{
|
||||
debug!("HTTP/3 request error from {}: {}", remote_addr, e);
|
||||
}
|
||||
});
|
||||
@@ -153,11 +161,14 @@ async fn handle_h3_request(
|
||||
// Delegate to HttpProxyService — same backend path as TCP/HTTP:
|
||||
// route matching, ALPN protocol detection, connection pool, H1/H2/H3 auto.
|
||||
let conn_activity = ConnActivity::new_standalone();
|
||||
let response = http_proxy.handle_request(req, peer_addr, port, cancel, conn_activity).await
|
||||
let response = http_proxy
|
||||
.handle_request(req, peer_addr, port, cancel, conn_activity)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Backend request failed: {}", e))?;
|
||||
|
||||
// Await the body reader to get the H3 stream back
|
||||
let mut stream = body_reader.await
|
||||
let mut stream = body_reader
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Body reader task failed: {}", e))?;
|
||||
|
||||
// Send response headers over H3 (skip hop-by-hop headers)
|
||||
@@ -170,10 +181,13 @@ async fn handle_h3_request(
|
||||
}
|
||||
h3_response = h3_response.header(name, value);
|
||||
}
|
||||
let h3_response = h3_response.body(())
|
||||
let h3_response = h3_response
|
||||
.body(())
|
||||
.map_err(|e| anyhow::anyhow!("Failed to build H3 response: {}", e))?;
|
||||
|
||||
stream.send_response(h3_response).await
|
||||
stream
|
||||
.send_response(h3_response)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to send H3 response: {}", e))?;
|
||||
|
||||
// Stream response body back over H3
|
||||
@@ -182,7 +196,9 @@ async fn handle_h3_request(
|
||||
match frame {
|
||||
Ok(frame) => {
|
||||
if let Ok(data) = frame.into_data() {
|
||||
stream.send_data(data).await
|
||||
stream
|
||||
.send_data(data)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to send H3 data: {}", e))?;
|
||||
}
|
||||
}
|
||||
@@ -194,7 +210,9 @@ async fn handle_h3_request(
|
||||
}
|
||||
|
||||
// Finish the H3 stream (send QUIC FIN)
|
||||
stream.finish().await
|
||||
stream
|
||||
.finish()
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to finish H3 stream: {}", e))?;
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user