Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions docs/root/configuration/http/http_filters/lua_filter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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("<html><b>Not Found<b></html>")
response_handle:headers():replace("content-length", content_length)
response_handle:body():setBytes("<html><b>Not Found<b></html>")
response_handle:headers():replace("content-type", "text/html")
end

Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions source/extensions/filters/common/lua/wrappers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 3 additions & 1 deletion source/extensions/filters/common/lua/wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ namespace Lua {
*/
class BufferWrapper : public BaseLuaObject<BufferWrapper> {
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},
Expand Down Expand Up @@ -46,6 +47,7 @@ class BufferWrapper : public BaseLuaObject<BufferWrapper> {
DECLARE_LUA_FUNCTION(BufferWrapper, luaSetBytes);

Buffer::Instance& data_;
Http::RequestOrResponseHeaderMap& headers_;
};

class MetadataMapWrapper;
Expand Down
23 changes: 12 additions & 11 deletions source/extensions/filters/http/lua/lua_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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<Filters::Common::Lua::BufferWrapper> 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_) {
Expand Down Expand Up @@ -458,9 +459,10 @@ int StreamHandleWrapper::luaBody(lua_State* state) {
callbacks_.addData(body);
}

body_wrapper_.reset(Filters::Common::Lua::BufferWrapper::create(
state, const_cast<Buffer::Instance&>(*callbacks_.bufferedBody())),
true);
body_wrapper_.reset(
Filters::Common::Lua::BufferWrapper::create(
state, headers_, const_cast<Buffer::Instance&>(*callbacks_.bufferedBody())),
true);
}
return 1;
}
Expand Down Expand Up @@ -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;
}
Expand Down
12 changes: 6 additions & 6 deletions source/extensions/filters/http/lua/lua_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ class StreamHandleWrapper : public Filters::Common::Lua::BaseLuaObject<StreamHan
Responded
};

StreamHandleWrapper(Filters::Common::Lua::Coroutine& coroutine, Http::HeaderMap& headers,
bool end_stream, Filter& filter, FilterCallbacks& callbacks,
TimeSource& time_source);
StreamHandleWrapper(Filters::Common::Lua::Coroutine& coroutine,
Http::RequestOrResponseHeaderMap& headers, bool end_stream, Filter& filter,
FilterCallbacks& callbacks, TimeSource& time_source);

Http::FilterHeadersStatus start(int function_ref);
Http::FilterDataStatus onData(Buffer::Instance& data, bool end_stream);
Expand Down Expand Up @@ -309,7 +309,7 @@ class StreamHandleWrapper : public Filters::Common::Lua::BaseLuaObject<StreamHan
void onBeforeFinalizeUpstreamSpan(Tracing::Span&, const Http::ResponseHeaderMap*) override {}

Filters::Common::Lua::Coroutine& coroutine_;
Http::HeaderMap& headers_;
Http::RequestOrResponseHeaderMap& headers_;
bool end_stream_;
bool headers_continued_{};
bool buffered_body_{};
Expand Down Expand Up @@ -538,8 +538,8 @@ class Filter : public Http::StreamFilter, Logger::Loggable<Logger::Id::lua> {
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);

Expand Down
6 changes: 4 additions & 2 deletions test/extensions/filters/common/lua/wrappers_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ TEST_F(LuaBufferWrapperTest, Methods) {

setup(SCRIPT);
Buffer::OwnedImpl data("hello world");
BufferWrapper::create(coroutine_->luaState(), data);
Http::TestRequestHeaderMapImpl headers;
BufferWrapper::create(coroutine_->luaState(), headers, data);
EXPECT_CALL(printer_, testPrint("11"));
EXPECT_CALL(printer_, testPrint("he"));
EXPECT_CALL(printer_, testPrint("world"));
Expand All @@ -101,7 +102,8 @@ TEST_F(LuaBufferWrapperTest, GetBytesInvalidParams) {

setup(SCRIPT);
Buffer::OwnedImpl data("hello world");
BufferWrapper::create(coroutine_->luaState(), data);
Http::TestRequestHeaderMapImpl 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");
Expand Down
16 changes: 16 additions & 0 deletions test/extensions/filters/http/lua/lua_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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