From 108472ef7cfa02f83c6b97cc4f3e60e4cdcba419 Mon Sep 17 00:00:00 2001 From: nic-chen <33000667+nic-chen@users.noreply.github.com> Date: Tue, 20 Oct 2020 23:35:59 +0800 Subject: [PATCH] lua: Expose stream info downstreamLocalAddress and downstreamDirectRemoteAddress for Lua filter (#13536) Signed-off-by: nic-chen --- .../http/http_filters/lua_filter.rst | 20 ++++++++++++ docs/root/version_history/current.rst | 1 + .../extensions/filters/http/lua/wrappers.cc | 10 ++++++ source/extensions/filters/http/lua/wrappers.h | 15 +++++++++ test/extensions/filters/http/lua/BUILD | 1 + .../filters/http/lua/lua_integration_test.cc | 18 +++++++++++ .../filters/http/lua/wrappers_test.cc | 31 +++++++++++++++++++ 7 files changed, 96 insertions(+) diff --git a/docs/root/configuration/http/http_filters/lua_filter.rst b/docs/root/configuration/http/http_filters/lua_filter.rst index ebd60a7c0ded..3f067fdb7ea0 100644 --- a/docs/root/configuration/http/http_filters/lua_filter.rst +++ b/docs/root/configuration/http/http_filters/lua_filter.rst @@ -643,6 +643,26 @@ protocol() Returns the string representation of :repo:`HTTP protocol ` used by the current request. The possible values are: *HTTP/1.0*, *HTTP/1.1*, and *HTTP/2*. +downstreamLocalAddress() +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: lua + + streamInfo:downstreamLocalAddress() + +Returns the string representation of :repo:`downstream remote address ` +used by the current request. + +downstreamDirectRemoteAddress() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: lua + + streamInfo:downstreamDirectRemoteAddress() + +Returns the string representation of :repo:`downstream directly connected address ` +used by the current request. This is equivalent to the address of the physical connection. + dynamicMetadata() ^^^^^^^^^^^^^^^^^ diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 93ef61b84438..9a7d02173def 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -33,6 +33,7 @@ New Features * hds: added support for delta updates in the :ref:`HealthCheckSpecifier `, making only the Endpoints and Health Checkers that changed be reconstructed on receiving a new message, rather than the entire HDS. * health_check: added option to use :ref:`no_traffic_healthy_interval ` which allows a different no traffic interval when the host is healthy. * listener: added an optional :ref:`default filter chain `. If this field is supplied, and none of the :ref:`filter_chains ` matches, this default filter chain is used to serve the connection. +* lua: added `downstreamDirectRemoteAddress()` and `downstreamLocalAddress()` APIs to :ref:`streamInfo() `. * mongo_proxy: the list of commands to produce metrics for is now :ref:`configurable `. * ratelimit: added support for use of various :ref:`metadata ` as a ratelimit action. * ratelimit: added :ref:`disable_x_envoy_ratelimited_header ` option to disable `X-Envoy-RateLimited` header. diff --git a/source/extensions/filters/http/lua/wrappers.cc b/source/extensions/filters/http/lua/wrappers.cc index cb31e695f8be..daf9d864f246 100644 --- a/source/extensions/filters/http/lua/wrappers.cc +++ b/source/extensions/filters/http/lua/wrappers.cc @@ -129,6 +129,16 @@ int StreamInfoWrapper::luaDownstreamSslConnection(lua_State* state) { return 1; } +int StreamInfoWrapper::luaDownstreamLocalAddress(lua_State* state) { + lua_pushstring(state, stream_info_.downstreamLocalAddress()->asString().c_str()); + return 1; +} + +int StreamInfoWrapper::luaDownstreamDirectRemoteAddress(lua_State* state) { + lua_pushstring(state, stream_info_.downstreamDirectRemoteAddress()->asString().c_str()); + return 1; +} + DynamicMetadataMapIterator::DynamicMetadataMapIterator(DynamicMetadataMapWrapper& parent) : parent_{parent}, current_{parent_.streamInfo().dynamicMetadata().filter_metadata().begin()} {} diff --git a/source/extensions/filters/http/lua/wrappers.h b/source/extensions/filters/http/lua/wrappers.h index 89f7cb6d2d24..bf19843dd8d1 100644 --- a/source/extensions/filters/http/lua/wrappers.h +++ b/source/extensions/filters/http/lua/wrappers.h @@ -184,6 +184,8 @@ class StreamInfoWrapper : public Filters::Common::Lua::BaseLuaObjectvalue() .getStringView()); + EXPECT_TRUE( + absl::StrContains(upstream_request_->headers() + .get(Http::LowerCaseString("request_downstream_local_address_value"))[0] + ->value() + .getStringView(), + GetParam() == Network::Address::IpVersion::v4 ? "127.0.0.1:" : "[::1]:")); + + EXPECT_TRUE(absl::StrContains( + upstream_request_->headers() + .get(Http::LowerCaseString("request_downstream_directremote_address_value"))[0] + ->value() + .getStringView(), + GetParam() == Network::Address::IpVersion::v4 ? "127.0.0.1:" : "[::1]:")); + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"foo", "bar"}}; upstream_request_->encodeHeaders(response_headers, false); Buffer::OwnedImpl response_data1("good"); diff --git a/test/extensions/filters/http/lua/wrappers_test.cc b/test/extensions/filters/http/lua/wrappers_test.cc index 990016db3f15..8d671df5ce58 100644 --- a/test/extensions/filters/http/lua/wrappers_test.cc +++ b/test/extensions/filters/http/lua/wrappers_test.cc @@ -1,6 +1,7 @@ #include "envoy/config/core/v3/base.pb.h" #include "common/http/utility.h" +#include "common/network/address_impl.h" #include "common/stream_info/stream_info_impl.h" #include "extensions/filters/http/lua/wrappers.h" @@ -11,6 +12,7 @@ using testing::InSequence; using testing::ReturnPointee; +using testing::ReturnRef; namespace Envoy { namespace Extensions { @@ -269,6 +271,35 @@ TEST_F(LuaStreamInfoWrapperTest, ReturnCurrentProtocol) { expectToPrintCurrentProtocol(Http::Protocol::Http2); } +// Verify downstream local addresses and downstream direct remote addresses are available from +// stream info wrapper. +TEST_F(LuaStreamInfoWrapperTest, ReturnCurrentDownstreamAddresses) { + const std::string SCRIPT{R"EOF( + function callMe(object) + testPrint(object:downstreamLocalAddress()) + testPrint(object:downstreamDirectRemoteAddress()) + end + )EOF"}; + + InSequence s; + setup(SCRIPT); + + NiceMock stream_info; + auto address = Network::Address::InstanceConstSharedPtr{ + new Network::Address::Ipv4Instance("127.0.0.1", 8000)}; + auto downstream_direct_remote = + Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance("8.8.8.8", 3000)}; + ON_CALL(stream_info, downstreamLocalAddress()).WillByDefault(ReturnRef(address)); + ON_CALL(stream_info, downstreamDirectRemoteAddress()) + .WillByDefault(ReturnRef(downstream_direct_remote)); + Filters::Common::Lua::LuaDeathRef wrapper( + StreamInfoWrapper::create(coroutine_->luaState(), stream_info), true); + EXPECT_CALL(printer_, testPrint(address->asString())); + EXPECT_CALL(printer_, testPrint(downstream_direct_remote->asString())); + start("callMe"); + wrapper.reset(); +} + // Set, get and iterate stream info dynamic metadata. TEST_F(LuaStreamInfoWrapperTest, SetGetAndIterateDynamicMetadata) { const std::string SCRIPT{R"EOF(