openresty / openresty/lua-nginx-module

bug: memory leak when collecting response body chunks

Open
#2,346 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
11.8k
Forks
2.1k
Avg merge
6h 1m
Merged PRs (30d)
6

Description

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided nginx.conf and its body_filter_by_lua_block, then reproduce the issue using an upstream response of at least 300 MB and monitor memory with top. Trace how response chunks are collected and released across repeated curl requests; done means memory no longer continually increases after requests complete.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua, nginx
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.