Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add delayed_body_filter phase #6605

Merged
merged 1 commit into from
Mar 15, 2022
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
1 change: 1 addition & 0 deletions apisix/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ end

function _M.http_body_filter_phase()
common_phase("body_filter")
common_phase("delayed_body_filter")
end


Expand Down
1 change: 1 addition & 0 deletions apisix/plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,7 @@ function _M.run_plugin(phase, plugins, api_ctx)
if phase ~= "log"
and phase ~= "header_filter"
and phase ~= "body_filter"
and phase ~= "delayed_body_filter"
then
for i = 1, #plugins, 2 do
if phase == "rewrite_in_consumer" and plugins[i + 1]._from_consumer
Expand Down
12 changes: 12 additions & 0 deletions apisix/plugins/example-plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ function _M.access(conf, ctx)
end


function _M.body_filter(conf, ctx)
core.log.warn("plugin body_filter phase, eof: ", ngx.arg[2],
", conf: ", core.json.encode(conf))
end


function _M.delayed_body_filter(conf, ctx)
core.log.warn("plugin delayed_body_filter phase, eof: ", ngx.arg[2],
", conf: ", core.json.encode(conf))
end


local function hello()
local args = ngx.req.get_uri_args()
if args["json"] then
Expand Down
15 changes: 14 additions & 1 deletion docs/en/latest/plugin-develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,26 @@ In APISIX, only the authentication logic can be run in the rewrite phase. Other
The following code snippet shows how to implement any logic relevant to the plugin in the OpenResty log phase.

```lua
function _M.log(conf)
function _M.log(conf, ctx)
-- Implement logic here
end
```

**Note : we can't invoke `ngx.exit` or `core.respond.exit` in rewrite phase and access phase. if need to exit, just return the status and body, the plugin engine will make the exit happen with the returned status and body. [example](https://github.com/apache/apisix/blob/35269581e21473e1a27b11cceca6f773cad0192a/apisix/plugins/limit-count.lua#L177)**

### extra phase

Besides OpenResty's phases, we also provide extra phases to satisfy specific purpose:

* `delayed_body_filter`

```lua
function _M.delayed_body_filter(conf, ctx)
-- delayed_body_filter is called after body_filter
-- it is used by the tracing plugins to end the span right after body_filter
end
```

## implement the logic

Write the logic of the plugin in the corresponding phase. There are two parameters `conf` and `ctx` in the phase method, take the `limit-conn` plugin configuration as an example.
Expand Down
13 changes: 13 additions & 0 deletions docs/zh/latest/plugin-develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,19 @@ end

**注意:我们不能在 rewrite 和 access 阶段调用 `ngx.exit` 或者 `core.respond.exit`。如果确实需要退出,只需要 return 状态码和正文,插件引擎将使用返回的状态码和正文进行退出。[例子](https://github.com/apache/apisix/blob/35269581e21473e1a27b11cceca6f773cad0192a/apisix/plugins/limit-count.lua#L177)**

### APISIX 的自定义阶段

除了 OpenResty 的阶段,我们还提供额外的阶段来满足特定的目的:

* `delayed_body_filter`

```lua
function _M.delayed_body_filter(conf, ctx)
-- delayed_body_filter 在 body_filter 之后被调用。
-- 它被 tracing 类型插件用来在 body_filter 之后立即结束 span。
end
```

## 编写执行逻辑

在对应的阶段方法里编写功能的逻辑代码,在阶段方法中具有 `conf` 和 `ctx` 两个参数,以 `limit-conn` 插件配置为例。
Expand Down
49 changes: 49 additions & 0 deletions t/plugin/example.t
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,52 @@ GET /t
done
--- no_error_log
[error]



=== TEST 12: body filter
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"example-plugin": {
"i": 11,
"ip": "127.0.0.1",
"port": 1981
}
},
"uri": "/server_port"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]



=== TEST 13: hit route
--- request
GET /server_port
--- grep_error_log eval
qr/plugin (body_filter|delayed_body_filter) phase, eof: (false|true)/
--- grep_error_log_out
plugin body_filter phase, eof: false
plugin delayed_body_filter phase, eof: false
plugin body_filter phase, eof: true
plugin delayed_body_filter phase, eof: true
--- no_error_log
[error]