v0.34.0_1
This commit is contained in:
1 parent
9b3d6731cc
commit
00f29f92c8
68 files changed
+2599
-513
No files matched your search
@@ -60,15 +60,36 @@ if pending_revalidation {
|
||||
if request.method() == Method::HEAD && cache_ticket.is_some() {
|
||||
*request.method_mut() = Method::GET;
|
||||
}
|
||||
// Preserve a pre-normalization Host snapshot for pool retries. Each next
|
||||
// backend gets its OWN target and Host/:authority, never the previous peer's.
|
||||
let retry_headers = request.headers().clone();
|
||||
// Save the pre-normalization headers only for replayable requests that may
|
||||
// actually be retried. The common one-backend HTTP/1 route has no retry peer
|
||||
// or H2 GOAWAY handling, so copying HeaderMap for every request was wasted.
|
||||
// Never replay writes, streaming uploads, auth or WebSocket requests.
|
||||
let retry_method = request.method().clone();
|
||||
let retry_policy = route.pool.as_ref().map(|pool| &pool.settings.retry);
|
||||
let pool_retry_possible = route.backend_id.is_none()
|
||||
&& !admin_control_plane
|
||||
&& handshake.is_none()
|
||||
&& retry_safe_method(&retry_method)
|
||||
&& route.pool.as_ref().is_some_and(|pool| pool.members.len() > 1)
|
||||
&& retry_policy.is_some_and(|policy| policy.max_retries > 0);
|
||||
let h2_replay_possible = !admin_control_plane
|
||||
&& handshake.is_none()
|
||||
&& retry_safe_method(&retry_method)
|
||||
&& matches!(backend.protocol,
|
||||
crate::config::UpstreamProtocol::Http2
|
||||
| crate::config::UpstreamProtocol::H2
|
||||
| crate::config::UpstreamProtocol::Auto);
|
||||
let replay_headers = ((pool_retry_possible || h2_replay_possible)
|
||||
&& (request.body().size_hint().exact() == Some(0)
|
||||
|| request.version() == Version::HTTP_3))
|
||||
.then(|| request.headers().clone());
|
||||
let expected_backend_host = if backend.preserve_host {
|
||||
&original_host
|
||||
} else {
|
||||
&backend.host_header
|
||||
};
|
||||
let retry_host_follows_backend = retry_headers.get(HOST)
|
||||
let retry_host_follows_backend = replay_headers.as_ref()
|
||||
.and_then(|headers| headers.get(HOST))
|
||||
.is_some_and(|value| value == expected_backend_host);
|
||||
let Some(upstream_target) = upstream_request_target(
|
||||
&uri, request.headers_mut(), &backend,
|
||||
@@ -125,14 +146,7 @@ let proactive_base_headers = if cache_ticket.is_some() && cache_settings.proacti
|
||||
let response_header_timeout = frontend
|
||||
.and_then(|frontend| frontend.proxy_timeouts.response_header_timeout())
|
||||
.unwrap_or(state.header_timeout);
|
||||
let retry_method = request.method().clone();
|
||||
let retry_policy = route.pool.as_ref().map(|pool| pool.settings.retry.clone());
|
||||
let retry_enabled = route.backend_id.is_none()
|
||||
&& !admin_control_plane
|
||||
&& handshake.is_none()
|
||||
&& request_body_empty
|
||||
&& retry_safe_method(&retry_method)
|
||||
&& retry_policy.as_ref().is_some_and(|policy| policy.max_retries > 0);
|
||||
let retry_enabled = pool_retry_possible && request_body_empty && replay_headers.is_some();
|
||||
let upstream_started = Instant::now();
|
||||
let mut attempt_started = Instant::now();
|
||||
let mut active_backend = backend.clone();
|
||||
@@ -165,15 +179,15 @@ let upstream_result = loop {
|
||||
&& (is_graceful_h2_goaway(cause)
|
||||
|| is_related_h2_close(cause, &active_backend))
|
||||
{
|
||||
if let Some(next_request) = retry_request(
|
||||
if let Some(next_request) = replay_headers.as_ref().and_then(|headers| retry_request(
|
||||
&retry_method,
|
||||
upstream_request_version(&active_backend, false),
|
||||
&retry_headers,
|
||||
headers,
|
||||
&active_backend,
|
||||
&original_host,
|
||||
&origin_suffix,
|
||||
retry_host_follows_backend,
|
||||
) {
|
||||
)) {
|
||||
graceful_retry_done = true;
|
||||
if let Some(lease) = &active_lease {
|
||||
lease.retry_attempted();
|
||||
@@ -201,6 +215,9 @@ let upstream_result = loop {
|
||||
break result;
|
||||
}
|
||||
attempted_backends.push(active_backend.id.clone());
|
||||
let Some(retry_headers) = replay_headers.as_ref() else {
|
||||
break result;
|
||||
};
|
||||
let Some(pool) = route.pool.as_ref() else {
|
||||
break result;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user