kwanhur commented on issue #5451:
URL: https://github.com/apache/apisix/issues/5451#issuecomment-1077539864


   After have a look at existed codes, update solution v3 and example:
   
   **Solution**
   
   Properties table adds one `filters`
   
   | name    | description                              | type  | default    |
   | ------- | ---------------------------------------- | ----- | ---------- |
   | filters | filter expressions, include key attributes how to filter | array 
| `[]` empty |
   
   filter key attributes
   
   | name    | description                              | type   | default   |
   | ------- | ---------------------------------------- | ------ | --------- |
   | ~~expr~~    | ~~match expression, adapters to 
[lua-resty-expr](https://github.com/api7/lua-resty-expr) , only on header~~ 
reuse `vars` | ~~map~~    | ~~{}~~        |
   | ~~kind~~    | ~~regex or subfilter mode~~                 | ~~string~~ | 
~~subfilter~~ |
   | scope   | regex substitute once or global          | string | "once"    |
   | ~~pattern~~regex | match pattern on response body, regex or fixed string 
both ok | string | ""        |
   | replace | regex substitution content               | string | ""        |
   | options | regex options, detail see 
[here](https://github.com/openresty/lua-nginx-module#ngxrematch) | string | ""  
      |
   
   Main steps:
   
   step 1: at `header_filter` phase, reuse `vars` to match the response headers.
   
   step 2: at `body_filter` phase if `ctx.response_rewrite_matched` false then 
return, otherwise
   * if `conf.filters` empty, backward to original body-replaced logic(backward 
compatibly).
   * if `conf.filters` not empty, buffer response body with 
`core.response.hold_body_chunk(ctx)`, then foreach `filters` to filter, 
pseudo-code:
      ```lua
      local body = core.response.hold_body_chunk(ctx)
        for i, filter in ipairs(conf.filters) do
            if filter.scope == "once" then
              body = ngx.re.sub(body, filter.pattern, filter.replace, 
filter.options)
            else
              body = ngx.re.gsub(body, filter.pattern, filter.replace, 
filter.options)
            end
        end
   
      ngx.arg[1] = body
      ```
   
   **Example**
   * with response code `200`, fixed string `hello` replace with `world`
   ```shell
   curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: 
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
   {
       "methods": ["GET"],
       "uri": "/test/index.html",
       "plugins": {
           "response-rewrite": {
               "filters": [
                   {"scope": "global", "regex": "hello", "replace": "world", 
"options": "jio"}
               ]
               "vars":[
                   [ "status","==",200 ]
               ]
           }
       }
   }'
   ```
   
   * with response content-type `text/plain`, regex `\d` replace with `*`
   ```shell
   curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: 
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
   {
       "methods": ["GET"],
       "uri": "/test/index.html",
       "plugins": {
           "response-rewrite": {
               "filters": [
                   {"scope": "global", "regex": "\d", "replace": "*", 
"options": "jio"}
               ]
               "vars":[
                   [ "content-type","==","text/plain"]
               ]
           }
       }
   }'
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to