add timeout

This commit is contained in:
wiaamm
2025-11-27 17:29:50 +02:00
parent 63ba61857d
commit 4d96e63529
2 changed files with 75 additions and 60 deletions

View File

@@ -182,8 +182,23 @@ function NanoHandler.body_filter(conf)
return return
end end
-- Initialize chunk counter on first call -- Initialize chunk counter and timeout tracking on first call
ctx.body_buffer_chunk = ctx.body_buffer_chunk or 0 if not ctx.body_buffer_chunk then
ctx.body_buffer_chunk = 0
ctx.body_filter_start_time = ngx.now() * 1000 -- Current time in milliseconds
ctx.body_filter_timeout = false
end
-- Check if we've exceeded 150ms timeout
local elapsed_time = (ngx.now() * 1000) - ctx.body_filter_start_time
if elapsed_time > 150 then
if not ctx.body_filter_timeout then
ctx.body_filter_timeout = true
kong.log.warn("body_filter timeout exceeded (150ms), failing open - no more chunks sent to nano-agent")
end
-- Fail-open: pass through remaining chunks without inspection
return
end
-- Get the current chunk from ngx.arg[1] (this is how Kong streams body data) -- Get the current chunk from ngx.arg[1] (this is how Kong streams body data)
local chunk = ngx.arg[1] local chunk = ngx.arg[1]
@@ -195,6 +210,12 @@ function NanoHandler.body_filter(conf)
-- Determine if we're dealing with a full body or streaming chunks -- Determine if we're dealing with a full body or streaming chunks
local is_streaming = (full_body == nil and chunk ~= nil) local is_streaming = (full_body == nil and chunk ~= nil)
-- If no body content at all (no full_body, no chunk, and no EOF), just return
-- This prevents sending empty traffic to nano-agent
if not full_body and not chunk and not eof then
return
end
if full_body and not ctx.body_seen then if full_body and not ctx.body_seen then
-- Small response body - use Kong API (original behavior) -- Small response body - use Kong API (original behavior)
ctx.body_seen = true ctx.body_seen = true
@@ -228,14 +249,11 @@ function NanoHandler.body_filter(conf)
ctx.body_buffer_chunk = ctx.body_buffer_chunk + 1 ctx.body_buffer_chunk = ctx.body_buffer_chunk + 1
end end
elseif is_streaming and chunk then elseif is_streaming and chunk and type(chunk) == "string" and #chunk > 0 then
-- Large response body - streaming chunks (file-buffered or large in-memory) -- Large response body - streaming chunks (file-buffered or large in-memory)
ctx.body_seen = true ctx.body_seen = true
-- Process chunk even if empty (empty chunks are valid in streaming responses) local chunk_size = #chunk
local chunk_size = (type(chunk) == "string") and #chunk or 0
if chunk_size > 0 then
kong.log.debug("Processing response body chunk #", ctx.body_buffer_chunk, ", size: ", chunk_size, ", eof: ", eof) kong.log.debug("Processing response body chunk #", ctx.body_buffer_chunk, ", size: ", chunk_size, ", eof: ", eof)
local ok, result = pcall(function() local ok, result = pcall(function()
@@ -272,17 +290,14 @@ function NanoHandler.body_filter(conf)
-- Fail-open: pass chunk through unmodified -- Fail-open: pass chunk through unmodified
-- ngx.arg[1] is already set to the original chunk -- ngx.arg[1] is already set to the original chunk
end end
else
-- Empty chunk - just track it, don't send to nano
kong.log.debug("Empty chunk #", ctx.body_buffer_chunk, ", eof: ", eof)
ctx.body_buffer_chunk = ctx.body_buffer_chunk + 1
end
end end
-- Finalize session on last chunk (EOF) or when no body expected -- Finalize session on last chunk (EOF) or when no body expected
if eof or (ctx.expect_body == false and not ctx.body_seen) then if eof or (ctx.expect_body == false and not ctx.body_seen) then
kong.log.debug("Finalizing response inspection, body_seen: ", ctx.body_seen, ", eof: ", eof) kong.log.debug("Finalizing response inspection, body_seen: ", ctx.body_seen, ", eof: ", eof, ", timeout: ", ctx.body_filter_timeout)
-- Only send end_inspection if we haven't timed out
if not ctx.body_filter_timeout then
local ok, result = pcall(function() local ok, result = pcall(function()
return {nano.end_inspection(session_id, session_data, nano.HttpChunkType.HTTP_RESPONSE_END)} return {nano.end_inspection(session_id, session_data, nano.HttpChunkType.HTTP_RESPONSE_END)}
end) end)
@@ -303,6 +318,9 @@ function NanoHandler.body_filter(conf)
else else
kong.log.warn("nano.end_inspection failed: ", result) kong.log.warn("nano.end_inspection failed: ", result)
end end
else
kong.log.debug("Skipping end_inspection due to timeout - failing open")
end
nano.fini_session(session_data) nano.fini_session(session_data)
nano.cleanup_all() nano.cleanup_all()

View File

@@ -363,9 +363,6 @@ static int lua_send_body(lua_State *L) {
return lua_error(L); return lua_error(L);
} }
// Send the chunk as-is without re-splitting
// Kong/Nginx already provides properly sized chunks from ngx.arg[1]
// Re-splitting causes memory issues and unnecessary overhead
HttpBody http_chunks; HttpBody http_chunks;
http_chunks.bodies_count = 1; http_chunks.bodies_count = 1;