openresty / openresty/lua-nginx-module

srcache_store response hangs with request body when used with ngx.req.get_body_data()

Open
#1,699 0 comments 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

Openresty srcache_store doesn't work if there is payload in request body. and ngx.req.get_body_data() is used

Using openresty lua-nginx-module to cache and serve web-pages. (reverse proxy to caching)
https://github.com/openresty/lua-nginx-module
Openresty 1.15.8.3
ngx_lua 0.10.16

ISSUE: When try request with request body, it hangs the response. . same is also observed using redis2_query and redis_pass.

Below is my default.conf script:


server {
    # Listen on port 80.
    listen 80 default_server;
    listen [::]:80 default_server;
    # The document root.
    root /usr/local/openresty/nginx/html/default;
    # Add index.php if you are using PHP.
    index index.html index.htm;

    # The server name, which isn't relevant in this case, because we only have one.
    server_name _;

    access_log /var/log/openresty/nginx_cache.log custom_cache_log ;

    location / {
     default_type application/json;
     client_max_body_size 100k;
     client_body_buffer_size 100k;
     set $key "";
     access_by_lua_block {
        ngx.req.read_body()
        local data = ngx.req.get_body_data()
        ngx.var.key = "es:" .. ngx.md5(ngx.var.request_uri .. (data or ""))
        ngx.log(ngx.ERR, "key: ", ngx.var.key)
    }

     srcache_fetch GET /redis-fetch key=$key;
     srcache_store PUT /redis-store key=$key&exptime=3600;

     proxy_set_header Host $host;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header X-Forwarded-Proto $scheme;
     proxy_pass http://ElasticSearch_SERVER:9200;
    }

    location = /redis-fetch {
        internal;
        content_by_lua_block {
                local redis = require "resty.redis"
                local red = redis:new()
                red:set_timeouts(10000, 10000, 10000)
                local ok, err = red:connect("Redis_Server",16318)
                if not ok then
                    ngx.say("failed to connect: ", err)
                    return
                end
                ngx.say(ok)
        }
    }

    location = /redis-store {
    internal;
    content_by_lua_block {
               local redis = require "resty.redis"
               local red = redis:new()
               red:set_timeouts(10000, 10000, 10000)
               local ok, err = red:connect("Redis_Server",16318)
               if not ok then
                   ngx.say("failed to connect: ", err)
                   return
               end
               ok, err = red:set(ngx.var.arg_key,ngx.var.echo_request_body)
               if not ok then
                   ngx.say("failed to set key: ", err)
                   return
               end
               ok, err = red:expire(ngx.var.arg_key,ngx.var.arg_exptime)
     }
   }   
}

Following request works fine (first time cache is not exists so served from upstream server and cache is created in redis. next time same page request is served from cache redis)

  1. Curl request, GET method:
    curl -u "username:Password" "http://Proxy_SERVER:80/index/_search?typed_keys=true&ignore_unavailable=true&expand_wildcards=open&allow_no_indices=true&search_type=query_then_fetch&batched_reduce_size=512"
    Result => works as expected.

  2. Curl to without any explicit HTTP method defined but small body parameters:
    curl -u username:password "http://Reverse_proxy:80/_search?pretty" -H 'Content-Type: application/json' -d '{"query":{"match_all":{}}}'

Result => response hangs

  1. Curl to without any explicit HTTP method defined but large body parameters:
  • same curl like #2 but larger body
    Result => response hangs.

Note that we can explicitly send HTTP method in every request as its coming from different client. Can we override the HTTP method in default.conf ?? or is there any other settings need to done to solve this issue?

We already tried following options but no luck:

  1. set srcache_methods POST GET PUT HEAD
  2. proxy_method POST
  3. increase proxy buffer

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 report using the supplied default.conf, especially the access_by_lua_block call to ngx.req.get_body_data() and the srcache_store path. Compare the working GET request with the body-bearing curl requests, and inspect the related redis2_query behavior. Done means the request-body requests no longer hang while the existing cache behavior remains intact.

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
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.