[nginx] Stream: the $upstream_addr variable.
Vladimir Homutov
vl at nginx.com
Fri Sep 2 15:28:32 UTC 2016
details: http://hg.nginx.org/nginx/rev/ab9b4fd8c5b7
branches:
changeset: 6675:ab9b4fd8c5b7
user: Vladimir Homutov <vl at nginx.com>
date: Fri Sep 02 18:27:05 2016 +0300
description:
Stream: the $upstream_addr variable.
Keeps the full address of the upstream server. If several servers were
contacted during proxying, their addresses are separated by commas,
e.g. "192.168.1.1:80, 192.168.1.2:80".
diffstat:
src/stream/ngx_stream.h | 3 +-
src/stream/ngx_stream_proxy_module.c | 17 ++++++
src/stream/ngx_stream_upstream.c | 92 +++++++++++++++++++++++++++++++++++-
src/stream/ngx_stream_upstream.h | 6 ++
4 files changed, 116 insertions(+), 2 deletions(-)
diffs (193 lines):
diff -r 38143d1abdec -r ab9b4fd8c5b7 src/stream/ngx_stream.h
--- a/src/stream/ngx_stream.h Thu Aug 11 20:22:23 2016 +0300
+++ b/src/stream/ngx_stream.h Fri Sep 02 18:27:05 2016 +0300
@@ -172,7 +172,8 @@ struct ngx_stream_session_s {
void **srv_conf;
ngx_stream_upstream_t *upstream;
-
+ ngx_array_t *upstream_states;
+ /* of ngx_stream_upstream_state_t */
ngx_stream_variable_value_t *variables;
#if (NGX_PCRE)
diff -r 38143d1abdec -r ab9b4fd8c5b7 src/stream/ngx_stream_proxy_module.c
--- a/src/stream/ngx_stream_proxy_module.c Thu Aug 11 20:22:23 2016 +0300
+++ b/src/stream/ngx_stream_proxy_module.c Fri Sep 02 18:27:05 2016 +0300
@@ -392,6 +392,13 @@ ngx_stream_proxy_handler(ngx_stream_sess
c->write->handler = ngx_stream_proxy_downstream_handler;
c->read->handler = ngx_stream_proxy_downstream_handler;
+ s->upstream_states = ngx_array_create(c->pool, 1,
+ sizeof(ngx_stream_upstream_state_t));
+ if (s->upstream_states == NULL) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
if (c->type == SOCK_STREAM) {
p = ngx_pnalloc(c->pool, pscf->buffer_size);
if (p == NULL) {
@@ -677,6 +684,14 @@ ngx_stream_proxy_connect(ngx_stream_sess
u = s->upstream;
+ u->state = ngx_array_push(s->upstream_states);
+ if (u->state == NULL) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ngx_memzero(u->state, sizeof(ngx_stream_upstream_state_t));
+
rc = ngx_event_connect_peer(&u->peer);
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
@@ -686,6 +701,8 @@ ngx_stream_proxy_connect(ngx_stream_sess
return;
}
+ u->state->peer = u->peer.name;
+
if (rc == NGX_BUSY) {
ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
diff -r 38143d1abdec -r ab9b4fd8c5b7 src/stream/ngx_stream_upstream.c
--- a/src/stream/ngx_stream_upstream.c Thu Aug 11 20:22:23 2016 +0300
+++ b/src/stream/ngx_stream_upstream.c Fri Sep 02 18:27:05 2016 +0300
@@ -10,6 +10,10 @@
#include <ngx_stream.h>
+static ngx_int_t ngx_stream_upstream_add_variables(ngx_conf_t *cf);
+static ngx_int_t ngx_stream_upstream_addr_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+
static char *ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd,
void *dummy);
static char *ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -39,7 +43,7 @@ static ngx_command_t ngx_stream_upstrea
static ngx_stream_module_t ngx_stream_upstream_module_ctx = {
- NULL, /* preconfiguration */
+ ngx_stream_upstream_add_variables, /* preconfiguration */
NULL, /* postconfiguration */
ngx_stream_upstream_create_main_conf, /* create main configuration */
@@ -66,6 +70,92 @@ ngx_module_t ngx_stream_upstream_module
};
+static ngx_stream_variable_t ngx_stream_upstream_vars[] = {
+
+ { ngx_string("upstream_addr"), NULL,
+ ngx_stream_upstream_addr_variable, 0,
+ NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
+
+
+static ngx_int_t
+ngx_stream_upstream_add_variables(ngx_conf_t *cf)
+{
+ ngx_stream_variable_t *var, *v;
+
+ for (v = ngx_stream_upstream_vars; v->name.len; v++) {
+ var = ngx_stream_add_variable(cf, &v->name, v->flags);
+ if (var == NULL) {
+ return NGX_ERROR;
+ }
+
+ var->get_handler = v->get_handler;
+ var->data = v->data;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_upstream_addr_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+ size_t len;
+ ngx_uint_t i;
+ ngx_stream_upstream_state_t *state;
+
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ if (s->upstream_states == NULL || s->upstream_states->nelts == 0) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ len = 0;
+ state = s->upstream_states->elts;
+
+ for (i = 0; i < s->upstream_states->nelts; i++) {
+ if (state[i].peer) {
+ len += state[i].peer->len;
+ }
+
+ len += 2;
+ }
+
+ p = ngx_pnalloc(s->connection->pool, len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->data = p;
+
+ i = 0;
+
+ for ( ;; ) {
+ if (state[i].peer) {
+ p = ngx_cpymem(p, state[i].peer->data, state[i].peer->len);
+ }
+
+ if (++i == s->upstream_states->nelts) {
+ break;
+ }
+
+ *p++ = ',';
+ *p++ = ' ';
+ }
+
+ v->len = p - v->data;
+
+ return NGX_OK;
+}
+
+
static char *
ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
{
diff -r 38143d1abdec -r ab9b4fd8c5b7 src/stream/ngx_stream_upstream.h
--- a/src/stream/ngx_stream_upstream.h Thu Aug 11 20:22:23 2016 +0300
+++ b/src/stream/ngx_stream_upstream.h Fri Sep 02 18:27:05 2016 +0300
@@ -79,6 +79,11 @@ struct ngx_stream_upstream_srv_conf_s {
typedef struct {
+ ngx_str_t *peer;
+} ngx_stream_upstream_state_t;
+
+
+typedef struct {
ngx_str_t host;
in_port_t port;
ngx_uint_t no_port; /* unsigned no_port:1 */
@@ -104,6 +109,7 @@ typedef struct {
ngx_str_t ssl_name;
#endif
ngx_stream_upstream_resolved_t *resolved;
+ ngx_stream_upstream_state_t *state;
unsigned connected:1;
unsigned proxy_protocol:1;
} ngx_stream_upstream_t;
More information about the nginx-devel
mailing list