Skip to content

Commit

Permalink
lua: add new function to get the name of the matched route
Browse files Browse the repository at this point in the history
Signed-off-by: Rohit Agrawal <[email protected]>
  • Loading branch information
agrawroh committed Jan 5, 2025
1 parent b0d58be commit 0ffcb47
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 1 deletion.
4 changes: 4 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,10 @@ new_features:
change: |
Add the option to reduce the rate limit budget based on request/response contexts on stream done.
See :ref:`apply_on_stream_done <envoy_v3_api_field_config.route.v3.RateLimit.apply_on_stream_done>` for more details.
- area: lua
change: |
Added :ref:`routeName() <config_http_filters_lua_stream_info_route_name>` API to the Stream Info Object to get the
name of the route matched by the filter chain.
deprecated:
- area: rbac
Expand Down
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 @@ -823,6 +823,26 @@ Stream info object API
Returns the string representation of :repo:`HTTP protocol <envoy/http/protocol.h>`
used by the current request. The possible values are: ``HTTP/1.0``, ``HTTP/1.1``, ``HTTP/2`` and ``HTTP/3*``.

.. _config_http_filters_lua_stream_info_route_name:

``routeName()``
^^^^^^^^^^^^^^^

.. code-block:: lua
streamInfo:routeName()
Returns the name of the route matched by the filter chain. Returns an empty string if no route was matched.

Example usage:

.. code-block:: lua
function envoy_on_request(request_handle)
local route_name = request_handle:streamInfo():routeName()
request_handle:logInfo("Matched route: " .. route_name)
end
.. _config_http_filters_lua_stream_info_downstream_direct_local_address:

``downstreamDirectLocalAddress()``
Expand Down
6 changes: 6 additions & 0 deletions source/extensions/filters/http/lua/wrappers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ int StreamInfoWrapper::luaRequestedServerName(lua_State* state) {
return 1;
}

int StreamInfoWrapper::luaRouteName(lua_State* state) {
const std::string& route_name = stream_info_.getRouteName();
lua_pushlstring(state, route_name.data(), route_name.length());
return 1;
}

DynamicMetadataMapIterator::DynamicMetadataMapIterator(DynamicMetadataMapWrapper& parent)
: parent_{parent}, current_{parent_.streamInfo().dynamicMetadata().filter_metadata().begin()} {}

Expand Down
9 changes: 8 additions & 1 deletion source/extensions/filters/http/lua/wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ class StreamInfoWrapper : public Filters::Common::Lua::BaseLuaObject<StreamInfoW
{"downstreamDirectRemoteAddress", static_luaDownstreamDirectRemoteAddress},
{"downstreamRemoteAddress", static_luaDownstreamRemoteAddress},
{"downstreamSslConnection", static_luaDownstreamSslConnection},
{"requestedServerName", static_luaRequestedServerName}};
{"requestedServerName", static_luaRequestedServerName},
{"routeName", static_luaRouteName}};
}

private:
Expand Down Expand Up @@ -328,6 +329,12 @@ class StreamInfoWrapper : public Filters::Common::Lua::BaseLuaObject<StreamInfoW
*/
DECLARE_LUA_FUNCTION(StreamInfoWrapper, luaRequestedServerName);

/**
* Get the name of the route matched by the filter chain
* @return matched route name or an empty string if no route was matched
*/
DECLARE_LUA_FUNCTION(StreamInfoWrapper, luaRouteName);

// Envoy::Lua::BaseLuaObject
void onMarkDead() override {
dynamic_metadata_wrapper_.reset();
Expand Down
44 changes: 44 additions & 0 deletions test/extensions/filters/http/lua/wrappers_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,50 @@ TEST_F(LuaStreamInfoWrapperTest, DontFinishIterationForDynamicMetadata) {
"[string \"...\"]:6: cannot create a second iterator before completing the first");
}

// Test for getting the route name
TEST_F(LuaStreamInfoWrapperTest, GetRouteName) {
const std::string SCRIPT{R"EOF(
function callMe(object)
testPrint(object:routeName())
end
)EOF"};

InSequence s;
setup(SCRIPT);

NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
std::string route_name = "test_route";
ON_CALL(stream_info, getRouteName()).WillByDefault(testing::ReturnRef(route_name));

Filters::Common::Lua::LuaDeathRef<StreamInfoWrapper> wrapper(
StreamInfoWrapper::create(coroutine_->luaState(), stream_info), true);
EXPECT_CALL(printer_, testPrint("test_route"));
start("callMe");
wrapper.reset();
}

// Test for empty route name
TEST_F(LuaStreamInfoWrapperTest, GetEmptyRouteName) {
const std::string SCRIPT{R"EOF(
function callMe(object)
testPrint(object:routeName())
end
)EOF"};

InSequence s;
setup(SCRIPT);

NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
std::string empty_route;
ON_CALL(stream_info, getRouteName()).WillByDefault(testing::ReturnRef(empty_route));

Filters::Common::Lua::LuaDeathRef<StreamInfoWrapper> wrapper(
StreamInfoWrapper::create(coroutine_->luaState(), stream_info), true);
EXPECT_CALL(printer_, testPrint(""));
start("callMe");
wrapper.reset();
}

} // namespace
} // namespace Lua
} // namespace HttpFilters
Expand Down

0 comments on commit 0ffcb47

Please sign in to comment.