我有大量的HTTP POST请求被发送到一个nginx服务器,然后得到负载平衡到一套反向代理node.js / express.js后端服务器。 为了节省一些networking消耗,使用GZIP和头Content-Encoding:gzip发送有效载荷。
我试图达到这样的东西:
[Client] [Nginx Reverse Proxy] [BackEnd] | [gziped payload] | [raw payload] |
|--------------------> | ----------------------------->| | | |
| [Raw Response] | [Raw response] | | <------------------ | <-----------------------------| | | |
出于效率的原因,我想在Nginx上运行Gunzip,但是我还没有做到这一点。 这里是http nginx.conf文件:
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; gunzip on; location / { proxy_pass http://localhost:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } }
这是一个请求的例子:
echo "{"id": 0,"mypayload":"This is an example"}" | gzip -c - | curl -v -i -X POST -H 'Content-Encoding: gzip' --data-binary '@-' http://localhost/test
我希望nginx解压缩有效负载的内容,并将原始内容传送到后端服务器,但内容仍然被压缩。
我见过很多人(Nginx gziping响应,甚至对没有Accept-Encoding:gzip头文件的客户端的响应),但是还是无法成功地将它载入后端。
任何线索?
我知道这是一个较老的问题,但我正在寻找一个发送压缩请求的IOS客户端,并在检查出你的问题后,我遇到了一个在这里描述的卢阿解决方案,并认为将其发布在这里供将来参考。
lua模块看起来像:
-- 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
然后你可以像这样使用它:
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; }