Created
July 17, 2016 02:57
-
-
Save nicky-zs/b395ff5fbcad6ed734357dbc120f597e to your computer and use it in GitHub Desktop.
Supporting gzipped request body.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- lua-zlib is required | |
local MAX_BODY_SIZE = 16777216 | |
ngx.ctx.max_chunk_size = tonumber(ngx.var.max_chunk_size) or 262144 -- 256KB | |
ngx.ctx.max_body_size = tonumber(ngx.var.max_body_size) or MAX_BODY_SIZE -- 16MB | |
function bad_request_response(status, msg) | |
local message = string.format('{"status": %d, "msg": "%s"}', status, msg) | |
ngx.status = ngx.HTTP_BAD_REQUEST | |
ngx.header.content_type = "application/json" | |
ngx.say(message) | |
ngx.exit(ngx.HTTP_OK) | |
end | |
function inflate_body(data) | |
local stream = require("zlib").inflate() | |
local buffer = "" | |
local chunk = "" | |
for index = 0, data:len(), ngx.ctx.max_chunk_size do | |
chunk = string.sub(data, index, index + ngx.ctx.max_chunk_size - 1) | |
local status, output, eof, bytes_in, bytes_out = pcall(stream, chunk) | |
if not status then -- corrupted chunk | |
ngx.log(ngx.ERR, output) | |
bad_request_response(4003, "gzip格式已损坏") | |
end | |
if bytes_in == 0 and bytes_out == 0 then -- body is not gzip compressed | |
bad_request_response(4004, "非gzip压缩格式") | |
end | |
buffer = buffer .. output | |
if bytes_out > ngx.ctx.max_body_size then -- uncompressed body too large | |
bad_request_response(4005, "gzip解压结果太大") | |
end | |
end | |
return buffer | |
end | |
local headers = ngx.req.get_headers() | |
local content_length = headers["Content-Length"] | |
local content_encoding = headers["Content-Encoding"] | |
if content_length and tonumber(content_length) > MAX_BODY_SIZE then | |
bad_request_response(4005, "gzip解压结果太大") | |
end | |
if content_encoding and content_encoding:lower() == "gzip" then | |
ngx.req.read_body() | |
local data = ngx.req.get_body_data() | |
if data == nil then | |
local file_name = ngx.req.get_body_file() | |
if file_name ~= nil and file_name ~= '' then | |
local file = io.open(file_name, "r") | |
data = file:read("*a") | |
file:close() | |
end | |
end | |
if data ~= nil and data ~= '' then | |
if data:len() > MAX_BODY_SIZE then | |
bad_request_response(4005, "gzip解压结果太大") | |
end | |
local new_data = inflate_body(data) | |
ngx.req.clear_header("Content-Encoding") | |
ngx.req.clear_header("Content-Length") | |
ngx.req.set_body_data(new_data) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment