Dynamic URL for proxy_pass directive via lua_module

941 views
Skip to first unread message

Muby M

unread,
Oct 12, 2017, 5:58:30 PM10/12/17
to openresty-en

Hi all !


The requirement is to use the dynamic URL for proxy_pass directive . By using $arg_name built variable and lua code(openresty)   ,  query parameter value acts as KEY to retrieve the corresponding VALUE ( target URL for proxy_pass directive) stored in Redis. For example in the URL http://10.10.10.3/?cust=cust2  ,  $arg_cust gets cust2 as KEY which is further used to retrieve corresponding VALUE stored in Redis .
It works fine for all the target url BUT one the target URL returns error when KEY value from the uri  is retrieved  dynamically via $arg_cust (http://10.10.10.3/?cust=cust2). curl http://10.10.10.3/?cust=cust2 works OK.  Interesting to note is that if  KEY value (cust2) is hard-coded in lua , it  also works OK.  

The target URL gets appended with extended new URL path in upstream server  (this part "/common/NSLogin.jsp?redirect=/console"  gets added )  via embeded javascript in the index page.  I do not understand WHY it works when KEY value (cust2) is hard coded in the lua but  does not work if same KEY value (cust2) is retrieved via $arg_cust variable.  As I said earlier, all other URL works fine for $arg_cust EXCEPT above one . May be error is due to extended URL in up-stream server.  Here is my code 


######################################## server block code ###############################################################
server {
        
        listen       80;
        server_name  localhost;
        set $ngcust $arg_cust;  # <<<<< NOT WORKING 
        #set $ngcust "cust2";    # <<<<< Works OK  if commented-out.
    
        set $ng1 ' ';  
        
         location / {
                           
            access_by_lua_block {
                local key = ngx.var.ngcust
                 local redis = require "resty.redis"
                 local red = redis:new()

                red:set_timeout(1000) -- 1 sec

                local ok, err = red:connect("127.0.0.1", 6379)
                if not ok then
                    ngx.say("failed to connect: ", err)
                   return
                end
                               
             local res, err = red:get(key)
            
          ngx.var.ng1=res
            
      --  ngx.say(ngx.var.ng1)   <<<<<<<<<  also shows correct VALUE retrieved from Redis. 

              }                
                
                
    proxy_set_header HOST $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   
 proxy_pass "http://$ng1";
     
               
        }
 

###############################################################################
 


#########error.log#######################


access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/common/NSLogin.jsp?redirect=/console"

2017/10/12 17:45:17 [notice] 3076#3076: signal process started

2017/10/12 17:45:17 [notice] 6086#6086: signal 1 (SIGHUP) received, reconfiguring

2017/10/12 17:45:17 [notice] 6086#6086: signal 1 (SIGHUP) received, reconfiguring

2017/10/12 17:45:17 [notice] 6086#6086: reconfiguring

2017/10/12 17:45:17 [notice] 6086#6086: reconfiguring

2017/10/12 17:45:17 [notice] 6086#6086: using the "epoll" event method

2017/10/12 17:45:17 [notice] 6086#6086: using the "epoll" event method

2017/10/12 17:45:17 [notice] 6086#6086: start worker processes

2017/10/12 17:45:17 [notice] 6086#6086: start worker processes

2017/10/12 17:45:17 [notice] 6086#6086: start worker process 3077

2017/10/12 17:45:17 [notice] 6086#6086: start worker process 3077

2017/10/12 17:45:17 [notice] 2748#2748: gracefully shutting down

2017/10/12 17:45:17 [notice] 2748#2748: gracefully shutting down

2017/10/12 17:45:17 [notice] 2748#2748: exiting

2017/10/12 17:45:17 [notice] 2748#2748: exiting

2017/10/12 17:45:17 [notice] 2748#2748: exit

2017/10/12 17:45:17 [notice] 6086#6086: signal 17 (SIGCHLD) received

2017/10/12 17:45:17 [notice] 6086#6086: signal 17 (SIGCHLD) received

2017/10/12 17:45:17 [notice] 6086#6086: worker process 2748 exited with code 0

2017/10/12 17:45:17 [notice] 6086#6086: worker process 2748 exited with code 0

2017/10/12 17:45:17 [notice] 6086#6086: signal 29 (SIGIO) received

2017/10/12 17:45:17 [notice] 6086#6086: signal 29 (SIGIO) received

2017/10/12 17:46:00 [error] 3077#3077: *31502 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:

coroutine 0:

[C]: in function '__newindex'

access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/?cust=cust2"

2017/10/12 17:46:00 [error] 3077#3077: *31502 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:

coroutine 0:

[C]: in function '__newindex'

access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/?cust=cust2"

2017/10/12 17:46:00 [error] 3077#3077: *31502 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:

coroutine 0:

[C]: in function '__newindex'

access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/?cust=cust2"

2017/10/12 17:46:00 [error] 3077#3077: *31503 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:

coroutine 0:

[C]: in function '__newindex'

access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /common/NSLogin.jsp?redirect=/console HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/?cust=cust2"

2017/10/12 17:46:00 [error] 3077#3077: *31503 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:

coroutine 0:

[C]: in function '__newindex'

access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /common/NSLogin.jsp?redirect=/console HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/?cust=cust2"

2017/10/12 17:46:00 [error] 3077#3077: *31503 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:

coroutine 0:

[C]: in function '__newindex'

access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /common/NSLogin.jsp?redirect=/console HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/?cust=cust2"

2017/10/12 17:46:00 [error] 3077#3077: *31508 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:

coroutine 0:

[C]: in function '__newindex'

access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/common/NSLogin.jsp?redirect=/console"

2017/10/12 17:46:00 [error] 3077#3077: *31508 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:

coroutine 0:

[C]: in function '__newindex'

access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/common/NSLogin.jsp?redirect=/console"

2017/10/12 17:46:00 [error] 3077#3077: *31508 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:

coroutine 0:

[C]: in function '__newindex'

access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.10.10.3", referrer: "http://10.10.10.3/common/NSLogin.jsp?redirect=/console"


#######################################################################################################

curl command output .. OK 

[root@localhost ~]# curl 10.10.10.3/?cust=cust2
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>nGenius Redirect</title>
        <script type="text/javascript">
                function launchSplash()
                {
                        var newPath = "/common/NSLogin.jsp?redirect=/console";
                        var host = document.location.host;
                        var protocol = document.location.protocol + "//";
                        var splashURL = protocol + host + newPath;
                        return splashURL;
                }

                var website = launchSplash();
                window.location = website;
        </script>
</head>
<body>
</body>
</html>


#############################################################

Contents of web-page 


An error occurred.

Sorry, the page you are looking for is currently unavailable.
Please try again later.

If you are the system administrator of this resource then you should check the error log for details.

Faithfully yours, OpenResty.

tokers

unread,
Oct 12, 2017, 9:46:07 PM10/12/17
to openresty-en
Hi!

There is an assignment that the value is got from redis(res), you should check the type since userdata is not accpeted for ngx.var.VARIABLE.

Muby M

unread,
Oct 13, 2017, 5:26:59 AM10/13/17
to openresty-en
Hi tokers

Thanks for your reply.  Let me explain the scenarios

scenario 1.  (not working )

 local res, err = red:get(key

In above statement, the value for key parameter comes from uri part ( 10.10.10.3/?cust=cust2 ) by using  built-in variable $arg_cust  which gets  "cust2" for key parameter .  The value retrieved against key "cust2" from the Redis is just target URL for proxy_pass. 




scenario 2.  (working)


But if the key parameter in the above statement   is hardcoded with a value like this  
 
local res,err = red:get("cust2") then it works fine.


Findings

1.  Scenario 1 works fine with all other target URL of proxy_pass  for cust3 , cust4 and so on  ( 10.10.10.3/?cust=cust3 ) . The difference is that in case of cust2, the target URL gets appended with extended new URL path in upstream server  (this part "/common/NSLogin.jsp?redirect=/console"  gets added )  via embeded javascript in the index page .

2.  This means lua code encounters an error when the browser gets extended url as added by target upstream.And this happens ONLY when key
value retrieved dynamically via $arg_cust  .    local res, err = red:get(key


Any input will be highly appreciated .

Muby M

unread,
Oct 13, 2017, 7:52:37 AM10/13/17
to openresty-en
Hi

Just to say that I get same error for all target URL irrespective of the fact that upstream server extend the URL or not.  Please treat following statement  as NOT valid as I mentioned in my last post in finding section.  

1.  Scenario 1 works fine with all other target URL of proxy_pass  for cust3 , cust4 and so on  ( 10.10.10.3/?cust=cust3 ) . The difference is that in case of cust2, the target URL gets appended with extended new URL path in upstream server  (this part "/common/NSLogin.jsp?redirect=/console"  gets added )  via embeded javascript in the index page




The following log shows error for a query parameter cust=7 which Redis value as simple target URL to proxy_pass to upstream running simple "hello word" .  Again it will only work if KEY parameter is hard-coded with the value "cust7".


 access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.3, server: localhost, request: "GET /cust=cust7 HTTP/1.1", host: "10.10.10.3"
2017/10/13 07:37:28 [error] 4612#4612: *33284 lua entry thread aborted: runtime error: access_by_lua(nginx.conf:72):16: bad argument #1 to '__newindex' (string, number, or nil expected, but got userdata)

stack traceback:
coroutine 0:
 [C]: in function '__newindex'
 access_by_lua(nginx.conf:72):16: in function <access_by_lua(nginx.conf:72):1>, client: 10.10.10.3, server: localhost, request: "GET /cust=cust7 HTTP/1.1", host: "10.10.10.3"
Reply all
Reply to author
Forward
0 new messages