From 25ec18a4c341955e4e6bd051a06b9d92d09e2d33 Mon Sep 17 00:00:00 2001 From: Justin Li Date: Thu, 4 Feb 2016 23:15:42 +0000 Subject: [PATCH] feature: Add upstream.current_upstream_name() to return the current proxy target --- README.md | 27 ++++++++++++ src/ngx_http_lua_upstream_module.c | 44 ++++++++++++++++++++ t/sanity.t | 84 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) diff --git a/README.md b/README.md index 56ba73f..bf36b7e 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Table of Contents * [get_primary_peers](#get_primary_peers) * [get_backup_peers](#get_backup_peers) * [set_peer_down](#set_peer_down) + * [current_upstream_name](#current_upstream_name) * [TODO](#todo) * [Compatibility](#compatibility) * [Installation](#installation) @@ -209,6 +210,32 @@ You can turn on a peer again by providing a `false` value as the 4th argument. [Back to TOC](#table-of-contents) +current_upstream_name +--------------------- +`syntax: name = upstream.current_upstream_name()` + +Returns the name of the proxied upstream for the current request. +If there is no upstream for this request (no `proxy_pass` call), or this +function is called in a phase prior to the content phase, then the return value +will be `nil`. If a port is explicitly included in the upstream definition or +`proxy_pass` directive, it will be included in the return value of this function. + +Example: + +```lua +-- upstream my_upstream { ... } +-- proxy_pass http://my_upstream; +upstream.current_upstream_name() --> my_upstream + +-- proxy_pass http://example.com:1234; +upstream.current_upstream_name() --> example.com:1234 +``` + +Note that implicit upstreams created by `proxy_pass` are included, contrary to +the output of `upstream.get_upstreams()`. + +[Back to TOC](#table-of-contents) + TODO ==== diff --git a/src/ngx_http_lua_upstream_module.c b/src/ngx_http_lua_upstream_module.c index 1ffd1da..f678d1d 100644 --- a/src/ngx_http_lua_upstream_module.c +++ b/src/ngx_http_lua_upstream_module.c @@ -34,6 +34,7 @@ static ngx_http_upstream_srv_conf_t * static ngx_http_upstream_rr_peer_t * ngx_http_lua_upstream_lookup_peer(lua_State *L); static int ngx_http_lua_upstream_set_peer_down(lua_State * L); +static int ngx_http_lua_upstream_current_upstream_name(lua_State *L); static ngx_http_module_t ngx_http_lua_upstream_ctx = { @@ -98,6 +99,9 @@ ngx_http_lua_upstream_create_module(lua_State * L) lua_pushcfunction(L, ngx_http_lua_upstream_set_peer_down); lua_setfield(L, -2, "set_peer_down"); + lua_pushcfunction(L, ngx_http_lua_upstream_current_upstream_name); + lua_setfield(L, -2, "current_upstream_name"); + return 1; } @@ -544,3 +548,43 @@ ngx_http_lua_upstream_find_upstream(lua_State *L, ngx_str_t *host) return NULL; } + + +static int +ngx_http_lua_upstream_current_upstream_name(lua_State *L) +{ + ngx_http_request_t *r; + ngx_http_upstream_t *us; + ngx_http_upstream_conf_t *ucf; + ngx_http_upstream_srv_conf_t *uscf; + + r = ngx_http_lua_get_request(L); + if (r == NULL) { + return luaL_error(L, "no request object found"); + } + + us = r->upstream; + if (us == NULL) { + lua_pushnil(L); /* no proxying is being done */ + return 1; + } + + ucf = us->conf; + if (ucf == NULL) { + return luaL_error(L, "no conf for upstream"); + } + + uscf = ucf->upstream; + if (uscf == NULL) { + return luaL_error(L, "no srv conf for upstream"); + } + + lua_pushlstring(L, (char *) uscf->host.data, uscf->host.len); + + if (uscf->port) { + lua_pushfstring(L, ":%d", (int) uscf->port); + lua_concat(L, 2); + } + + return 1; +} diff --git a/t/sanity.t b/t/sanity.t index b6142a4..c713c78 100644 --- a/t/sanity.t +++ b/t/sanity.t @@ -564,3 +564,87 @@ upstream 127.0.0.1:1130: --- no_error_log [error] + + +=== TEST 15: upstream_name with valid explicit upstream +--- http_config + upstream some_upstream { + server 127.0.0.1:$TEST_NGINX_SERVER_PORT; + } +--- config + log_by_lua_block { + local upstream = require "ngx.upstream" + ngx.log(ngx.INFO, "upstream = " .. tostring(upstream.current_upstream_name())) + } + location /test { + proxy_pass http://some_upstream/back; + } + location /back { + echo ok; + } +--- request +GET /test +--- response_body +ok +--- log_level: info +--- error_log eval +qr/upstream = some_upstream/ + + + +=== TEST 16: upstream_name with valid implicit upstream +--- config + log_by_lua_block { + local upstream = require "ngx.upstream" + ngx.log(ngx.INFO, "upstream = " .. tostring(upstream.current_upstream_name())) + } + location /test { + proxy_pass http://127.0.0.1:$TEST_NGINX_SERVER_PORT/back; + } + location /back { + echo ok; + } +--- request +GET /test +--- response_body +ok +--- log_level: info +--- error_log eval +qr/upstream = 127.0.0.1:\d+/ + + + +=== TEST 17: upstream_name with no proxy_pass +--- config + log_by_lua_block { + local upstream = require "ngx.upstream" + ngx.log(ngx.INFO, "upstream = " .. tostring(upstream.current_upstream_name())) + } + location /test { + echo ok; + } +--- request +GET /test +--- response_body +ok +--- log_level: info +--- error_log eval +qr/upstream = nil/ + + + +=== TEST 18: upstream_name in content_by_lua +--- config + location /test { + content_by_lua_block { + local upstream = require "ngx.upstream" + ngx.say(upstream.current_upstream_name()) + } + } +--- request +GET /test +--- response_body +nil +--- no_error_log +[error] +