-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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: Body transformer plugin #8766
Conversation
apisix/plugins/body-transformer.lua
Outdated
|
||
|
||
-- luacheck: ignore | ||
function string.escape_xml(s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we register these methods before we use them and deregister once the job is done? So we can avoid affecting other modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
luacheck has no inline option to depress "setting undefine field of global" warning. But depress the whole lua file is not proper. And escape_*
has no conflict so far, so I think it's ok to use these names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The solution is not about making luacheck happy, but limiting the scope of the injection. If we don't deregister the methods, it will affect other modules including those not written by us.
Anyway, it is not a good idea to allow the monkey patch of the std lib outside our scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I know. But setting methods on demand on the global object will make luacheck warns: setting undefined field escape_xml of global string
, which could not be depressed via inline comment, so ignore the whole file in .luacheckrc
instead?
function _M.body_filter(conf, ctx) | ||
if conf.response then | ||
local body = core.response.hold_body_chunk(ctx) | ||
if ngx.arg[2] == false and not body then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ngx.arg[2] == false and not body then | |
if not body then |
hold_body_chunk returns a body only when ngx.arg[2] is true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this plugiin needs to handle body=nil
case.
apisix/plugins/body-transformer.lua
Outdated
if type(k) == "string" then | ||
k = k:match(".*:(.*)") | ||
if k then | ||
tbl[k] = v |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems this code just inserts a new k
end | ||
|
||
|
||
function _M.rewrite(conf, ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rewrite
is only for plugins that require running before other plugins. For example, plugins to select consumers, plugins for tracing, plugins to set real IP, and so on. Most of the other plugin use access
phase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This plugin needs to use original content-type header before proxy-rewrite plugin overrrdes it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this plugin is just doing rewrite job, just like proxy-rewrite plugin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We used to have a discussion to unify the "rewrite/access" methods in 2020.
Since this is not the only plugin that has inconsistent "rewrite/access" methods, and you insist on it, I am OK to accept it.
|
||
|
||
local function set_input_format(conf, typ, ct) | ||
if conf[typ].input_format == nil and ct then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conf is shared between reqs. Is there a race if the previous request set the input format different from the current one?
t/plugin/body-transformer.t
Outdated
local httpc = http.new() | ||
local res, err = httpc:request_uri(uri, opt) | ||
if not res then | ||
ngx.say(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should check --- response_body
to ensure no err happens. Please update other similar places.
t/plugin/body-transformer.t
Outdated
} | ||
} | ||
--- error_log | ||
attempt to call global 'name' (a string value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add log prefix to ensure it comes from an expected log
t/plugin/body-transformer.t
Outdated
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar?name=hello" | ||
local opt = {method = "GET"} | ||
local httpc = http.new() | ||
httpc:request_uri(uri, opt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to check the res here?
| ----------- | ----------- | ----------- | ----------- | | ||
| `request` | object | False | request body transformation configuration | | ||
| `request.input_format` | string | False | request body original format, if not specified, it would be determined from `Content-Type` header. | | ||
| `request.template` | string | False | request body transformation template | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The template is required
| `request.template` | string | False | request body transformation template | | ||
| `response` | object | False | response body transformation configuration | | ||
| `response.input_format` | string | False | response body original format | | ||
| `response.template` | string | False | response body transformation template, if not specified, it would be determined from `Content-Type` header. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean determining the input_format from Content-Type
header?
|
||
function _M.body_filter(_, ctx) | ||
local conf = ctx.body_transformer_conf | ||
if conf.response then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems if neither conf.request nor conf.response are given, the conf will be nil here.
We should check if one of them is configured at least in check_schema.
* upstream/master: docs: change the file name to 'create-ssl.py'.If 'ssl.py' is used as … (apache#8623) feat: Body transformer plugin (apache#8766) fix: mocking plugin panic when response_example contain $ (apache#8810) (apache#8816) feat: file logger plugin support response body in variable (apache#8711) docs(getting-started): rewrite the install section (apache#8807) feat: allow each logger to define custom log format in its conf (apache#8806) fix(etcd): reloaded data may be in res.body.node (apache#8736) fix: fix fetch all service info from consul (apache#8651) docs: fix global-rule.md wrong curl address (apache#8793) feat: stream subsystem support consul service discovery (apache#8696) chore(kafka-logger): support configuration `meta_refresh_interval` parameter (apache#8762) feat: ready to release 2.15.2 (apache#8783)
Description
This plugin is used to transform the request or response body from one
format to another format, e.g. JSON to XML.
It depends on xml2lua and lua-resty-template.
Use cases:
Checklist