Skip to content

Instantly share code, notes, and snippets.

@csfrancis
Created June 10, 2016 00:20
Show Gist options
  • Save csfrancis/4b6ca42b9903f4cef1e05580b2dba1d9 to your computer and use it in GitHub Desktop.
Save csfrancis/4b6ca42b9903f4cef1e05580b2dba1d9 to your computer and use it in GitHub Desktop.
From 25ec18a4c341955e4e6bd051a06b9d92d09e2d33 Mon Sep 17 00:00:00 2001
From: Justin Li <jli.justinli@gmail.com>
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]
+
# HG changeset patch
# User Yichun Zhang <agentzh@openresty.org>
# Date 1451762084 28800
# Sat Jan 02 11:14:44 2016 -0800
# Node ID 449f0461859c16e95bdb18e8be6b94401545d3dd
# Parent 78b4e10b4367b31367aad3c83c9c3acdd42397c4
SSL: handled SSL_CTX_set_cert_cb() callback yielding.
OpenSSL 1.0.2+ introduces SSL_CTX_set_cert_cb() to allow custom
callbacks to serve the SSL certificiates and private keys dynamically
and lazily. The callbacks may yield for nonblocking I/O or sleeping.
Here we added support for such usage in NGINX 3rd-party modules
(like ngx_lua) in NGINX's event handlers for downstream SSL
connections.
diff -r 78b4e10b4367 -r 449f0461859c src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c Thu Dec 17 16:39:15 2015 +0300
+++ b/src/event/ngx_event_openssl.c Sat Jan 02 11:14:44 2016 -0800
@@ -1210,6 +1210,23 @@
return NGX_AGAIN;
}
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ if (sslerr == SSL_ERROR_WANT_X509_LOOKUP) {
+ c->read->handler = ngx_ssl_handshake_handler;
+ c->write->handler = ngx_ssl_handshake_handler;
+
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ return NGX_AGAIN;
+ }
+#endif
+
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
c->ssl->no_wait_shutdown = 1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment