diff --git a/RAW_RELEASE_NOTES.md b/RAW_RELEASE_NOTES.md index 93a768912d7a..a0aea8728b38 100644 --- a/RAW_RELEASE_NOTES.md +++ b/RAW_RELEASE_NOTES.md @@ -51,3 +51,5 @@ final version. :ref:`Squash ` allows debugging an incoming request to a microservice in the mesh. * lua: added headers replace() API. * Added support for direct responses -- i.e., sending a preconfigured HTTP response without proxying anywhere. +* Added DOWNSTREAM_LOCAL_ADDRESS, DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT header formatters, and + DOWNSTREAM_LOCAL_ADDRESS access log formatter. diff --git a/source/common/access_log/access_log_formatter.cc b/source/common/access_log/access_log_formatter.cc index 8dfd1c312fdc..8f4b09810df1 100644 --- a/source/common/access_log/access_log_formatter.cc +++ b/source/common/access_log/access_log_formatter.cc @@ -235,6 +235,11 @@ RequestInfoFormatter::RequestInfoFormatter(const std::string& field_name) { field_extractor_ = [](const RequestInfo::RequestInfo& request_info) { return request_info.downstreamLocalAddress()->asString(); }; + } else if (field_name == "DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT") { + field_extractor_ = [](const Envoy::RequestInfo::RequestInfo& request_info) { + return RequestInfo::Utility::formatDownstreamAddressNoPort( + *request_info.downstreamLocalAddress()); + }; } else if (field_name == "DOWNSTREAM_REMOTE_ADDRESS") { field_extractor_ = [](const RequestInfo::RequestInfo& request_info) { return request_info.downstreamRemoteAddress()->asString(); diff --git a/source/common/router/header_formatter.cc b/source/common/router/header_formatter.cc index e13a7c79e301..776c9fc98e77 100644 --- a/source/common/router/header_formatter.cc +++ b/source/common/router/header_formatter.cc @@ -126,6 +126,15 @@ RequestInfoHeaderFormatter::RequestInfoHeaderFormatter(absl::string_view field_n return RequestInfo::Utility::formatDownstreamAddressNoPort( *request_info.downstreamRemoteAddress()); }; + } else if (field_name == "DOWNSTREAM_LOCAL_ADDRESS") { + field_extractor_ = [](const RequestInfo::RequestInfo& request_info) { + return request_info.downstreamLocalAddress()->asString(); + }; + } else if (field_name == "DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT") { + field_extractor_ = [](const Envoy::RequestInfo::RequestInfo& request_info) { + return RequestInfo::Utility::formatDownstreamAddressNoPort( + *request_info.downstreamLocalAddress()); + }; } else if (field_name.find_first_of("UPSTREAM_METADATA") == 0) { field_extractor_ = parseUpstreamMetadataField(field_name.substr(STATIC_STRLEN("UPSTREAM_METADATA"))); diff --git a/test/common/access_log/access_log_formatter_test.cc b/test/common/access_log/access_log_formatter_test.cc index 2cb23417ea36..7ba1c5c15549 100644 --- a/test/common/access_log/access_log_formatter_test.cc +++ b/test/common/access_log/access_log_formatter_test.cc @@ -157,6 +157,11 @@ TEST(AccessLogFormatterTest, requestInfoFormatter) { EXPECT_EQ("127.0.0.2:0", upstream_format.format(header, header, request_info)); } + { + RequestInfoFormatter upstream_format("DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT"); + EXPECT_EQ("127.0.0.2", upstream_format.format(header, header, request_info)); + } + { RequestInfoFormatter upstream_format("DOWNSTREAM_ADDRESS"); EXPECT_EQ("127.0.0.1", upstream_format.format(header, header, request_info)); diff --git a/test/common/router/header_formatter_test.cc b/test/common/router/header_formatter_test.cc index bd1d51d69bba..ee0fcf728cef 100644 --- a/test/common/router/header_formatter_test.cc +++ b/test/common/router/header_formatter_test.cc @@ -64,6 +64,14 @@ TEST_F(RequestInfoHeaderFormatterTest, TestFormatWithDownstreamRemoteAddressVari testFormatting("DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT", "127.0.0.1"); } +TEST_F(RequestInfoHeaderFormatterTest, TestFormatWithDownstreamLocalAddressVariable) { + testFormatting("DOWNSTREAM_LOCAL_ADDRESS", "127.0.0.2:0"); +} + +TEST_F(RequestInfoHeaderFormatterTest, TestFormatWithDownstreamLocalAddressWithoutPortVariable) { + testFormatting("DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT", "127.0.0.2"); +} + TEST_F(RequestInfoHeaderFormatterTest, TestFormatWithProtocolVariable) { NiceMock request_info; Optional protocol = Envoy::Http::Protocol::Http11; @@ -252,6 +260,8 @@ TEST(HeaderParserTest, TestParseInternal) { {"%PROTOCOL%%%", {"HTTP/1.1%"}, {}}, {"%%%PROTOCOL%%%", {"%HTTP/1.1%"}, {}}, {"%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%", {"127.0.0.1"}, {}}, + {"%DOWNSTREAM_LOCAL_ADDRESS%", {"127.0.0.2:0"}, {}}, + {"%DOWNSTREAM_LOCAL_ADDRESS_WITHOUT_PORT%", {"127.0.0.2"}, {}}, {"%UPSTREAM_METADATA([\"ns\", \"key\"])%", {"value"}, {}}, {"[%UPSTREAM_METADATA([\"ns\", \"key\"])%", {"[value"}, {}}, {"%UPSTREAM_METADATA([\"ns\", \"key\"])%]", {"value]"}, {}},