2626#include " source/common/common/assert.h"
2727#include " source/common/common/logger.h"
2828#include " source/common/common/utility.h"
29+ #include " source/common/http/headers.h"
2930#include " source/extensions/filters/http/common/factory_base.h"
3031
3132#include " absl/status/statusor.h"
@@ -299,8 +300,10 @@ void AccessFilter::onStreamComplete() {
299300}
300301
301302Http::FilterHeadersStatus AccessFilter::encodeHeaders (Http::ResponseHeaderMap& headers, bool ) {
303+ const auto & stream_info = callbacks_->streamInfo ();
304+
302305 // Skip enforcement or logging on shadows
303- if (callbacks_-> streamInfo () .isShadow ()) {
306+ if (stream_info .isShadow ()) {
304307 return Http::FilterHeadersStatus::Continue;
305308 }
306309
@@ -312,6 +315,33 @@ Http::FilterHeadersStatus AccessFilter::encodeHeaders(Http::ResponseHeaderMap& h
312315 return Http::FilterHeadersStatus::Continue;
313316 }
314317
318+ // Propagate connection: close from upstream to downstream (if original source is preserved)
319+ if (callbacks_->connection ().has_value () && stream_info.upstreamInfo ().has_value () &&
320+ stream_info.hasResponseFlag (StreamInfo::UpstreamConnectionTermination)) {
321+ // check if upstream and downstream connections have the same source and destination
322+ // addresses, respectively
323+ const auto & conn = callbacks_->connection ().ref ();
324+ const auto & upstream_info = stream_info.upstreamInfo ().ref ();
325+
326+ if (upstream_info.upstreamRemoteAddress () == conn.connectionInfoProvider ().localAddress () &&
327+ upstream_info.upstreamLocalAddress () == conn.connectionInfoProvider ().remoteAddress ()) {
328+ ENVOY_CONN_LOG (debug,
329+ " Upstream connection with same 5-tuple closed, passing connection close to "
330+ " downstream response" ,
331+ conn);
332+
333+ headers.setReferenceConnection (Http::Headers::get ().ConnectionValues .Close );
334+ } else {
335+ ENVOY_CONN_LOG (debug,
336+ " Upstream connection closed, but it has different 5-tuple, downstream "
337+ " connection not closed (src: {}/{}, dst: {}/{})" ,
338+ conn, conn.connectionInfoProvider ().remoteAddress ()->asStringView (),
339+ upstream_info.upstreamLocalAddress ()->asStringView (),
340+ conn.connectionInfoProvider ().localAddress ()->asStringView (),
341+ upstream_info.upstreamRemoteAddress ()->asStringView ());
342+ }
343+ }
344+
315345 if (log_entry_ == nullptr ) {
316346 return Http::FilterHeadersStatus::Continue;
317347 }
0 commit comments