Kong Gateway v3.6.0自定义插件:5xx重定向至自定义URL时日志报错
Kong Gateway v3.6.0 500转307重定向避免日志报错方案
核心问题是access阶段调用kong.response.exit(500)后,Kong内部仍会保留原状态码的设置逻辑,而header_filter阶段已将状态改为307并发送响应头,导致Nginx触发状态码重复设置的报错。以下是两种可行的解决思路:
方案一:覆盖Nginx内部状态变量,阻止后续冲突设置
直接修改ngx.var.status来覆盖Nginx记录的原状态值,从根源上避免后续的状态码设置尝试:
-- header_filter阶段代码 local status = kong.response.get_status() if status == ngx.HTTP_INTERNAL_SERVER_ERROR then -- 设置重定向状态和Location头 kong.response.set_status(ngx.HTTP_TEMPORARY_REDIRECT) kong.response.set_header("Location", location_url) -- 关键:覆盖Nginx内部状态变量,阻止后续设置原500状态 ngx.var.status = tostring(ngx.HTTP_TEMPORARY_REDIRECT) -- 清除原响应的Content-Length,避免响应体长度不匹配 kong.response.clear_header("Content-Length") kong.response.set_header("Content-Length", "0") end
方案二:通过共享上下文标记,跳过access阶段的exit调用
如果你的插件同时控制access阶段的错误触发和header_filter的重定向逻辑,可以用共享上下文标记替代kong.response.exit,避免触发Kong内部的状态码残留逻辑:
-- access阶段代码 -- 假设这里是触发错误的判断条件 if some_error_condition then -- 用共享上下文标记需要重定向,不调用exit kong.ctx.shared.need_redirect = true return end -- header_filter阶段代码 local status = kong.response.get_status() if status == ngx.HTTP_INTERNAL_SERVER_ERROR or kong.ctx.shared.need_redirect then kong.response.set_status(ngx.HTTP_TEMPORARY_REDIRECT) kong.response.set_header("Location", location_url) ngx.var.status = tostring(ngx.HTTP_TEMPORARY_REDIRECT) kong.response.clear_header("Content-Length") end
报错原因说明
当你在access阶段调用kong.response.exit(500)时,Kong会在内部Nginx流程中记录该状态码,后续会尝试发送这个状态。但header_filter阶段已提前将状态改为307并发送了响应头,此时Nginx再尝试设置500状态就会触发"attempt to set status via ngx.exit after sending out the response status"错误。修改ngx.var.status可以直接覆盖Nginx内部的状态记录,彻底避免冲突。
内容的提问来源于stack exchange,提问作者Heidtmare
相关产品推荐
相关产品推荐

