Skip to content

Commit

Permalink
feature(response-rewrite): support gzip when use filters.regex option (
Browse files Browse the repository at this point in the history
  • Loading branch information
yuweizzz authored Dec 25, 2023
1 parent 129844c commit 8f3b026
Show file tree
Hide file tree
Showing 3 changed files with 480 additions and 1 deletion.
3 changes: 2 additions & 1 deletion apisix-master-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ dependencies = {
"lua-resty-mediador = 0.1.2-1",
"lua-resty-ldap = 0.1.0-0",
"lua-resty-t1k = 1.1.0",
"brotli-ffi = 0.3-1"
"brotli-ffi = 0.3-1",
"lua-ffi-zlib = 0.6-0"
}

build = {
Expand Down
43 changes: 43 additions & 0 deletions apisix/plugins/response-rewrite.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ local expr = require("resty.expr.v1")
local re_compile = require("resty.core.regex").re_match_compile
local plugin_name = "response-rewrite"
local ngx = ngx
local ngx_header = ngx.header
local re_match = ngx.re.match
local re_sub = ngx.re.sub
local re_gsub = ngx.re.gsub
local pairs = pairs
local ipairs = ipairs
local type = type
local pcall = pcall
local zlib = require("ffi-zlib")
local str_buffer = require("string.buffer")


local lrucache = core.lrucache.new({
Expand Down Expand Up @@ -199,6 +202,31 @@ local function check_set_headers(headers)
end


local function inflate_gzip(data)
local inputs = str_buffer.new():set(data)
local outputs = str_buffer.new()

local read_inputs = function(size)
local data = inputs:get(size)
if data == "" then
return nil
end
return data
end

local write_outputs = function(data)
return outputs:put(data)
end

local ok, err = zlib.inflateGzip(read_inputs, write_outputs)
if not ok then
return nil, err
end

return outputs:get()
end


function _M.check_schema(conf)
local ok, err = core.schema.check(schema, conf)
if not ok then
Expand Down Expand Up @@ -260,6 +288,19 @@ function _M.body_filter(conf, ctx)
end

local err
if ctx.response_encoding == "gzip" then
body, err = inflate_gzip(body)
if err ~= nil then
core.log.error("filters may not work as expected, inflate gzip err: ", err)
return
end
elseif ctx.response_encoding ~= nil then
core.log.error("filters may not work as expected ",
"due to unsupported compression encoding type: ",
ctx.response_encoding)
return
end

for _, filter in ipairs(conf.filters) do
if filter.scope == "once" then
body, _, err = re_sub(body, filter.regex, filter.replace, filter.options)
Expand Down Expand Up @@ -333,7 +374,9 @@ function _M.header_filter(conf, ctx)

-- if filters have no any match, response body won't be modified.
if conf.filters or conf.body then
local response_encoding = ngx_header["Content-Encoding"]
core.response.clear_header_as_body_modified()
ctx.response_encoding = response_encoding
end

if not conf.headers then
Expand Down
Loading

0 comments on commit 8f3b026

Please sign in to comment.