Skip to content

Commit b7de6c8

Browse files
committed
filers/ondemand: protect body behaviour change
runtime flag to protect the behaviour change Signed-off-by: William Dauchy <william.dauchy@datadoghq.com>
1 parent 1126a18 commit b7de6c8

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

changelogs/current.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,11 @@ new_features:
325325
change: |
326326
Added runtime guard ``envoy.reloadable_features.report_load_when_rq_active_is_non_zero``.
327327
When enabled, LRS continues to send locality_stats reoprt to config server when there is no request_issued in the poll cycle.
328+
- area: on_demand
329+
change: |
330+
Added runtime guard ``envoy.reloadable_features.on_demand_track_end_stream``.
331+
When enabled, the on_demand filter tracks downstream end_stream state to support stream recreation with fully read request bodies.
332+
Previously, the filter rejected all requests with bodies by checking for the presence of a decoding buffer, even when the body was complete.
328333
- area: router
329334
change: |
330335
Added :ref:`request_mirror_policies <envoy_v3_api_field_extensions.upstreams.http.v3.HttpProtocolOptions.request_mirror_policies>`

source/common/runtime/runtime_features.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ RUNTIME_GUARD(envoy_reloadable_features_no_extension_lookup_by_name);
6060
RUNTIME_GUARD(envoy_reloadable_features_oauth2_cleanup_cookies);
6161
RUNTIME_GUARD(envoy_reloadable_features_oauth2_encrypt_tokens);
6262
RUNTIME_GUARD(envoy_reloadable_features_odcds_over_ads_fix);
63+
RUNTIME_GUARD(envoy_reloadable_features_on_demand_track_end_stream);
6364
RUNTIME_GUARD(envoy_reloadable_features_original_dst_rely_on_idle_timeout);
6465
RUNTIME_GUARD(envoy_reloadable_features_prefix_map_matcher_resume_after_subtree_miss);
6566
RUNTIME_GUARD(envoy_reloadable_features_quic_defer_logging_to_ack_listener);

source/extensions/filters/http/on_demand/on_demand_update.cc

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,17 @@ void OnDemandRouteUpdate::onRouteConfigUpdateCompletion(bool route_exists) {
245245
return;
246246
}
247247

248-
if (route_exists && // route can be resolved after an on-demand
249-
// VHDS update
250-
downstream_end_stream_ && // Redirects require fully read body.
248+
bool can_recreate_stream = false;
249+
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.on_demand_track_end_stream")) {
250+
// New behavior: track end_stream state to support stream recreation with fully read bodies.
251+
can_recreate_stream = downstream_end_stream_;
252+
} else {
253+
// Old behavior: reject all requests with bodies.
254+
can_recreate_stream = !callbacks_->decodingBuffer();
255+
}
256+
if (route_exists && // route can be resolved after an on-demand
257+
// VHDS update
258+
can_recreate_stream && // Redirects require fully read body.
251259
callbacks_->recreateStream(/*headers=*/nullptr)) {
252260
return;
253261
}
@@ -261,8 +269,16 @@ void OnDemandRouteUpdate::onClusterDiscoveryCompletion(
261269
Upstream::ClusterDiscoveryStatus cluster_status) {
262270
filter_iteration_state_ = Http::FilterHeadersStatus::Continue;
263271
cluster_discovery_handle_.reset();
272+
bool can_recreate_stream = false;
273+
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.on_demand_track_end_stream")) {
274+
// New behavior: track end_stream state to support stream recreation with fully read bodies.
275+
can_recreate_stream = downstream_end_stream_;
276+
} else {
277+
// Old behavior: reject all requests with bodies.
278+
can_recreate_stream = !callbacks_->decodingBuffer();
279+
}
264280
if (cluster_status == Upstream::ClusterDiscoveryStatus::Available &&
265-
downstream_end_stream_) { // Redirects require fully read body.
281+
can_recreate_stream) { // Redirects require fully read body.
266282
const Http::ResponseHeaderMap* headers = nullptr;
267283
if (callbacks_->recreateStream(headers)) {
268284
callbacks_->downstreamCallbacks()->clearRouteCache();

0 commit comments

Comments
 (0)