openresty / openresty/lua-nginx-module

Connection leak in ngx.location.capture()

Open
#1,857 4 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

The following settings lead to connections leak in nginx():

server {
  listen 8081;
  server_name  localhost;
  proxy_buffering on;
  proxy_buffers 8 128k;
  proxy_max_temp_file_size 0;
  location /a/ {
    content_by_lua_block {
      local data = ngx.location.capture('/b/')
      ngx.say("ok")
    }
  }
  location /b/ {
    proxy_pass http://127.0.0.1:8082/get/;
  }
  location /s/ {
    stub_status;
  }
}

If http://127.0.0.1:8082/get/ returned more than 1m (8 * 128k) of data then the upstream connection hangs. It still hangs even if the client connection breaks. You can easily see the leakage by configuring nginx with --with-http_stub_status_module option and by requesting http://127.0.0.1:8081/s/. Normal case (before requests):

Active connections: 1 
server accepts handled requests
 1 1 1 
Reading: 0 Writing: 1 Waiting: 0 

After 3 requests:

Active connections: 4 
server accepts handled requests
 5 5 5 
Reading: 0 Writing: 4 Waiting: 0 

You can setup a server for http://127.0.0.1:8082/get/ with the following configuration:

server {
  listen 8082;
  server_name  localhost;

  location /get/ {
    content_by_lua_block {
      ngx.say(string.rep(" ", 8*1024*1024))
    }
  }
}

Note that all works fine when proxy_buffering off; is set.

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

Reproduce the leak with the provided nginx configurations, a response larger than 1 MB, and proxy_buffering on; inspect ngx.location.capture() behavior around upstream responses and client disconnects. Use the /s/ stub_status endpoint to verify that connections return to the baseline after requests complete, including when proxy_buffering is disabled for comparison.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.