Last active
January 9, 2024 10:17
-
-
Save davidcaste/05b2f9461ebe4a3bb3fc to your computer and use it in GitHub Desktop.
Nginx config: receive a request with a gzipped body, inflate it, and pass it to a proxied server
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
-- Debian packages nginx-extras, lua-zlib required | |
ngx.ctx.max_chunk_size = tonumber(ngx.var.max_chunk_size) | |
ngx.ctx.max_body_size = tonumber(ngx.var.max_body_size) | |
function create_error_response (code, description) | |
local message = string.format('{"status":400,"statusReason":"Bad Request","code":%d,"exception":"","description":"%s","message":"HTTP 400 Bad Request"}', code, description) | |
ngx.status = ngx.HTTP_BAD_REQUEST | |
ngx.header.content_type = "application/json" | |
ngx.say(message) | |
ngx.exit(ngx.HTTP_OK) | |
end | |
function inflate_chunk (stream, chunk) | |
return stream(chunk) | |
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) | |
create_error_response(4001, "Corrupted GZIP body") | |
end | |
if bytes_in == 0 and bytes_out == 0 then | |
-- body is not gzip compressed | |
create_error_response(4002, "Invalid GZIP body") | |
end | |
buffer = buffer .. output | |
if bytes_out > ngx.ctx.max_body_size then | |
-- uncompressed body too large | |
create_error_response(4003, "Uncompressed body too large") | |
end | |
end | |
return buffer | |
end | |
local content_encoding = ngx.req.get_headers()["Content-Encoding"] | |
if content_encoding == "gzip" then | |
ngx.req.read_body() | |
local data = ngx.req.get_body_data() | |
if data ~= '' then | |
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 |
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
server { | |
server_name default_server; | |
listen 80; | |
location / { | |
proxy_pass http://127.0.0.1:8080; | |
proxy_pass_request_headers on; | |
proxy_redirect off; | |
proxy_set_header X-Real-IP $remote_addr; | |
client_max_body_size 512k; # Max request body size of 512 KB | |
client_body_buffer_size 512k; | |
set $max_chunk_size = 10240; # Chunks of 10 KB | |
set $max_body_size = 524288; # Max inflated body size of 512 KB | |
rewrite_by_lua_file inflate_body.lua; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
set $max_chunk_size = 10240; # Chunks of 10 KB
shoud be change to the following:
set $max_chunk_size 10240; # Chunks of 10 KB