mirror of
https://github.com/nginx/nginx.git
synced 2024-12-23 15:40:03 -06:00
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".
This commit is contained in:
parent
be6024f9b7
commit
c6d456da87
@ -172,7 +172,8 @@ struct ngx_stream_session_s {
|
|||||||
void **srv_conf;
|
void **srv_conf;
|
||||||
|
|
||||||
ngx_stream_upstream_t *upstream;
|
ngx_stream_upstream_t *upstream;
|
||||||
|
ngx_array_t *upstream_states;
|
||||||
|
/* of ngx_stream_upstream_state_t */
|
||||||
ngx_stream_variable_value_t *variables;
|
ngx_stream_variable_value_t *variables;
|
||||||
|
|
||||||
#if (NGX_PCRE)
|
#if (NGX_PCRE)
|
||||||
|
@ -392,6 +392,13 @@ ngx_stream_proxy_handler(ngx_stream_session_t *s)
|
|||||||
c->write->handler = ngx_stream_proxy_downstream_handler;
|
c->write->handler = ngx_stream_proxy_downstream_handler;
|
||||||
c->read->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) {
|
if (c->type == SOCK_STREAM) {
|
||||||
p = ngx_pnalloc(c->pool, pscf->buffer_size);
|
p = ngx_pnalloc(c->pool, pscf->buffer_size);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
@ -677,6 +684,14 @@ ngx_stream_proxy_connect(ngx_stream_session_t *s)
|
|||||||
|
|
||||||
u = s->upstream;
|
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);
|
rc = ngx_event_connect_peer(&u->peer);
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
|
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
|
||||||
@ -686,6 +701,8 @@ ngx_stream_proxy_connect(ngx_stream_session_t *s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u->state->peer = u->peer.name;
|
||||||
|
|
||||||
if (rc == NGX_BUSY) {
|
if (rc == NGX_BUSY) {
|
||||||
ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
|
ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
|
||||||
ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
|
ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
|
||||||
|
@ -10,6 +10,10 @@
|
|||||||
#include <ngx_stream.h>
|
#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,
|
static char *ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
void *dummy);
|
void *dummy);
|
||||||
static char *ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
|
static char *ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
@ -39,7 +43,7 @@ static ngx_command_t ngx_stream_upstream_commands[] = {
|
|||||||
|
|
||||||
|
|
||||||
static ngx_stream_module_t ngx_stream_upstream_module_ctx = {
|
static ngx_stream_module_t ngx_stream_upstream_module_ctx = {
|
||||||
NULL, /* preconfiguration */
|
ngx_stream_upstream_add_variables, /* preconfiguration */
|
||||||
NULL, /* postconfiguration */
|
NULL, /* postconfiguration */
|
||||||
|
|
||||||
ngx_stream_upstream_create_main_conf, /* create main configuration */
|
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 *
|
static char *
|
||||||
ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +78,11 @@ struct ngx_stream_upstream_srv_conf_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_str_t *peer;
|
||||||
|
} ngx_stream_upstream_state_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_str_t host;
|
ngx_str_t host;
|
||||||
in_port_t port;
|
in_port_t port;
|
||||||
@ -104,6 +109,7 @@ typedef struct {
|
|||||||
ngx_str_t ssl_name;
|
ngx_str_t ssl_name;
|
||||||
#endif
|
#endif
|
||||||
ngx_stream_upstream_resolved_t *resolved;
|
ngx_stream_upstream_resolved_t *resolved;
|
||||||
|
ngx_stream_upstream_state_t *state;
|
||||||
unsigned connected:1;
|
unsigned connected:1;
|
||||||
unsigned proxy_protocol:1;
|
unsigned proxy_protocol:1;
|
||||||
} ngx_stream_upstream_t;
|
} ngx_stream_upstream_t;
|
||||||
|
Loading…
Reference in New Issue
Block a user