From e435d5aad1f2386709ed6f9579115572b4acd126 Mon Sep 17 00:00:00 2001 From: wangkai19 Date: Fri, 12 Nov 2021 19:50:54 +0800 Subject: [PATCH 1/5] lua: support body setBytes with header content length set automatically Signed-off-by: wangkai19 --- .../extensions/filters/common/lua/wrappers.cc | 1 + .../extensions/filters/common/lua/wrappers.h | 4 +++- .../extensions/filters/http/lua/lua_filter.cc | 23 ++++++++++--------- .../extensions/filters/http/lua/lua_filter.h | 12 +++++----- .../filters/http/lua/lua_integration_test.cc | 16 +++++++++++++ 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/source/extensions/filters/common/lua/wrappers.cc b/source/extensions/filters/common/lua/wrappers.cc index bfb2a1c473259..9963a446cb773 100644 --- a/source/extensions/filters/common/lua/wrappers.cc +++ b/source/extensions/filters/common/lua/wrappers.cc @@ -68,6 +68,7 @@ int BufferWrapper::luaSetBytes(lua_State* state) { data_.drain(data_.length()); absl::string_view bytes = getStringViewFromLuaString(state, 2); data_.add(bytes); + headers_.setContentLength(data_.length()); lua_pushnumber(state, data_.length()); return 1; } diff --git a/source/extensions/filters/common/lua/wrappers.h b/source/extensions/filters/common/lua/wrappers.h index 344467d39ff2c..391120bd3f45f 100644 --- a/source/extensions/filters/common/lua/wrappers.h +++ b/source/extensions/filters/common/lua/wrappers.h @@ -16,7 +16,8 @@ namespace Lua { */ class BufferWrapper : public BaseLuaObject { public: - BufferWrapper(Buffer::Instance& data) : data_(data) {} + BufferWrapper(Http::RequestOrResponseHeaderMap& headers, Buffer::Instance& data) + : data_(data), headers_(headers) {} static ExportedFunctions exportedFunctions() { return {{"length", static_luaLength}, @@ -46,6 +47,7 @@ class BufferWrapper : public BaseLuaObject { DECLARE_LUA_FUNCTION(BufferWrapper, luaSetBytes); Buffer::Instance& data_; + Http::RequestOrResponseHeaderMap& headers_; }; class MetadataMapWrapper; diff --git a/source/extensions/filters/http/lua/lua_filter.cc b/source/extensions/filters/http/lua/lua_filter.cc index 9be9dd3d49b4a..7442154d0aad9 100644 --- a/source/extensions/filters/http/lua/lua_filter.cc +++ b/source/extensions/filters/http/lua/lua_filter.cc @@ -191,8 +191,9 @@ PerLuaCodeSetup::PerLuaCodeSetup(const std::string& lua_code, ThreadLocal::SlotA } StreamHandleWrapper::StreamHandleWrapper(Filters::Common::Lua::Coroutine& coroutine, - Http::HeaderMap& headers, bool end_stream, Filter& filter, - FilterCallbacks& callbacks, TimeSource& time_source) + Http::RequestOrResponseHeaderMap& headers, bool end_stream, + Filter& filter, FilterCallbacks& callbacks, + TimeSource& time_source) : coroutine_(coroutine), headers_(headers), end_stream_(end_stream), filter_(filter), callbacks_(callbacks), yield_callback_([this]() { if (state_ == State::Running) { @@ -224,7 +225,7 @@ Http::FilterDataStatus StreamHandleWrapper::onData(Buffer::Instance& data, bool if (state_ == State::WaitForBodyChunk) { ENVOY_LOG(trace, "resuming for next body chunk"); Filters::Common::Lua::LuaDeathRef wrapper( - Filters::Common::Lua::BufferWrapper::create(coroutine_.luaState(), data), true); + Filters::Common::Lua::BufferWrapper::create(coroutine_.luaState(), headers_, data), true); state_ = State::Running; coroutine_.resume(1, yield_callback_); } else if (state_ == State::WaitForBody && end_stream_) { @@ -458,9 +459,10 @@ int StreamHandleWrapper::luaBody(lua_State* state) { callbacks_.addData(body); } - body_wrapper_.reset(Filters::Common::Lua::BufferWrapper::create( - state, const_cast(*callbacks_.bufferedBody())), - true); + body_wrapper_.reset( + Filters::Common::Lua::BufferWrapper::create( + state, headers_, const_cast(*callbacks_.bufferedBody())), + true); } return 1; } @@ -720,11 +722,10 @@ void Filter::onDestroy() { } } -Http::FilterHeadersStatus Filter::doHeaders(StreamHandleRef& handle, - Filters::Common::Lua::CoroutinePtr& coroutine, - FilterCallbacks& callbacks, int function_ref, - PerLuaCodeSetup* setup, Http::HeaderMap& headers, - bool end_stream) { +Http::FilterHeadersStatus +Filter::doHeaders(StreamHandleRef& handle, Filters::Common::Lua::CoroutinePtr& coroutine, + FilterCallbacks& callbacks, int function_ref, PerLuaCodeSetup* setup, + Http::RequestOrResponseHeaderMap& headers, bool end_stream) { if (function_ref == LUA_REFNIL) { return Http::FilterHeadersStatus::Continue; } diff --git a/source/extensions/filters/http/lua/lua_filter.h b/source/extensions/filters/http/lua/lua_filter.h index a558177bd4418..c67e4f74560e3 100644 --- a/source/extensions/filters/http/lua/lua_filter.h +++ b/source/extensions/filters/http/lua/lua_filter.h @@ -133,9 +133,9 @@ class StreamHandleWrapper : public Filters::Common::Lua::BaseLuaObject { Http::FilterHeadersStatus doHeaders(StreamHandleRef& handle, Filters::Common::Lua::CoroutinePtr& coroutine, FilterCallbacks& callbacks, int function_ref, - PerLuaCodeSetup* setup, Http::HeaderMap& headers, - bool end_stream); + PerLuaCodeSetup* setup, + Http::RequestOrResponseHeaderMap& headers, bool end_stream); Http::FilterDataStatus doData(StreamHandleRef& handle, Buffer::Instance& data, bool end_stream); Http::FilterTrailersStatus doTrailers(StreamHandleRef& handle, Http::HeaderMap& trailers); diff --git a/test/extensions/filters/http/lua/lua_integration_test.cc b/test/extensions/filters/http/lua/lua_integration_test.cc index 14734bb5389fd..cc41bb5f353bc 100644 --- a/test/extensions/filters/http/lua/lua_integration_test.cc +++ b/test/extensions/filters/http/lua/lua_integration_test.cc @@ -1163,5 +1163,21 @@ name: lua testRewriteResponse(FILTER_AND_CODE); } +TEST_P(LuaIntegrationTest, RewriteResponseBufferWithoutHeaderReplaceContentLength) { + const std::string FILTER_AND_CODE = + R"EOF( +name: lua +typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + inline_code: | + function envoy_on_response(response_handle) + local content_length = response_handle:body():setBytes("ok") + response_handle:logTrace(content_length) + end +)EOF"; + + testRewriteResponse(FILTER_AND_CODE); +} + } // namespace } // namespace Envoy From 1e9dabb6acf5e09f9a90e997fae7d4df96c33ea6 Mon Sep 17 00:00:00 2001 From: wangkai19 Date: Fri, 12 Nov 2021 21:30:43 +0800 Subject: [PATCH 2/5] fix wrappers test Signed-off-by: wangkai19 --- test/extensions/filters/common/lua/wrappers_test.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/extensions/filters/common/lua/wrappers_test.cc b/test/extensions/filters/common/lua/wrappers_test.cc index 565843d7e14c0..4ec27fc887a99 100644 --- a/test/extensions/filters/common/lua/wrappers_test.cc +++ b/test/extensions/filters/common/lua/wrappers_test.cc @@ -82,7 +82,8 @@ TEST_F(LuaBufferWrapperTest, Methods) { setup(SCRIPT); Buffer::OwnedImpl data("hello world"); - BufferWrapper::create(coroutine_->luaState(), data); + Http::RequestOrResponseHeaderMap headers; + BufferWrapper::create(coroutine_->luaState(), heders, data); EXPECT_CALL(printer_, testPrint("11")); EXPECT_CALL(printer_, testPrint("he")); EXPECT_CALL(printer_, testPrint("world")); @@ -101,7 +102,8 @@ TEST_F(LuaBufferWrapperTest, GetBytesInvalidParams) { setup(SCRIPT); Buffer::OwnedImpl data("hello world"); - BufferWrapper::create(coroutine_->luaState(), data); + Http::RequestOrResponseHeaderMap headers; + BufferWrapper::create(coroutine_->luaState(), headers, data); EXPECT_THROW_WITH_MESSAGE( start("callMe"), LuaException, "[string \"...\"]:3: index/length must be >= 0 and (index + length) must be <= buffer size"); From 7e2e1d0c5cd6fe453a2baa91adb97420ae86a84b Mon Sep 17 00:00:00 2001 From: wangkai19 Date: Fri, 12 Nov 2021 22:43:28 +0800 Subject: [PATCH 3/5] fix wrapper ut Signed-off-by: wangkai19 --- test/extensions/filters/common/lua/wrappers_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/extensions/filters/common/lua/wrappers_test.cc b/test/extensions/filters/common/lua/wrappers_test.cc index 4ec27fc887a99..92437bb6142e1 100644 --- a/test/extensions/filters/common/lua/wrappers_test.cc +++ b/test/extensions/filters/common/lua/wrappers_test.cc @@ -83,7 +83,7 @@ TEST_F(LuaBufferWrapperTest, Methods) { setup(SCRIPT); Buffer::OwnedImpl data("hello world"); Http::RequestOrResponseHeaderMap headers; - BufferWrapper::create(coroutine_->luaState(), heders, data); + BufferWrapper::create(coroutine_->luaState(), headers, data); EXPECT_CALL(printer_, testPrint("11")); EXPECT_CALL(printer_, testPrint("he")); EXPECT_CALL(printer_, testPrint("world")); From cdf22ad538baf62d43cdbd576ebe595d76554d8a Mon Sep 17 00:00:00 2001 From: wangkai19 Date: Sat, 13 Nov 2021 00:05:20 +0800 Subject: [PATCH 4/5] fix wrappers test Signed-off-by: wangkai19 --- test/extensions/filters/common/lua/wrappers_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/extensions/filters/common/lua/wrappers_test.cc b/test/extensions/filters/common/lua/wrappers_test.cc index 92437bb6142e1..dc7f9e5ff2312 100644 --- a/test/extensions/filters/common/lua/wrappers_test.cc +++ b/test/extensions/filters/common/lua/wrappers_test.cc @@ -82,7 +82,7 @@ TEST_F(LuaBufferWrapperTest, Methods) { setup(SCRIPT); Buffer::OwnedImpl data("hello world"); - Http::RequestOrResponseHeaderMap headers; + Http::TestRequestHeaderMapImpl headers; BufferWrapper::create(coroutine_->luaState(), headers, data); EXPECT_CALL(printer_, testPrint("11")); EXPECT_CALL(printer_, testPrint("he")); @@ -102,7 +102,7 @@ TEST_F(LuaBufferWrapperTest, GetBytesInvalidParams) { setup(SCRIPT); Buffer::OwnedImpl data("hello world"); - Http::RequestOrResponseHeaderMap headers; + Http::TestRequestHeaderMapImpl headers; BufferWrapper::create(coroutine_->luaState(), headers, data); EXPECT_THROW_WITH_MESSAGE( start("callMe"), LuaException, From 6e1af0aaadabbd5f365a52de15c304f2de4323a3 Mon Sep 17 00:00:00 2001 From: wangkai19 Date: Tue, 23 Nov 2021 09:55:05 +0800 Subject: [PATCH 5/5] modify lua filter setBytes doc Signed-off-by: wangkai19 --- docs/root/configuration/http/http_filters/lua_filter.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/root/configuration/http/http_filters/lua_filter.rst b/docs/root/configuration/http/http_filters/lua_filter.rst index 78777d4e9c7b6..cb232dfe9bdf5 100644 --- a/docs/root/configuration/http/http_filters/lua_filter.rst +++ b/docs/root/configuration/http/http_filters/lua_filter.rst @@ -248,8 +248,7 @@ There are two ways of doing this, the first one is via the ``body()`` API. .. code-block:: lua function envoy_on_response(response_handle) - local content_length = response_handle:body():setBytes("Not Found") - response_handle:headers():replace("content-length", content_length) + response_handle:body():setBytes("Not Found") response_handle:headers():replace("content-type", "text/html") end @@ -260,8 +259,7 @@ Or, through ``bodyChunks()`` API, which let Envoy to skip buffering the upstream function envoy_on_response(response_handle) - -- Sets the content-length. - response_handle:headers():replace("content-length", 28) + -- Sets the content-type. response_handle:headers():replace("content-type", "text/html") local last