Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lua: Expose stream info downstreamLocalAddress and downstreamDirectRemoteAddress for Lua filter #13536

Merged
merged 14 commits into from
Oct 20, 2020
Merged
20 changes: 20 additions & 0 deletions docs/root/configuration/http/http_filters/lua_filter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,26 @@ protocol()
Returns the string representation of :repo:`HTTP protocol <include/envoy/http/protocol.h>`
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 <include/envoy/stream_info/stream_info.h>`
used by the current request.

downstreamDirectRemoteAddress()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: lua

streamInfo:downstreamDirectRemoteAddress()

Returns the string representation of :repo:`downstream directly connected address <include/envoy/stream_info/stream_info.h>`
used by the current request. This is equivalent to the address of the physical connection.

dynamicMetadata()
^^^^^^^^^^^^^^^^^

Expand Down
2 changes: 2 additions & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ New Features
* grpc: implemented header value syntax support when defining :ref:`initial metadata <envoy_v3_api_field_config.core.v3.GrpcService.initial_metadata>` for gRPC-based `ext_authz` :ref:`HTTP <envoy_v3_api_field_extensions.filters.http.ext_authz.v3.ExtAuthz.grpc_service>` and :ref:`network <envoy_v3_api_field_extensions.filters.network.ext_authz.v3.ExtAuthz.grpc_service>` filters, and :ref:`ratelimit <envoy_v3_api_field_config.ratelimit.v3.RateLimitServiceConfig.grpc_service>` filters.
* hds: added support for delta updates in the :ref:`HealthCheckSpecifier <envoy_v3_api_msg_service.health.v3.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 <envoy_v3_api_field_config.core.v3.HealthCheck.no_traffic_healthy_interval>` which allows a different no traffic interval when the host is healthy.
* lua: added :ref:`streamInfo():downstreamLocalAddress() <config_http_filters_lua_stream_info_wrapper>` API.
* lua: added :ref:`streamInfo():downstreamDirectRemoteAddress() <config_http_filters_lua_stream_info_wrapper>` API.
nic-chen marked this conversation as resolved.
Show resolved Hide resolved
* mongo_proxy: the list of commands to produce metrics for is now :ref:`configurable <envoy_v3_api_field_extensions.filters.network.mongo_proxy.v3.MongoProxy.commands>`.
* ratelimit: added :ref:`disable_x_envoy_ratelimited_header <envoy_v3_api_msg_extensions.filters.http.ratelimit.v3.RateLimit>` option to disable `X-Envoy-RateLimited` header.
* tcp: added a new :ref:`envoy.overload_actions.reject_incoming_connections <config_overload_manager_overload_actions>` action to reject incoming TCP connections.
Expand Down
10 changes: 10 additions & 0 deletions source/extensions/filters/http/lua/wrappers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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()} {}

Expand Down
15 changes: 15 additions & 0 deletions source/extensions/filters/http/lua/wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ class StreamInfoWrapper : public Filters::Common::Lua::BaseLuaObject<StreamInfoW
static ExportedFunctions exportedFunctions() {
return {{"protocol", static_luaProtocol},
{"dynamicMetadata", static_luaDynamicMetadata},
{"downstreamLocalAddress", static_luaDownstreamLocalAddress},
{"downstreamDirectRemoteAddress", static_luaDownstreamDirectRemoteAddress},
{"downstreamSslConnection", static_luaDownstreamSslConnection}};
}

Expand All @@ -206,6 +208,19 @@ class StreamInfoWrapper : public Filters::Common::Lua::BaseLuaObject<StreamInfoW
*/
DECLARE_LUA_FUNCTION(StreamInfoWrapper, luaDownstreamSslConnection);

/**
* Get current downstream local address
* @return string representation of downstream local address.
*/
DECLARE_LUA_FUNCTION(StreamInfoWrapper, luaDownstreamLocalAddress);

/**
* Get current downstream local address
* @return string representation of downstream directly connected address.
* This is equivalent to the address of the physical connection.
*/
DECLARE_LUA_FUNCTION(StreamInfoWrapper, luaDownstreamDirectRemoteAddress);

// Envoy::Lua::BaseLuaObject
void onMarkDead() override { dynamic_metadata_wrapper_.reset(); }

Expand Down
1 change: 1 addition & 0 deletions test/extensions/filters/http/lua/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ envoy_extension_cc_test(
srcs = ["wrappers_test.cc"],
extension_name = "envoy.filters.http.lua",
deps = [
"//source/common/network:address_lib",
"//source/common/stream_info:stream_info_lib",
"//source/extensions/filters/http/lua:wrappers_lib",
"//test/extensions/filters/common/lua:lua_wrappers_lib",
Expand Down
18 changes: 18 additions & 0 deletions test/extensions/filters/http/lua/lua_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ name: lua
end
request_handle:headers():add("request_protocol", request_handle:streamInfo():protocol())
request_handle:headers():add("request_dynamic_metadata_value", dynamic_metadata_value)
request_handle:headers():add("request_downstream_local_address_value",
request_handle:streamInfo():downstreamLocalAddress())
request_handle:headers():add("request_downstream_directremote_address_value",
request_handle:streamInfo():downstreamDirectRemoteAddress())
end

function envoy_on_response(response_handle)
Expand Down Expand Up @@ -325,6 +329,20 @@ name: lua
->value()
.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");
Expand Down
31 changes: 31 additions & 0 deletions test/extensions/filters/http/lua/wrappers_test.cc
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -11,6 +12,7 @@

using testing::InSequence;
using testing::ReturnPointee;
using testing::ReturnRef;

namespace Envoy {
namespace Extensions {
Expand Down Expand Up @@ -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<Envoy::StreamInfo::MockStreamInfo> 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<StreamInfoWrapper> 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(
Expand Down