Open yehorkovalchuk777 opened 7 months ago
I had tried this earlier but wasn't successful. Technically this should work in set_by_lua
feature. But APISIX doesn't support set_by_lua
yet. This could be by design.
You can change the status of response in the header_filter
phase. like this:
ngx.header.content_length = #your body's length
ngx.header.content_encoding = nil
ngx.status = 400
header_filter
must work with body_filter
when you want to modify both header and body.
It worked for me.
You can change the status of response in the
header_filter
phase. like this:ngx.header.content_length = #your body's length
ngx.header.content_encoding = nil
ngx.status = 400
header_filter
must work withbody_filter
when you want to modify both header and body. It worked for me.
I can change the response status only in the header_filter
phase, but I want to change the status only when the response body is invalid. The following situation arises:
In the header_filter
phase, we can change the status of the response, but we cannot read and validate the response body and set the status based on the validation.
In the body_filter
phase, we can read and validate the response body, but we cannot change the response status.
You can change the status of response in the
header_filter
phase. like this:ngx.header.content_length = #your body's length
ngx.header.content_encoding = nil
ngx.status = 400
header_filter
must work withbody_filter
when you want to modify both header and body. It worked for me.I can change the response status only in the
header_filter
phase, but I want to change the status only when the response body is invalid. The following situation arises: In theheader_filter
phase, we can change the status of the response, but we cannot read and validate the response body and set the status based on the validation. In thebody_filter
phase, we can read and validate the response body, but we cannot change the response status.
function _M.access(conf, ctx)
local body = ngx.req.get_body_data()
core.log.info("example2 access phase, get_body_data: ", body)
if string.find(body, "test") then
core.log.info("example2 access phase, set filter_flag true")
ctx.filter_flag = true
else
ctx.filter_flag = false
end
end
function _M.header_filter(conf, ctx)
core.log.info("example2 header_filter phase, ctx filter_flag: ", ctx.filter_flag)
if ctx.filter_flag then
ngx.status = 401
end
end
Part of the log after I run it is here:
2024/02/06 22:08:06 [info] 75#75: 610 [lua] example-plugin2.lua:63: phase_func(): example2 access phase, get_body_data: {"test":"test"} 2024/02/06 22:08:06 [info] 75#75: 610 [lua] example-plugin2.lua:65: phase_func(): example2 access phase, set filter_flag true 2024/02/06 22:08:06 [info] 75#75: *610 [lua] example-plugin2.lua:73: phase_func(): example2 header_filter phase, ctx filter_flag: true while reading response header from upstream
curl log:
curl -sL -w "http_code:%{http_code} content_type:%{content_type}" -o /dev/null --request POST 'http://xxxxxxx' -d '{"test":"test"}' http_code:401 content_type:application/json; charset=utf-8%
In the access phase, the body is read and the flag is set. In the header_filter phase, the response status can be set according to the flag. Does this work for you?
function _M.access(conf, ctx) local body = ngx.req.get_body_data()
Here you are fetching the request body in the access phase which is related to the request (not the response). I am trying to return a 500 status if the response body is invalid
function _M.access(conf, ctx) local body = ngx.req.get_body_data()
Here you are fetching the request body in the access phase which is related to the request (not the response). I am trying to return a 500 status if the response body is invalid
yes, you are right. Please ignore this reply.
https://apisix.apache.org/docs/apisix/plugins/response-rewrite/ Does it works ?
I checked the response-rewrite
for a different use case where I would like to conditionally change the response body based on the actual response body from the upstream service. Correct me if I am wrong but I don't think this is possible.
That said, is there any other outstanding question in this thread?
Description
I need to validate whether a request or response is valid JSON or XML. I'm trying to solve this with a custom plugin.
In the case of the request, everything is fine, I enter the rewrite phase and check the request body, if it is not valid, I set response status to 400
However, in the case of a response, we can only read the response body in the body_filter phase, but in this phase we cannot change the response status. In this phase we can only change the response body
How can I change the response status in Apisix (using a custom plugin, or another method) depending on the response body?
Environment