lua-nginx-module icon indicating copy to clipboard operation
lua-nginx-module copied to clipboard

bug: memory leak when collecting response body chunks

Open shreemaan-abhishek opened this issue 1 year ago • 1 comments

Loading large response body with size > 300 MB into memory causes leak.

The purpose of collecting response body chunks is to record them in logs in the log phase.

Steps to reproduce:

  • use the following nginx.conf:
worker_processes 1;
error_log logs/error.log warn;

events {
    worker_connections 1024;
}

http {

    server {
        listen       8080;

        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;

            body_filter_by_lua_block {

                local body_buffer
                local chunk, eof = ngx.arg[1], ngx.arg[2]

                local ctx = ngx.ctx
                if not ctx._body_buffer then
                    ctx._body_buffer = {}
                end

                if type(chunk) == "string" and chunk ~= "" then
                    body_buffer = ctx._body_buffer
                    if not body_buffer then
                        body_buffer = {
                            chunk,
                            n = 1
                        }
                        ctx._body_buffer = body_buffer
                    else
                        local n = (body_buffer.n or 1) + 1
                        body_buffer.n = n
                        body_buffer[n] = chunk
                    end
                end

                if eof then
                    body_buffer = ctx._body_buffer
                    if not body_buffer then
                        return chunk
                    end

                    body_buffer = table.concat(body_buffer, "", 1, body_buffer.n)
                    ctx._body_buffer = nil
                end

            }
        }
    }

    upstream backend {
        server 192.168.253.1:8081;
    }
}
  • the upstream should respond with a response body of size >= 300MB.
  • start openresty
  • check memory usage using top image
  • send a request:
curl http://127.0.0.1:8080/ --output tmpfile
  • top command output will clearly show memory usage spike that doesn't get freed but the usage keeps on increasing upon further requests image

version:

nginx version: openresty/1.25.3.1
built by gcc 13.2.0 (Ubuntu 13.2.0-23ubuntu4)
built with OpenSSL 3.0.13 30 Jan 2024
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --with-debug --with-cc-opt='-DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC -O2 -DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC -O2 -DNGX_LUA_ABORT_AT_PANIC' --add-module=../ngx_devel_kit-0.3.3 --add-module=../echo-nginx-module-0.63 --add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2 --add-module=../set-misc-nginx-module-0.33 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.09 --add-module=../srcache-nginx-module-0.33 --add-module=../ngx_lua-0.10.26 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.37 --add-module=../array-var-nginx-module-0.06 --add-module=../memc-nginx-module-0.20 --add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-module-0.3.9 --add-module=../rds-json-nginx-module-0.16 --add-module=../rds-csv-nginx-module-0.09 --add-module=../ngx_stream_lua-0.0.14 --with-ld-opt=-Wl,-rpath,/usr/local/openresty/luajit/lib --with-stream --without-pcre2 --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_ssl_module

shreemaan-abhishek avatar Aug 02 '24 04:08 shreemaan-abhishek