mirror of
https://github.com/nginx/nginx.git
synced 2025-06-07 17:52:38 +08:00
upstream choice modules
This commit is contained in:
parent
a53f7293c8
commit
3d2fd18a39
@ -255,6 +255,11 @@ if [ $HTTP_FLV = YES ]; then
|
|||||||
HTTP_SRCS="$HTTP_SRCS $HTTP_FLV_SRCS"
|
HTTP_SRCS="$HTTP_SRCS $HTTP_FLV_SRCS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then
|
||||||
|
HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_IP_HASH_MODULE"
|
||||||
|
HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_IP_HASH_SRCS"
|
||||||
|
fi
|
||||||
|
|
||||||
# STUB
|
# STUB
|
||||||
#USE_MD5=YES
|
#USE_MD5=YES
|
||||||
#HTTP_SRCS="$HTTP_SRCS $HTPP_CACHE_SRCS"
|
#HTTP_SRCS="$HTTP_SRCS $HTPP_CACHE_SRCS"
|
||||||
|
@ -71,6 +71,7 @@ HTTP_MEMCACHED=YES
|
|||||||
HTTP_EMPTY_GIF=YES
|
HTTP_EMPTY_GIF=YES
|
||||||
HTTP_BROWSER=YES
|
HTTP_BROWSER=YES
|
||||||
HTTP_FLV=NO
|
HTTP_FLV=NO
|
||||||
|
HTTP_UPSTREAM_IP_HASH=YES
|
||||||
|
|
||||||
# STUB
|
# STUB
|
||||||
HTTP_STUB_STATUS=NO
|
HTTP_STUB_STATUS=NO
|
||||||
@ -170,6 +171,7 @@ do
|
|||||||
--without-http_memcached_module) HTTP_MEMCACHED=NO ;;
|
--without-http_memcached_module) HTTP_MEMCACHED=NO ;;
|
||||||
--without-http_empty_gif_module) HTTP_EMPTY_GIF=NO ;;
|
--without-http_empty_gif_module) HTTP_EMPTY_GIF=NO ;;
|
||||||
--without-http_browser_module) HTTP_BROWSER=NO ;;
|
--without-http_browser_module) HTTP_BROWSER=NO ;;
|
||||||
|
--without-http_upstream_ip_hash_module) HTTP_UPSTREAM_IP_HASH=NO ;;
|
||||||
|
|
||||||
--with-http_perl_module) HTTP_PERL=YES ;;
|
--with-http_perl_module) HTTP_PERL=YES ;;
|
||||||
--with-perl_modules_path=*) NGX_PERL_MODULES="$value" ;;
|
--with-perl_modules_path=*) NGX_PERL_MODULES="$value" ;;
|
||||||
@ -271,6 +273,8 @@ cat << END
|
|||||||
--without-http_memcached_module disable ngx_http_memcached_module
|
--without-http_memcached_module disable ngx_http_memcached_module
|
||||||
--without-http_empty_gif_module disable ngx_http_empty_gif_module
|
--without-http_empty_gif_module disable ngx_http_empty_gif_module
|
||||||
--without-http_browser_module disable ngx_http_browser_module
|
--without-http_browser_module disable ngx_http_browser_module
|
||||||
|
--without-http_upstream_ip_hash_module
|
||||||
|
disable ngx_http_upstream_ip_hash_module
|
||||||
|
|
||||||
--with-http_perl_module enable ngx_http_perl_module
|
--with-http_perl_module enable ngx_http_perl_module
|
||||||
--with-perl_modules_path=PATH set path to the perl modules
|
--with-perl_modules_path=PATH set path to the perl modules
|
||||||
|
@ -270,6 +270,7 @@ HTTP_DEPS="src/http/ngx_http.h \
|
|||||||
src/http/ngx_http_variables.h \
|
src/http/ngx_http_variables.h \
|
||||||
src/http/ngx_http_script.h \
|
src/http/ngx_http_script.h \
|
||||||
src/http/ngx_http_upstream.h \
|
src/http/ngx_http_upstream.h \
|
||||||
|
src/http/ngx_http_upstream_round_robin.h \
|
||||||
src/http/ngx_http_busy_lock.h"
|
src/http/ngx_http_busy_lock.h"
|
||||||
|
|
||||||
HTTP_SRCS="src/http/ngx_http.c \
|
HTTP_SRCS="src/http/ngx_http.c \
|
||||||
@ -285,6 +286,7 @@ HTTP_SRCS="src/http/ngx_http.c \
|
|||||||
src/http/ngx_http_variables.c \
|
src/http/ngx_http_variables.c \
|
||||||
src/http/ngx_http_script.c \
|
src/http/ngx_http_script.c \
|
||||||
src/http/ngx_http_upstream.c \
|
src/http/ngx_http_upstream.c \
|
||||||
|
src/http/ngx_http_upstream_round_robin.c \
|
||||||
src/http/ngx_http_parse_time.c \
|
src/http/ngx_http_parse_time.c \
|
||||||
src/http/modules/ngx_http_static_module.c \
|
src/http/modules/ngx_http_static_module.c \
|
||||||
src/http/modules/ngx_http_index_module.c \
|
src/http/modules/ngx_http_index_module.c \
|
||||||
@ -398,6 +400,10 @@ HTTP_FLV_MODULE=ngx_http_flv_module
|
|||||||
HTTP_FLV_SRCS=src/http/modules/ngx_http_flv_module.c
|
HTTP_FLV_SRCS=src/http/modules/ngx_http_flv_module.c
|
||||||
|
|
||||||
|
|
||||||
|
HTTP_UPSTREAM_IP_HASH_MODULE=ngx_http_upstream_ip_hash_module
|
||||||
|
HTTP_UPSTREAM_IP_HASH_SRCS=src/http/modules/ngx_http_upstream_ip_hash_module.c
|
||||||
|
|
||||||
|
|
||||||
IMAP_INCS="src/imap"
|
IMAP_INCS="src/imap"
|
||||||
|
|
||||||
IMAP_DEPS="src/imap/ngx_imap.h"
|
IMAP_DEPS="src/imap/ngx_imap.h"
|
||||||
|
@ -19,7 +19,6 @@ typedef struct ngx_open_file_s ngx_open_file_t;
|
|||||||
typedef struct ngx_command_s ngx_command_t;
|
typedef struct ngx_command_s ngx_command_t;
|
||||||
typedef struct ngx_file_s ngx_file_t;
|
typedef struct ngx_file_s ngx_file_t;
|
||||||
typedef struct ngx_event_s ngx_event_t;
|
typedef struct ngx_event_s ngx_event_t;
|
||||||
typedef struct ngx_peers_s ngx_peers_t;
|
|
||||||
typedef struct ngx_connection_s ngx_connection_t;
|
typedef struct ngx_connection_s ngx_connection_t;
|
||||||
|
|
||||||
typedef void (*ngx_event_handler_pt)(ngx_event_t *ev);
|
typedef void (*ngx_event_handler_pt)(ngx_event_t *ev);
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
#include <ngx_event.h>
|
|
||||||
#include <ngx_event_connect.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -239,8 +237,6 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
|
|
||||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||||
|
|
||||||
u->type = NGX_PARSE_URL_UNIX;
|
|
||||||
|
|
||||||
p += 5;
|
p += 5;
|
||||||
len -= 5;
|
len -= 5;
|
||||||
|
|
||||||
@ -271,8 +267,8 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t));
|
u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
|
||||||
if (u->peers == NULL) {
|
if (u->addrs == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,16 +277,15 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->peers->number = 1;
|
u->naddrs = 1;
|
||||||
|
|
||||||
saun->sun_family = AF_UNIX;
|
saun->sun_family = AF_UNIX;
|
||||||
(void) ngx_cpystrn((u_char *) saun->sun_path, p, len + 1);
|
(void) ngx_cpystrn((u_char *) saun->sun_path, p, len + 1);
|
||||||
|
|
||||||
u->peers->peer[0].sockaddr = (struct sockaddr *) saun;
|
u->addrs[0].sockaddr = (struct sockaddr *) saun;
|
||||||
u->peers->peer[0].socklen = sizeof(struct sockaddr_un);
|
u->addrs[0].socklen = sizeof(struct sockaddr_un);
|
||||||
u->peers->peer[0].name.len = len + 5;
|
u->addrs[0].name.len = len + 5;
|
||||||
u->peers->peer[0].name.data = u->url.data;
|
u->addrs[0].name.data = u->url.data;
|
||||||
u->peers->peer[0].uri_separator = ":";
|
|
||||||
|
|
||||||
u->host_header.len = sizeof("localhost") - 1;
|
u->host_header.len = sizeof("localhost") - 1;
|
||||||
u->host_header.data = (u_char *) "localhost";
|
u->host_header.data = (u_char *) "localhost";
|
||||||
@ -310,8 +305,6 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->type = NGX_PARSE_URL_INET;
|
|
||||||
|
|
||||||
u->host.data = p;
|
u->host.data = p;
|
||||||
u->host_header.len = len;
|
u->host_header.len = len;
|
||||||
u->host_header.data = p;
|
u->host_header.data = p;
|
||||||
@ -323,7 +316,7 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
u->host.len = i;
|
u->host.len = i;
|
||||||
|
|
||||||
if (!u->uri_part) {
|
if (!u->uri_part) {
|
||||||
u->port.len = &p[len] - u->port.data;
|
u->port.len = len - (i + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -338,8 +331,8 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (u->port.data == NULL) {
|
if (u->port.data == NULL) {
|
||||||
u->default_port = 1;
|
u->no_port = 1;
|
||||||
goto port;
|
goto no_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->port.len = &p[i] - u->port.data;
|
u->port.len = &p[i] - u->port.data;
|
||||||
@ -375,10 +368,10 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
port = ngx_atoi(p, len);
|
port = ngx_atoi(p, len);
|
||||||
|
|
||||||
if (port == NGX_ERROR) {
|
if (port == NGX_ERROR) {
|
||||||
u->default_port = 1;
|
|
||||||
u->host.len = len;
|
u->host.len = len;
|
||||||
|
u->no_port = 1;
|
||||||
|
|
||||||
goto port;
|
goto no_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->port.len = len;
|
u->port.len = len;
|
||||||
@ -388,9 +381,10 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
|
|
||||||
u->portn = (in_port_t) port;
|
u->portn = (in_port_t) port;
|
||||||
|
|
||||||
port:
|
no_port:
|
||||||
|
|
||||||
if (u->listen) {
|
if (u->listen) {
|
||||||
|
|
||||||
if (u->portn == 0) {
|
if (u->portn == 0) {
|
||||||
if (u->default_portn == 0) {
|
if (u->default_portn == 0) {
|
||||||
u->err = "no port";
|
u->err = "no port";
|
||||||
@ -435,13 +429,9 @@ port:
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->default_port) {
|
if (u->no_port) {
|
||||||
|
|
||||||
if (u->upstream) {
|
if (u->default_portn == 0 && !u->upstream) {
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (u->default_portn == 0) {
|
|
||||||
u->err = "no port";
|
u->err = "no port";
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -455,12 +445,8 @@ port:
|
|||||||
|
|
||||||
u->port.len = ngx_sprintf(u->port.data, "%d", u->portn) - u->port.data;
|
u->port.len = ngx_sprintf(u->port.data, "%d", u->portn) - u->port.data;
|
||||||
|
|
||||||
} else if (u->portn) {
|
} else if (u->portn == 0) {
|
||||||
if (u->portn == u->default_portn) {
|
|
||||||
u->default_port = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
u->err = "no port";
|
u->err = "no port";
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -470,14 +456,11 @@ port:
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->peers = ngx_inet_resolve_peer(cf, &u->host, u->portn);
|
if (u->no_resolve) {
|
||||||
|
return NGX_OK;
|
||||||
if (u->peers == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->peers == NGX_CONF_ERROR) {
|
if (ngx_inet_resolve_host(cf, u) != NGX_OK) {
|
||||||
u->err = "host not found";
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,23 +468,22 @@ port:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_peers_t *
|
ngx_int_t
|
||||||
ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name, in_port_t port)
|
ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
|
||||||
{
|
{
|
||||||
u_char *host;
|
u_char *host;
|
||||||
size_t len;
|
size_t len;
|
||||||
in_addr_t in_addr;
|
in_addr_t in_addr;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_peers_t *peers;
|
|
||||||
struct hostent *h;
|
struct hostent *h;
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
host = ngx_palloc(cf->temp_pool, name->len + 1);
|
host = ngx_palloc(cf->temp_pool, u->host.len + 1);
|
||||||
if (host == NULL) {
|
if (host == NULL) {
|
||||||
return NULL;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) ngx_cpystrn(host, name->data, name->len + 1);
|
(void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
|
||||||
|
|
||||||
/* AF_INET only */
|
/* AF_INET only */
|
||||||
|
|
||||||
@ -511,92 +493,88 @@ ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name, in_port_t port)
|
|||||||
h = gethostbyname((char *) host);
|
h = gethostbyname((char *) host);
|
||||||
|
|
||||||
if (h == NULL || h->h_addr_list[0] == NULL) {
|
if (h == NULL || h->h_addr_list[0] == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
u->err = "host not found";
|
||||||
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
|
if (u->one_addr == 0) {
|
||||||
|
for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
|
||||||
|
|
||||||
|
} else {
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* MP: ngx_shared_palloc() */
|
/* MP: ngx_shared_palloc() */
|
||||||
|
|
||||||
peers = ngx_pcalloc(cf->pool,
|
u->addrs = ngx_pcalloc(cf->pool, i * sizeof(ngx_peer_addr_t));
|
||||||
sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1));
|
if (u->addrs == NULL) {
|
||||||
if (peers == NULL) {
|
return NGX_ERROR;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
peers->number = i;
|
u->naddrs = i;
|
||||||
|
|
||||||
for (i = 0; h->h_addr_list[i] != NULL; i++) {
|
for (i = 0; h->h_addr_list[i] != NULL; i++) {
|
||||||
|
|
||||||
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
|
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
|
||||||
if (sin == NULL) {
|
if (sin == NULL) {
|
||||||
return NULL;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
sin->sin_family = AF_INET;
|
sin->sin_family = AF_INET;
|
||||||
sin->sin_port = htons(port);
|
sin->sin_port = htons(u->portn);
|
||||||
sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
|
sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
|
||||||
|
|
||||||
peers->peer[i].sockaddr = (struct sockaddr *) sin;
|
u->addrs[i].sockaddr = (struct sockaddr *) sin;
|
||||||
peers->peer[i].socklen = sizeof(struct sockaddr_in);
|
u->addrs[i].socklen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
|
len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
|
||||||
|
|
||||||
peers->peer[i].name.data = ngx_palloc(cf->pool, len);
|
u->addrs[i].name.data = ngx_palloc(cf->pool, len);
|
||||||
if (peers->peer[i].name.data == NULL) {
|
if (u->addrs[i].name.data == NULL) {
|
||||||
return NULL;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin,
|
len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin,
|
||||||
peers->peer[i].name.data, len);
|
u->addrs[i].name.data, len);
|
||||||
|
|
||||||
peers->peer[i].name.len =
|
u->addrs[i].name.len = ngx_sprintf(&u->addrs[i].name.data[len],
|
||||||
ngx_sprintf(&peers->peer[i].name.data[len],
|
":%d", u->portn)
|
||||||
":%d", port)
|
- u->addrs[i].name.data;
|
||||||
- peers->peer[i].name.data;
|
|
||||||
|
|
||||||
peers->peer[i].uri_separator = "";
|
|
||||||
|
|
||||||
peers->peer[i].weight = NGX_CONF_UNSET_UINT;
|
|
||||||
peers->peer[i].max_fails = NGX_CONF_UNSET_UINT;
|
|
||||||
peers->peer[i].fail_timeout = NGX_CONF_UNSET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* MP: ngx_shared_palloc() */
|
/* MP: ngx_shared_palloc() */
|
||||||
|
|
||||||
peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t));
|
u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
|
||||||
if (peers == NULL) {
|
if (u->addrs == NULL) {
|
||||||
return NULL;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
|
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
|
||||||
if (sin == NULL) {
|
if (sin == NULL) {
|
||||||
return NULL;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
peers->number = 1;
|
u->naddrs = 1;
|
||||||
|
|
||||||
sin->sin_family = AF_INET;
|
sin->sin_family = AF_INET;
|
||||||
sin->sin_port = htons(port);
|
sin->sin_port = htons(u->portn);
|
||||||
sin->sin_addr.s_addr = in_addr;
|
sin->sin_addr.s_addr = in_addr;
|
||||||
|
|
||||||
peers->peer[0].sockaddr = (struct sockaddr *) sin;
|
u->addrs[0].sockaddr = (struct sockaddr *) sin;
|
||||||
peers->peer[0].socklen = sizeof(struct sockaddr_in);
|
u->addrs[0].socklen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
peers->peer[0].name.data = ngx_palloc(cf->pool,
|
u->addrs[0].name.data = ngx_palloc(cf->pool,
|
||||||
name->len + sizeof(":65536") - 1);
|
u->host.len + sizeof(":65536") - 1);
|
||||||
if (peers->peer[0].name.data == NULL) {
|
if (u->addrs[0].name.data == NULL) {
|
||||||
return NULL;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
peers->peer[0].name.len = ngx_sprintf(peers->peer[0].name.data, "%V:%d",
|
u->addrs[0].name.len = ngx_sprintf(u->addrs[0].name.data, "%V:%d",
|
||||||
name, port)
|
&u->host, u->portn)
|
||||||
- peers->peer[0].name.data;
|
- u->addrs[0].name.data;
|
||||||
|
|
||||||
peers->peer[0].uri_separator = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return peers;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
@ -12,80 +12,51 @@
|
|||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
|
|
||||||
|
|
||||||
#define NGX_PARSE_URL_INET 1
|
|
||||||
#define NGX_PARSE_URL_UNIX 2
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
in_addr_t addr;
|
in_addr_t addr;
|
||||||
in_addr_t mask;
|
in_addr_t mask;
|
||||||
} ngx_inet_cidr_t;
|
} ngx_inet_cidr_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct sockaddr *sockaddr;
|
|
||||||
socklen_t socklen;
|
|
||||||
|
|
||||||
ngx_str_t name;
|
|
||||||
char *uri_separator;
|
|
||||||
|
|
||||||
ngx_uint_t current_weight;
|
|
||||||
ngx_uint_t weight;
|
|
||||||
|
|
||||||
ngx_uint_t fails;
|
|
||||||
time_t accessed;
|
|
||||||
|
|
||||||
ngx_uint_t max_fails;
|
|
||||||
time_t fail_timeout;
|
|
||||||
|
|
||||||
#if (NGX_SSL)
|
|
||||||
ngx_ssl_session_t *ssl_session;
|
|
||||||
#endif
|
|
||||||
} ngx_peer_t;
|
|
||||||
|
|
||||||
|
|
||||||
struct ngx_peers_s {
|
|
||||||
ngx_uint_t current;
|
|
||||||
|
|
||||||
ngx_uint_t number;
|
|
||||||
ngx_uint_t last_cached;
|
|
||||||
|
|
||||||
/* ngx_mutex_t *mutex; */
|
|
||||||
ngx_connection_t **cached;
|
|
||||||
|
|
||||||
ngx_peer_t peer[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
in_addr_t in_addr;
|
in_addr_t in_addr;
|
||||||
} ngx_url_addr_t;
|
} ngx_url_addr_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_int_t type;
|
struct sockaddr *sockaddr;
|
||||||
|
socklen_t socklen;
|
||||||
|
ngx_str_t name;
|
||||||
|
} ngx_peer_addr_t;
|
||||||
|
|
||||||
ngx_peers_t *peers;
|
|
||||||
|
|
||||||
ngx_str_t url;
|
typedef struct {
|
||||||
ngx_str_t host;
|
ngx_int_t type;
|
||||||
ngx_str_t host_header;
|
|
||||||
ngx_str_t port;
|
|
||||||
ngx_str_t uri;
|
|
||||||
|
|
||||||
in_port_t portn;
|
ngx_str_t url;
|
||||||
in_port_t default_portn;
|
ngx_str_t host;
|
||||||
|
ngx_str_t host_header;
|
||||||
|
ngx_str_t port;
|
||||||
|
ngx_str_t uri;
|
||||||
|
|
||||||
unsigned listen:1;
|
in_port_t portn;
|
||||||
unsigned uri_part:1;
|
in_port_t default_portn;
|
||||||
unsigned upstream:1;
|
|
||||||
|
|
||||||
unsigned default_port:1;
|
unsigned listen:1;
|
||||||
unsigned wildcard:1;
|
unsigned uri_part:1;
|
||||||
|
unsigned upstream:1;
|
||||||
|
unsigned no_resolve:1;
|
||||||
|
unsigned one_addr:1;
|
||||||
|
|
||||||
ngx_url_addr_t addr;
|
unsigned wildcard:1;
|
||||||
|
unsigned no_port:1;
|
||||||
|
|
||||||
char *err;
|
ngx_url_addr_t addr;
|
||||||
|
|
||||||
|
ngx_peer_addr_t *addrs;
|
||||||
|
ngx_uint_t naddrs;
|
||||||
|
|
||||||
|
char *err;
|
||||||
} ngx_url_t;
|
} ngx_url_t;
|
||||||
|
|
||||||
|
|
||||||
@ -93,8 +64,8 @@ size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len);
|
|||||||
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
|
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
|
||||||
ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
|
ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
|
||||||
ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u);
|
ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u);
|
||||||
ngx_peers_t *ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name,
|
ngx_int_t ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u);
|
||||||
in_port_t port);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NGX_INET_H_INCLUDED_ */
|
#endif /* _NGX_INET_H_INCLUDED_ */
|
||||||
|
@ -14,145 +14,21 @@ ngx_int_t
|
|||||||
ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
ngx_uint_t level, i;
|
|
||||||
u_int event;
|
u_int event;
|
||||||
time_t now;
|
|
||||||
ngx_err_t err;
|
ngx_err_t err;
|
||||||
ngx_peer_t *peer;
|
ngx_uint_t level;
|
||||||
ngx_socket_t s;
|
ngx_socket_t s;
|
||||||
ngx_event_t *rev, *wev;
|
ngx_event_t *rev, *wev;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
|
|
||||||
now = ngx_time();
|
rc = pc->get(pc, pc->data);
|
||||||
|
if (rc != NGX_OK) {
|
||||||
/* ngx_lock_mutex(pc->peers->mutex); */
|
return rc;
|
||||||
|
|
||||||
if (pc->peers->last_cached) {
|
|
||||||
|
|
||||||
/* cached connection */
|
|
||||||
|
|
||||||
c = pc->peers->cached[pc->peers->last_cached];
|
|
||||||
pc->peers->last_cached--;
|
|
||||||
|
|
||||||
/* ngx_unlock_mutex(pc->peers->mutex); */
|
|
||||||
|
|
||||||
#if (NGX_THREADS)
|
|
||||||
c->read->lock = c->read->own_lock;
|
|
||||||
c->write->lock = c->write->own_lock;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pc->connection = c;
|
|
||||||
pc->cached = 1;
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pc->cached = 0;
|
s = ngx_socket(pc->sockaddr->sa_family, SOCK_STREAM, 0);
|
||||||
pc->connection = NULL;
|
|
||||||
|
|
||||||
if (pc->peers->number == 1) {
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, "socket %d", s);
|
||||||
peer = &pc->peers->peer[0];
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* there are several peers */
|
|
||||||
|
|
||||||
if (pc->tries == pc->peers->number) {
|
|
||||||
|
|
||||||
/* it's a first try - get a current peer */
|
|
||||||
|
|
||||||
for ( ;; ) {
|
|
||||||
pc->cur_peer = pc->peers->current;
|
|
||||||
|
|
||||||
peer = &pc->peers->peer[pc->cur_peer];
|
|
||||||
|
|
||||||
if (peer->max_fails == 0 || peer->fails <= peer->max_fails) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now - peer->accessed > peer->fail_timeout) {
|
|
||||||
peer->fails = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pc->peers->current++;
|
|
||||||
|
|
||||||
if (pc->peers->current >= pc->peers->number) {
|
|
||||||
pc->peers->current = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pc->tries--;
|
|
||||||
|
|
||||||
if (pc->tries) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
peer->current_weight--;
|
|
||||||
|
|
||||||
if (peer->current_weight == 0) {
|
|
||||||
peer->current_weight = peer->weight;
|
|
||||||
|
|
||||||
pc->peers->current++;
|
|
||||||
|
|
||||||
if (pc->peers->current >= pc->peers->number) {
|
|
||||||
pc->peers->current = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
for ( ;; ) {
|
|
||||||
peer = &pc->peers->peer[pc->cur_peer];
|
|
||||||
|
|
||||||
if (peer->max_fails == 0 || peer->fails <= peer->max_fails) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now - peer->accessed > peer->fail_timeout) {
|
|
||||||
peer->fails = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pc->cur_peer++;
|
|
||||||
|
|
||||||
if (pc->cur_peer >= pc->peers->number) {
|
|
||||||
pc->cur_peer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pc->tries--;
|
|
||||||
|
|
||||||
if (pc->tries) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
peer->current_weight--;
|
|
||||||
|
|
||||||
if (peer->current_weight == 0) {
|
|
||||||
peer->current_weight = peer->weight;
|
|
||||||
|
|
||||||
if (pc->cur_peer == pc->peers->current) {
|
|
||||||
pc->peers->current++;
|
|
||||||
|
|
||||||
if (pc->peers->current >= pc->peers->number) {
|
|
||||||
pc->peers->current = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ngx_unlock_mutex(pc->peers->mutex); */
|
|
||||||
|
|
||||||
|
|
||||||
s = ngx_socket(peer->sockaddr->sa_family, SOCK_STREAM, 0);
|
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0,
|
|
||||||
"socket %d", s);
|
|
||||||
|
|
||||||
if (s == -1) {
|
if (s == -1) {
|
||||||
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
||||||
@ -211,7 +87,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||||||
|
|
||||||
c->log_error = pc->log_error;
|
c->log_error = pc->log_error;
|
||||||
|
|
||||||
if (peer->sockaddr->sa_family != AF_INET) {
|
if (pc->sockaddr->sa_family != AF_INET) {
|
||||||
c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
|
c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
|
||||||
c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
|
c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
|
||||||
|
|
||||||
@ -254,9 +130,9 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0,
|
||||||
"connect to %V, fd:%d #%d", &peer->name, s, c->number);
|
"connect to %V, fd:%d #%d", pc->name, s, c->number);
|
||||||
|
|
||||||
rc = connect(s, peer->sockaddr, peer->socklen);
|
rc = connect(s, pc->sockaddr, pc->socklen);
|
||||||
|
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
err = ngx_socket_errno;
|
err = ngx_socket_errno;
|
||||||
@ -272,7 +148,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_error(level, c->log, err, "connect() to %V failed",
|
ngx_log_error(level, c->log, err, "connect() to %V failed",
|
||||||
&peer->name);
|
pc->name);
|
||||||
|
|
||||||
return NGX_DECLINED;
|
return NGX_DECLINED;
|
||||||
}
|
}
|
||||||
@ -352,51 +228,11 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||||||
wev->ready = 1;
|
wev->ready = 1;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
|
|
||||||
failed:
|
|
||||||
|
|
||||||
/* all peers failed, mark them as live for quick recovery */
|
|
||||||
|
|
||||||
for (i = 0; i < pc->peers->number; i++) {
|
|
||||||
pc->peers->peer[i].fails = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ngx_unlock_mutex(pc->peers->mutex); */
|
|
||||||
|
|
||||||
return NGX_BUSY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
ngx_int_t
|
||||||
ngx_event_connect_peer_failed(ngx_peer_connection_t *pc, ngx_uint_t down)
|
ngx_event_get_peer(ngx_peer_connection_t *pc, void *data)
|
||||||
{
|
{
|
||||||
time_t now;
|
return NGX_OK;
|
||||||
ngx_peer_t *peer;
|
|
||||||
|
|
||||||
if (down) {
|
|
||||||
now = ngx_time();
|
|
||||||
|
|
||||||
/* ngx_lock_mutex(pc->peers->mutex); */
|
|
||||||
|
|
||||||
peer = &pc->peers->peer[pc->cur_peer];
|
|
||||||
|
|
||||||
peer->fails++;
|
|
||||||
peer->accessed = now;
|
|
||||||
|
|
||||||
if (peer->current_weight > 1) {
|
|
||||||
peer->current_weight /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ngx_unlock_mutex(pc->peers->mutex); */
|
|
||||||
}
|
|
||||||
|
|
||||||
pc->cur_peer++;
|
|
||||||
|
|
||||||
if (pc->cur_peer >= pc->peers->number) {
|
|
||||||
pc->cur_peer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pc->tries) {
|
|
||||||
pc->tries--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -13,27 +13,56 @@
|
|||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
#define NGX_PEER_KEEPALIVE 1
|
||||||
ngx_peers_t *peers;
|
#define NGX_PEER_NEXT 2
|
||||||
ngx_uint_t cur_peer;
|
#define NGX_PEER_FAILED 4
|
||||||
ngx_uint_t tries;
|
|
||||||
|
|
||||||
ngx_connection_t *connection;
|
|
||||||
#if (NGX_THREADS)
|
typedef struct ngx_peer_connection_s ngx_peer_connection_t;
|
||||||
ngx_atomic_t *lock;
|
|
||||||
|
typedef ngx_int_t (*ngx_event_get_peer_pt)(ngx_peer_connection_t *pc,
|
||||||
|
void *data);
|
||||||
|
#if (NGX_SSL)
|
||||||
|
typedef void (*ngx_event_save_peer_pt)(ngx_peer_connection_t *pc, void *data);
|
||||||
|
#endif
|
||||||
|
typedef void (*ngx_event_free_peer_pt)(ngx_peer_connection_t *pc, void *data,
|
||||||
|
ngx_uint_t state);
|
||||||
|
|
||||||
|
|
||||||
|
struct ngx_peer_connection_s {
|
||||||
|
ngx_connection_t *connection;
|
||||||
|
|
||||||
|
struct sockaddr *sockaddr;
|
||||||
|
socklen_t socklen;
|
||||||
|
ngx_str_t *name;
|
||||||
|
|
||||||
|
ngx_uint_t tries;
|
||||||
|
|
||||||
|
ngx_event_get_peer_pt get;
|
||||||
|
ngx_event_free_peer_pt free;
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
#if (NGX_SSL)
|
||||||
|
ngx_ssl_session_t *ssl_session;
|
||||||
|
ngx_event_save_peer_pt save_session;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int rcvbuf;
|
#if (NGX_THREADS)
|
||||||
|
ngx_atomic_t *lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
ngx_log_t *log;
|
int rcvbuf;
|
||||||
|
|
||||||
unsigned cached:1;
|
ngx_log_t *log;
|
||||||
unsigned log_error:2; /* ngx_connection_log_error_e */
|
|
||||||
} ngx_peer_connection_t;
|
unsigned cached:1;
|
||||||
|
unsigned log_error:2; /* ngx_connection_log_error_e */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc);
|
ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc);
|
||||||
void ngx_event_connect_peer_failed(ngx_peer_connection_t *pc, ngx_uint_t down);
|
ngx_int_t ngx_event_get_peer(ngx_peer_connection_t *pc, void *data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NGX_EVENT_CONNECT_H_INCLUDED_ */
|
#endif /* _NGX_EVENT_CONNECT_H_INCLUDED_ */
|
||||||
|
@ -13,9 +13,6 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_http_upstream_conf_t upstream;
|
ngx_http_upstream_conf_t upstream;
|
||||||
|
|
||||||
ngx_http_upstream_srv_conf_t *upstream_peers;
|
|
||||||
ngx_peers_t *peers0;
|
|
||||||
|
|
||||||
ngx_str_t index;
|
ngx_str_t index;
|
||||||
|
|
||||||
ngx_array_t *flushes;
|
ngx_array_t *flushes;
|
||||||
@ -121,6 +118,11 @@ static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||||||
static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,
|
static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
static char *ngx_http_fastcgi_upstream_max_fails_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf);
|
||||||
|
static char *ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf);
|
||||||
|
|
||||||
|
|
||||||
static ngx_http_fastcgi_request_start_t ngx_http_fastcgi_request_start = {
|
static ngx_http_fastcgi_request_start_t ngx_http_fastcgi_request_start = {
|
||||||
{ 1, /* version */
|
{ 1, /* version */
|
||||||
@ -310,16 +312,16 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
|
|||||||
|
|
||||||
{ ngx_string("fastcgi_upstream_max_fails"),
|
{ ngx_string("fastcgi_upstream_max_fails"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_num_slot,
|
ngx_http_fastcgi_upstream_max_fails_unsupported,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
0,
|
||||||
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.max_fails),
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("fastcgi_upstream_fail_timeout"),
|
{ ngx_string("fastcgi_upstream_fail_timeout"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_sec_slot,
|
ngx_http_fastcgi_upstream_fail_timeout_unsupported,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
0,
|
||||||
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.fail_timeout),
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("fastcgi_param"),
|
{ ngx_string("fastcgi_param"),
|
||||||
@ -411,8 +413,6 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
u->peer.log = r->connection->log;
|
u->peer.log = r->connection->log;
|
||||||
u->peer.log_error = NGX_ERROR_ERR;
|
u->peer.log_error = NGX_ERROR_ERR;
|
||||||
u->peer.peers = flcf->upstream_peers->peers;
|
|
||||||
u->peer.tries = flcf->upstream_peers->peers->number;
|
|
||||||
#if (NGX_THREADS)
|
#if (NGX_THREADS)
|
||||||
u->peer.lock = &r->connection->lock;
|
u->peer.lock = &r->connection->lock;
|
||||||
#endif
|
#endif
|
||||||
@ -1547,9 +1547,6 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
|
|||||||
conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
|
conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
|
||||||
conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
|
conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
|
||||||
|
|
||||||
conf->upstream.max_fails = NGX_CONF_UNSET_UINT;
|
|
||||||
conf->upstream.fail_timeout = NGX_CONF_UNSET;
|
|
||||||
|
|
||||||
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
|
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
|
||||||
conf->upstream.pass_request_body = NGX_CONF_UNSET;
|
conf->upstream.pass_request_body = NGX_CONF_UNSET;
|
||||||
|
|
||||||
@ -1573,7 +1570,6 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
uintptr_t *code;
|
uintptr_t *code;
|
||||||
ngx_str_t *header;
|
ngx_str_t *header;
|
||||||
ngx_uint_t i, j;
|
ngx_uint_t i, j;
|
||||||
ngx_peer_t *peer;
|
|
||||||
ngx_array_t hide_headers;
|
ngx_array_t hide_headers;
|
||||||
ngx_keyval_t *src;
|
ngx_keyval_t *src;
|
||||||
ngx_hash_key_t *hk;
|
ngx_hash_key_t *hk;
|
||||||
@ -1707,25 +1703,6 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
|NGX_HTTP_UPSTREAM_FT_OFF;
|
|NGX_HTTP_UPSTREAM_FT_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_conf_merge_uint_value(conf->upstream.max_fails,
|
|
||||||
prev->upstream.max_fails, 1);
|
|
||||||
|
|
||||||
ngx_conf_merge_sec_value(conf->upstream.fail_timeout,
|
|
||||||
prev->upstream.fail_timeout, 10);
|
|
||||||
|
|
||||||
if (conf->upstream_peers) {
|
|
||||||
peer = conf->upstream_peers->peers->peer;
|
|
||||||
for (i = 0; i < conf->upstream_peers->peers->number; i++) {
|
|
||||||
ngx_conf_init_uint_value(peer[i].weight, 1);
|
|
||||||
peer[i].current_weight = peer[i].weight;
|
|
||||||
ngx_conf_init_uint_value(peer[i].max_fails,
|
|
||||||
conf->upstream.max_fails);
|
|
||||||
ngx_conf_init_value(peer[i].fail_timeout,
|
|
||||||
conf->upstream.fail_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_conf_merge_path_value(conf->upstream.temp_path,
|
ngx_conf_merge_path_value(conf->upstream.temp_path,
|
||||||
prev->upstream.temp_path,
|
prev->upstream.temp_path,
|
||||||
NGX_HTTP_FASTCGI_TEMP_PATH, 1, 2, 0,
|
NGX_HTTP_FASTCGI_TEMP_PATH, 1, 2, 0,
|
||||||
@ -1844,8 +1821,8 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
|
|
||||||
peers:
|
peers:
|
||||||
|
|
||||||
if (conf->upstream_peers == NULL) {
|
if (conf->upstream.upstream == NULL) {
|
||||||
conf->upstream_peers = prev->upstream_peers;
|
conf->upstream.upstream = prev->upstream.upstream;
|
||||||
conf->upstream.schema = prev->upstream.schema;
|
conf->upstream.schema = prev->upstream.schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2033,10 +2010,10 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||||
|
|
||||||
u.url = value[1];
|
u.url = value[1];
|
||||||
u.upstream = 1;
|
u.no_resolve = 1;
|
||||||
|
|
||||||
lcf->upstream_peers = ngx_http_upstream_add(cf, &u);
|
lcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
|
||||||
if (lcf->upstream_peers == NULL) {
|
if (lcf->upstream.upstream == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2084,3 +2061,29 @@ ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, void *data)
|
|||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ngx_http_fastcgi_upstream_max_fails_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf)
|
||||||
|
{
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"fastcgi_upstream_max_fails\" is not supported, "
|
||||||
|
"use the \"max_fails\" parameter of the \"server\" directive ",
|
||||||
|
"inside the \"upstream\" block");
|
||||||
|
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf)
|
||||||
|
{
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"fastcgi_upstream_fail_timeout\" is not supported, "
|
||||||
|
"use the \"fail_timeout\" parameter of the \"server\" directive ",
|
||||||
|
"inside the \"upstream\" block");
|
||||||
|
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_http_upstream_conf_t upstream;
|
ngx_http_upstream_conf_t upstream;
|
||||||
ngx_peers_t *peers;
|
|
||||||
} ngx_http_memcached_loc_conf_t;
|
} ngx_http_memcached_loc_conf_t;
|
||||||
|
|
||||||
|
|
||||||
@ -39,6 +38,11 @@ static char *ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf,
|
|||||||
static char *ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
static char *ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
void *conf);
|
void *conf);
|
||||||
|
|
||||||
|
static char *ngx_http_memcached_upstream_max_fails_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf);
|
||||||
|
static char *ngx_http_memcached_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf);
|
||||||
|
|
||||||
|
|
||||||
static ngx_conf_bitmask_t ngx_http_memcached_next_upstream_masks[] = {
|
static ngx_conf_bitmask_t ngx_http_memcached_next_upstream_masks[] = {
|
||||||
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
|
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
|
||||||
@ -96,16 +100,16 @@ static ngx_command_t ngx_http_memcached_commands[] = {
|
|||||||
|
|
||||||
{ ngx_string("memcached_upstream_max_fails"),
|
{ ngx_string("memcached_upstream_max_fails"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_num_slot,
|
ngx_http_memcached_upstream_max_fails_unsupported,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
0,
|
||||||
offsetof(ngx_http_memcached_loc_conf_t, upstream.max_fails),
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("memcached_upstream_fail_timeout"),
|
{ ngx_string("memcached_upstream_fail_timeout"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_sec_slot,
|
ngx_http_memcached_upstream_fail_timeout_unsupported,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
0,
|
||||||
offsetof(ngx_http_memcached_loc_conf_t, upstream.fail_timeout),
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
ngx_null_command
|
ngx_null_command
|
||||||
@ -178,8 +182,6 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
u->peer.log = r->connection->log;
|
u->peer.log = r->connection->log;
|
||||||
u->peer.log_error = NGX_ERROR_ERR;
|
u->peer.log_error = NGX_ERROR_ERR;
|
||||||
u->peer.peers = mlcf->peers;
|
|
||||||
u->peer.tries = mlcf->peers->number;
|
|
||||||
#if (NGX_THREADS)
|
#if (NGX_THREADS)
|
||||||
u->peer.lock = &r->connection->lock;
|
u->peer.lock = &r->connection->lock;
|
||||||
#endif
|
#endif
|
||||||
@ -511,13 +513,8 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
|
|||||||
|
|
||||||
conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
|
conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
|
||||||
|
|
||||||
conf->upstream.max_fails = NGX_CONF_UNSET_UINT;
|
|
||||||
conf->upstream.fail_timeout = NGX_CONF_UNSET;
|
|
||||||
|
|
||||||
/* "fastcgi_cyclic_temp_file" is disabled */
|
|
||||||
conf->upstream.cyclic_temp_file = 0;
|
|
||||||
|
|
||||||
/* the hardcoded values */
|
/* the hardcoded values */
|
||||||
|
conf->upstream.cyclic_temp_file = 0;
|
||||||
conf->upstream.buffering = 0;
|
conf->upstream.buffering = 0;
|
||||||
conf->upstream.ignore_client_abort = 0;
|
conf->upstream.ignore_client_abort = 0;
|
||||||
conf->upstream.send_lowat = 0;
|
conf->upstream.send_lowat = 0;
|
||||||
@ -540,8 +537,6 @@ ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
ngx_http_memcached_loc_conf_t *prev = parent;
|
ngx_http_memcached_loc_conf_t *prev = parent;
|
||||||
ngx_http_memcached_loc_conf_t *conf = child;
|
ngx_http_memcached_loc_conf_t *conf = child;
|
||||||
|
|
||||||
ngx_uint_t i;
|
|
||||||
|
|
||||||
ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
|
ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
|
||||||
prev->upstream.connect_timeout, 60000);
|
prev->upstream.connect_timeout, 60000);
|
||||||
|
|
||||||
@ -566,20 +561,6 @@ ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
|NGX_HTTP_UPSTREAM_FT_OFF;
|
|NGX_HTTP_UPSTREAM_FT_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_conf_merge_uint_value(conf->upstream.max_fails,
|
|
||||||
prev->upstream.max_fails, 1);
|
|
||||||
|
|
||||||
ngx_conf_merge_sec_value(conf->upstream.fail_timeout,
|
|
||||||
prev->upstream.fail_timeout, 10);
|
|
||||||
|
|
||||||
if (conf->peers && conf->peers->number > 1) {
|
|
||||||
for (i = 0; i < conf->peers->number; i++) {
|
|
||||||
conf->peers->peer[i].weight = 1;
|
|
||||||
conf->peers->peer[i].max_fails = conf->upstream.max_fails;
|
|
||||||
conf->peers->peer[i].fail_timeout = conf->upstream.fail_timeout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,16 +583,14 @@ ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||||
|
|
||||||
u.url = value[1];
|
u.url = value[1];
|
||||||
u.uri_part = 1;
|
u.no_resolve = 1;
|
||||||
|
/* u.uri_part = 1; may be used as namespace */
|
||||||
|
|
||||||
if (ngx_parse_url(cf, &u) != NGX_OK) {
|
lcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
|
||||||
if (u.err) {
|
if (lcf->upstream.upstream == NULL) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
return NGX_CONF_ERROR;
|
||||||
"%s in \"%V\"", u.err, &u.url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lcf->peers = u.peers;
|
|
||||||
lcf->upstream.schema.len = sizeof("memcached://") - 1;
|
lcf->upstream.schema.len = sizeof("memcached://") - 1;
|
||||||
lcf->upstream.schema.data = (u_char *) "memcached://";
|
lcf->upstream.schema.data = (u_char *) "memcached://";
|
||||||
|
|
||||||
@ -627,3 +606,29 @@ ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ngx_http_memcached_upstream_max_fails_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf)
|
||||||
|
{
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"memcached_upstream_max_fails\" is not supported, "
|
||||||
|
"use the \"max_fails\" parameter of the \"server\" directive ",
|
||||||
|
"inside the \"upstream\" block");
|
||||||
|
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ngx_http_memcached_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf)
|
||||||
|
{
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"memcached_upstream_fail_timeout\" is not supported, "
|
||||||
|
"use the \"fail_timeout\" parameter of the \"server\" directive ",
|
||||||
|
"inside the \"upstream\" block");
|
||||||
|
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
@ -35,8 +35,6 @@ struct ngx_http_proxy_redirect_s {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_http_upstream_conf_t upstream;
|
ngx_http_upstream_conf_t upstream;
|
||||||
|
|
||||||
ngx_http_upstream_srv_conf_t *upstream_peers;
|
|
||||||
|
|
||||||
ngx_array_t *flushes;
|
ngx_array_t *flushes;
|
||||||
ngx_array_t *body_set_len;
|
ngx_array_t *body_set_len;
|
||||||
ngx_array_t *body_set;
|
ngx_array_t *body_set;
|
||||||
@ -107,6 +105,11 @@ static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||||||
|
|
||||||
static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data);
|
static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data);
|
||||||
|
|
||||||
|
static char *ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf);
|
||||||
|
static char *ngx_http_proxy_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf);
|
||||||
|
|
||||||
|
|
||||||
static ngx_conf_post_t ngx_http_proxy_lowat_post =
|
static ngx_conf_post_t ngx_http_proxy_lowat_post =
|
||||||
{ ngx_http_proxy_lowat_check };
|
{ ngx_http_proxy_lowat_check };
|
||||||
@ -297,16 +300,16 @@ static ngx_command_t ngx_http_proxy_commands[] = {
|
|||||||
|
|
||||||
{ ngx_string("proxy_upstream_max_fails"),
|
{ ngx_string("proxy_upstream_max_fails"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_num_slot,
|
ngx_http_proxy_upstream_max_fails_unsupported,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
0,
|
||||||
offsetof(ngx_http_proxy_loc_conf_t, upstream.max_fails),
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("proxy_upstream_fail_timeout"),
|
{ ngx_string("proxy_upstream_fail_timeout"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_sec_slot,
|
ngx_http_proxy_upstream_fail_timeout_unsupported,
|
||||||
NGX_HTTP_LOC_CONF_OFFSET,
|
0,
|
||||||
offsetof(ngx_http_proxy_loc_conf_t, upstream.fail_timeout),
|
0,
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("proxy_pass_header"),
|
{ ngx_string("proxy_pass_header"),
|
||||||
@ -419,8 +422,6 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
u->peer.log = r->connection->log;
|
u->peer.log = r->connection->log;
|
||||||
u->peer.log_error = NGX_ERROR_ERR;
|
u->peer.log_error = NGX_ERROR_ERR;
|
||||||
u->peer.peers = plcf->upstream_peers->peers;
|
|
||||||
u->peer.tries = plcf->upstream_peers->peers->number;
|
|
||||||
#if (NGX_THREADS)
|
#if (NGX_THREADS)
|
||||||
u->peer.lock = &r->connection->lock;
|
u->peer.lock = &r->connection->lock;
|
||||||
#endif
|
#endif
|
||||||
@ -1498,9 +1499,6 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||||||
conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
|
conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
|
||||||
conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
|
conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
|
||||||
|
|
||||||
conf->upstream.max_fails = NGX_CONF_UNSET_UINT;
|
|
||||||
conf->upstream.fail_timeout = NGX_CONF_UNSET;
|
|
||||||
|
|
||||||
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
|
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
|
||||||
conf->upstream.pass_request_body = NGX_CONF_UNSET;
|
conf->upstream.pass_request_body = NGX_CONF_UNSET;
|
||||||
|
|
||||||
@ -1527,7 +1525,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
uintptr_t *code;
|
uintptr_t *code;
|
||||||
ngx_str_t *header;
|
ngx_str_t *header;
|
||||||
ngx_uint_t i, j;
|
ngx_uint_t i, j;
|
||||||
ngx_peer_t *peer;
|
|
||||||
ngx_array_t hide_headers;
|
ngx_array_t hide_headers;
|
||||||
ngx_keyval_t *src, *s, *h;
|
ngx_keyval_t *src, *s, *h;
|
||||||
ngx_hash_key_t *hk;
|
ngx_hash_key_t *hk;
|
||||||
@ -1660,24 +1657,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
|NGX_HTTP_UPSTREAM_FT_OFF;
|
|NGX_HTTP_UPSTREAM_FT_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_conf_merge_uint_value(conf->upstream.max_fails,
|
|
||||||
prev->upstream.max_fails, 1);
|
|
||||||
|
|
||||||
ngx_conf_merge_sec_value(conf->upstream.fail_timeout,
|
|
||||||
prev->upstream.fail_timeout, 10);
|
|
||||||
|
|
||||||
if (conf->upstream_peers) {
|
|
||||||
peer = conf->upstream_peers->peers->peer;
|
|
||||||
for (i = 0; i < conf->upstream_peers->peers->number; i++) {
|
|
||||||
ngx_conf_init_uint_value(peer[i].weight, 1);
|
|
||||||
peer[i].current_weight = peer[i].weight;
|
|
||||||
ngx_conf_init_uint_value(peer[i].max_fails,
|
|
||||||
conf->upstream.max_fails);
|
|
||||||
ngx_conf_init_value(peer[i].fail_timeout,
|
|
||||||
conf->upstream.fail_timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_conf_merge_path_value(conf->upstream.temp_path,
|
ngx_conf_merge_path_value(conf->upstream.temp_path,
|
||||||
prev->upstream.temp_path,
|
prev->upstream.temp_path,
|
||||||
NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
|
NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
|
||||||
@ -1834,8 +1813,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
|
|
||||||
peers:
|
peers:
|
||||||
|
|
||||||
if (conf->upstream_peers == NULL) {
|
if (conf->upstream.upstream == NULL) {
|
||||||
conf->upstream_peers = prev->upstream_peers;
|
conf->upstream.upstream = prev->upstream.upstream;
|
||||||
|
|
||||||
conf->host_header = prev->host_header;
|
conf->host_header = prev->host_header;
|
||||||
conf->port_text = prev->port_text;
|
conf->port_text = prev->port_text;
|
||||||
@ -2180,11 +2159,11 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
u.url.len = url->len - add;
|
u.url.len = url->len - add;
|
||||||
u.url.data = url->data + add;
|
u.url.data = url->data + add;
|
||||||
u.default_portn = port;
|
u.default_portn = port;
|
||||||
|
u.no_resolve = 1;
|
||||||
u.uri_part = 1;
|
u.uri_part = 1;
|
||||||
u.upstream = 1;
|
|
||||||
|
|
||||||
plcf->upstream_peers = ngx_http_upstream_add(cf, &u);
|
plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
|
||||||
if (plcf->upstream_peers == NULL) {
|
if (plcf->upstream.upstream == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2345,3 +2324,29 @@ ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
|
|||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf)
|
||||||
|
{
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"proxy_upstream_max_fails\" is not supported, "
|
||||||
|
"use the \"max_fails\" parameter of the \"server\" directive ",
|
||||||
|
"inside the \"upstream\" block");
|
||||||
|
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ngx_http_proxy_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
|
||||||
|
ngx_command_t *cmd, void *conf)
|
||||||
|
{
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"proxy_upstream_fail_timeout\" is not supported, "
|
||||||
|
"use the \"fail_timeout\" parameter of the \"server\" directive ",
|
||||||
|
"inside the \"upstream\" block");
|
||||||
|
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
228
src/http/modules/ngx_http_upstream_ip_hash_module.c
Normal file
228
src/http/modules/ngx_http_upstream_ip_hash_module.c
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Igor Sysoev
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ngx_config.h>
|
||||||
|
#include <ngx_core.h>
|
||||||
|
#include <ngx_http.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* the round robin data must be first */
|
||||||
|
ngx_http_upstream_rr_peer_data_t rrp;
|
||||||
|
|
||||||
|
ngx_uint_t hash;
|
||||||
|
|
||||||
|
/* AF_INET only */
|
||||||
|
u_char addr[3];
|
||||||
|
|
||||||
|
u_char tries;
|
||||||
|
|
||||||
|
ngx_event_get_peer_pt get_rr_peer;
|
||||||
|
} ngx_http_upstream_ip_hash_peer_data_t;
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
|
||||||
|
ngx_http_upstream_srv_conf_t *us);
|
||||||
|
static ngx_int_t ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc,
|
||||||
|
void *data);
|
||||||
|
static char *ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
|
void *conf);
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_command_t ngx_http_upstream_ip_hash_commands[] = {
|
||||||
|
|
||||||
|
{ ngx_string("ip_hash"),
|
||||||
|
NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,
|
||||||
|
ngx_http_upstream_ip_hash,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL },
|
||||||
|
|
||||||
|
ngx_null_command
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_http_module_t ngx_http_upstream_ip_hash_module_ctx = {
|
||||||
|
NULL, /* preconfiguration */
|
||||||
|
NULL, /* postconfiguration */
|
||||||
|
|
||||||
|
NULL, /* create main configuration */
|
||||||
|
NULL, /* init main configuration */
|
||||||
|
|
||||||
|
NULL, /* create server configuration */
|
||||||
|
NULL, /* merge server configuration */
|
||||||
|
|
||||||
|
NULL, /* create location configuration */
|
||||||
|
NULL /* merge location configuration */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ngx_module_t ngx_http_upstream_ip_hash_module = {
|
||||||
|
NGX_MODULE_V1,
|
||||||
|
&ngx_http_upstream_ip_hash_module_ctx, /* module context */
|
||||||
|
ngx_http_upstream_ip_hash_commands, /* module directives */
|
||||||
|
NGX_HTTP_MODULE, /* module type */
|
||||||
|
NULL, /* init master */
|
||||||
|
NULL, /* init module */
|
||||||
|
NULL, /* init process */
|
||||||
|
NULL, /* init thread */
|
||||||
|
NULL, /* exit thread */
|
||||||
|
NULL, /* exit process */
|
||||||
|
NULL, /* exit master */
|
||||||
|
NGX_MODULE_V1_PADDING
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ngx_int_t
|
||||||
|
ngx_http_upstream_init_ip_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
|
||||||
|
{
|
||||||
|
if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
us->peer.init = ngx_http_upstream_init_ip_hash_peer;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
|
||||||
|
ngx_http_upstream_srv_conf_t *us)
|
||||||
|
{
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
ngx_http_upstream_ip_hash_peer_data_t *iphp;
|
||||||
|
|
||||||
|
iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t));
|
||||||
|
if (iphp == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->upstream->peer.data = &iphp->rrp;
|
||||||
|
|
||||||
|
if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer;
|
||||||
|
|
||||||
|
/* AF_INET only */
|
||||||
|
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||||
|
iphp->addr[0] = (u_char) ((sin->sin_addr.s_addr >> 24) & 0xff);
|
||||||
|
iphp->addr[1] = (u_char) ((sin->sin_addr.s_addr >> 16) & 0xff);
|
||||||
|
iphp->addr[2] = (u_char) ((sin->sin_addr.s_addr >> 8) & 0xff);
|
||||||
|
|
||||||
|
iphp->hash = 89;
|
||||||
|
iphp->tries = 0;
|
||||||
|
iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
|
||||||
|
{
|
||||||
|
ngx_http_upstream_ip_hash_peer_data_t *iphp = data;
|
||||||
|
|
||||||
|
time_t now;
|
||||||
|
uintptr_t m;
|
||||||
|
ngx_uint_t i, n, p, hash;
|
||||||
|
ngx_http_upstream_rr_peer_t *peer;
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||||
|
"get ip hash peer, try: %ui", pc->tries);
|
||||||
|
|
||||||
|
/* TODO: cached */
|
||||||
|
|
||||||
|
if (iphp->tries > 20 || iphp->rrp.peers->number == 1) {
|
||||||
|
return iphp->get_rr_peer(pc, &iphp->rrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
now = ngx_time();
|
||||||
|
|
||||||
|
pc->cached = 0;
|
||||||
|
pc->connection = NULL;
|
||||||
|
|
||||||
|
hash = iphp->hash;
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
hash = (hash * 113 + iphp->addr[i]) % 6271;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = hash % iphp->rrp.peers->number;
|
||||||
|
|
||||||
|
n = p / (8 * sizeof(uintptr_t));
|
||||||
|
m = 1 << p % (8 * sizeof(uintptr_t));
|
||||||
|
|
||||||
|
if (!(iphp->rrp.tried[n] & m)) {
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||||
|
"get ip hash peer, hash: %ui %04XA", p, m);
|
||||||
|
|
||||||
|
peer = &iphp->rrp.peers->peer[p];
|
||||||
|
|
||||||
|
/* ngx_lock_mutex(iphp->rrp.peers->mutex); */
|
||||||
|
|
||||||
|
if (!peer->down) {
|
||||||
|
|
||||||
|
if (peer->max_fails == 0 || peer->fails < peer->max_fails) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now - peer->accessed > peer->fail_timeout) {
|
||||||
|
peer->fails = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
iphp->rrp.tried[n] |= m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
|
||||||
|
|
||||||
|
pc->tries--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++iphp->tries >= 20) {
|
||||||
|
return iphp->get_rr_peer(pc, &iphp->rrp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pc->sockaddr = peer->sockaddr;
|
||||||
|
pc->socklen = peer->socklen;
|
||||||
|
pc->name = &peer->name;
|
||||||
|
#if (NGX_SSL)
|
||||||
|
pc->ssl_session = peer->ssl_session;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
|
||||||
|
|
||||||
|
iphp->rrp.tried[n] |= m;
|
||||||
|
iphp->hash = hash;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
|
{
|
||||||
|
ngx_http_upstream_srv_conf_t *uscf;
|
||||||
|
|
||||||
|
uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
|
||||||
|
|
||||||
|
uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
|
||||||
|
|
||||||
|
uscf->flags = NGX_HTTP_UPSTREAM_CREATE
|
||||||
|
|NGX_HTTP_UPSTREAM_MAX_FAILS
|
||||||
|
|NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
|
||||||
|
|NGX_HTTP_UPSTREAM_DOWN;
|
||||||
|
|
||||||
|
return NGX_CONF_OK;
|
||||||
|
}
|
@ -32,6 +32,7 @@ typedef u_char *(*ngx_http_log_handler_pt)(ngx_http_request_t *r,
|
|||||||
#include <ngx_http_variables.h>
|
#include <ngx_http_variables.h>
|
||||||
#include <ngx_http_request.h>
|
#include <ngx_http_request.h>
|
||||||
#include <ngx_http_upstream.h>
|
#include <ngx_http_upstream.h>
|
||||||
|
#include <ngx_http_upstream_round_robin.h>
|
||||||
#include <ngx_http_config.h>
|
#include <ngx_http_config.h>
|
||||||
#include <ngx_http_busy_lock.h>
|
#include <ngx_http_busy_lock.h>
|
||||||
#include <ngx_http_core_module.h>
|
#include <ngx_http_core_module.h>
|
||||||
|
@ -2409,9 +2409,9 @@ static u_char *
|
|||||||
ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
|
ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
|
||||||
u_char *buf, size_t len)
|
u_char *buf, size_t len)
|
||||||
{
|
{
|
||||||
u_char *p;
|
char *uri_separator;
|
||||||
ngx_http_upstream_t *u;
|
u_char *p;
|
||||||
ngx_peer_connection_t *peer;
|
ngx_http_upstream_t *u;
|
||||||
|
|
||||||
if (r->server_name.data) {
|
if (r->server_name.data) {
|
||||||
p = ngx_snprintf(buf, len, ", server: %V", &r->server_name);
|
p = ngx_snprintf(buf, len, ", server: %V", &r->server_name);
|
||||||
@ -2451,14 +2451,19 @@ ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
|
|||||||
|
|
||||||
u = sr->upstream;
|
u = sr->upstream;
|
||||||
|
|
||||||
if (u) {
|
if (u && u->peer.name) {
|
||||||
peer = &u->peer;
|
|
||||||
|
uri_separator = "";
|
||||||
|
|
||||||
|
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||||
|
if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
|
||||||
|
uri_separator = ":";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
|
p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
|
||||||
&u->conf->schema,
|
&u->conf->schema, u->peer.name,
|
||||||
&peer->peers->peer[peer->cur_peer].name,
|
uri_separator, &u->uri);
|
||||||
peer->peers->peer[peer->cur_peer].uri_separator,
|
|
||||||
&u->uri);
|
|
||||||
len -= p - buf;
|
len -= p - buf;
|
||||||
buf = p;
|
buf = p;
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,6 @@ static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
|
|||||||
static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *,
|
static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *,
|
||||||
ngx_http_upstream_t *u, ngx_connection_t *c);
|
ngx_http_upstream_t *u, ngx_connection_t *c);
|
||||||
static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c);
|
static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c);
|
||||||
static void ngx_http_upstream_ssl_shutdown(ngx_connection_t *c,
|
|
||||||
ngx_peer_t *peer);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -215,7 +213,7 @@ static ngx_command_t ngx_http_upstream_commands[] = {
|
|||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("server"),
|
{ ngx_string("server"),
|
||||||
NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
|
NGX_HTTP_UPS_CONF|NGX_CONF_1MORE,
|
||||||
ngx_http_upstream_server,
|
ngx_http_upstream_server,
|
||||||
NGX_HTTP_SRV_CONF_OFFSET,
|
NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
0,
|
0,
|
||||||
@ -308,12 +306,15 @@ ngx_http_upstream_init(ngx_http_request_t *r)
|
|||||||
u->request_bufs = r->request_body->bufs;
|
u->request_bufs = r->request_body->bufs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->create_request(r) != NGX_OK) {
|
if (u->conf->upstream->peer.init(r, u->conf->upstream) != NGX_OK) {
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->peer.log = r->connection->log;
|
if (u->create_request(r) != NGX_OK) {
|
||||||
|
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
@ -326,7 +327,7 @@ ngx_http_upstream_init(ngx_http_request_t *r)
|
|||||||
|
|
||||||
u->writer.pool = r->pool;
|
u->writer.pool = r->pool;
|
||||||
|
|
||||||
if (ngx_array_init(&u->states, r->pool, u->peer.peers->number,
|
if (ngx_array_init(&u->states, r->pool, 1,
|
||||||
sizeof(ngx_http_upstream_state_t))
|
sizeof(ngx_http_upstream_state_t))
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
@ -528,7 +529,7 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->state->peer = &u->peer.peers->peer[u->peer.cur_peer].name;
|
u->state->peer = u->peer.name;
|
||||||
|
|
||||||
if (rc == NGX_BUSY) {
|
if (rc == NGX_BUSY) {
|
||||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams");
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams");
|
||||||
@ -617,8 +618,7 @@ static void
|
|||||||
ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
|
ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
|
||||||
ngx_http_upstream_t *u, ngx_connection_t *c)
|
ngx_http_upstream_t *u, ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_peer_t *peer;
|
|
||||||
|
|
||||||
if (ngx_ssl_create_connection(u->conf->ssl, c,
|
if (ngx_ssl_create_connection(u->conf->ssl, c,
|
||||||
NGX_SSL_BUFFER|NGX_SSL_CLIENT)
|
NGX_SSL_BUFFER|NGX_SSL_CLIENT)
|
||||||
@ -632,9 +632,7 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
|
|||||||
c->sendfile = 0;
|
c->sendfile = 0;
|
||||||
u->output.sendfile = 0;
|
u->output.sendfile = 0;
|
||||||
|
|
||||||
peer = &u->peer.peers->peer[u->peer.cur_peer];
|
if (ngx_ssl_set_session(c, u->peer.ssl_session) != NGX_OK) {
|
||||||
|
|
||||||
if (ngx_ssl_set_session(c, peer->ssl_session) != NGX_OK) {
|
|
||||||
ngx_http_upstream_finalize_request(r, u,
|
ngx_http_upstream_finalize_request(r, u,
|
||||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
return;
|
return;
|
||||||
@ -664,6 +662,8 @@ ngx_http_upstream_ssl_handshake(ngx_connection_t *c)
|
|||||||
|
|
||||||
if (c->ssl->handshaked) {
|
if (c->ssl->handshaked) {
|
||||||
|
|
||||||
|
u->peer.save_session(&u->peer, u->peer.data);
|
||||||
|
|
||||||
c->write->handler = ngx_http_upstream_send_request_handler;
|
c->write->handler = ngx_http_upstream_send_request_handler;
|
||||||
c->read->handler = ngx_http_upstream_process_header;
|
c->read->handler = ngx_http_upstream_process_header;
|
||||||
|
|
||||||
@ -972,7 +972,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
n = u->peer.connection->recv(u->peer.connection, u->buffer.last,
|
n = u->peer.connection->recv(u->peer.connection, u->buffer.last,
|
||||||
u->buffer.end - u->buffer.last);
|
u->buffer.end - u->buffer.last);
|
||||||
|
|
||||||
if (n == NGX_AGAIN) {
|
if (n == NGX_AGAIN) {
|
||||||
#if 0
|
#if 0
|
||||||
@ -1585,7 +1585,7 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_uint_t do_write;
|
ngx_uint_t do_write;
|
||||||
ngx_connection_t *c, *client;
|
ngx_connection_t *c, *downstream, *upstream;
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
ngx_http_upstream_t *u;
|
ngx_http_upstream_t *u;
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
@ -1618,7 +1618,8 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
client = r->connection;
|
downstream = r->connection;
|
||||||
|
upstream = u->peer.connection;
|
||||||
|
|
||||||
b = &u->buffer;
|
b = &u->buffer;
|
||||||
|
|
||||||
@ -1633,7 +1634,7 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||||||
if (u->out_bufs || u->busy_bufs) {
|
if (u->out_bufs || u->busy_bufs) {
|
||||||
rc = ngx_http_output_filter(r, u->out_bufs);
|
rc = ngx_http_output_filter(r, u->out_bufs);
|
||||||
|
|
||||||
if (client->destroyed) {
|
if (downstream->destroyed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1649,8 +1650,8 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||||||
if (u->busy_bufs == NULL) {
|
if (u->busy_bufs == NULL) {
|
||||||
|
|
||||||
if (u->length == 0
|
if (u->length == 0
|
||||||
|| u->peer.connection->read->eof
|
|| upstream->read->eof
|
||||||
|| u->peer.connection->read->error)
|
|| upstream->read->error)
|
||||||
{
|
{
|
||||||
ngx_http_upstream_finalize_request(r, u, 0);
|
ngx_http_upstream_finalize_request(r, u, 0);
|
||||||
return;
|
return;
|
||||||
@ -1667,9 +1668,9 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||||||
size = u->length;
|
size = u->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size && u->peer.connection->read->ready) {
|
if (size && upstream->read->ready) {
|
||||||
|
|
||||||
n = u->peer.connection->recv(u->peer.connection, b->last, size);
|
n = upstream->recv(upstream, b->last, size);
|
||||||
|
|
||||||
if (n == NGX_AGAIN) {
|
if (n == NGX_AGAIN) {
|
||||||
break;
|
break;
|
||||||
@ -1690,8 +1691,8 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->data == r) {
|
if (downstream->data == r) {
|
||||||
if (ngx_handle_write_event(client->write, clcf->send_lowat)
|
if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
|
||||||
== NGX_ERROR)
|
== NGX_ERROR)
|
||||||
{
|
{
|
||||||
ngx_http_upstream_finalize_request(r, u, 0);
|
ngx_http_upstream_finalize_request(r, u, 0);
|
||||||
@ -1699,23 +1700,23 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->write->active) {
|
if (downstream->write->active) {
|
||||||
ngx_add_timer(client->write, clcf->send_timeout);
|
ngx_add_timer(downstream->write, clcf->send_timeout);
|
||||||
|
|
||||||
} else if (client->write->timer_set) {
|
} else if (downstream->write->timer_set) {
|
||||||
ngx_del_timer(client->write);
|
ngx_del_timer(downstream->write);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_handle_read_event(u->peer.connection->read, 0) == NGX_ERROR) {
|
if (ngx_handle_read_event(upstream->read, 0) == NGX_ERROR) {
|
||||||
ngx_http_upstream_finalize_request(r, u, 0);
|
ngx_http_upstream_finalize_request(r, u, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->peer.connection->read->active) {
|
if (upstream->read->active) {
|
||||||
ngx_add_timer(u->peer.connection->read, u->conf->read_timeout);
|
ngx_add_timer(upstream->read, u->conf->read_timeout);
|
||||||
|
|
||||||
} else if (u->peer.connection->read->timer_set) {
|
} else if (upstream->read->timer_set) {
|
||||||
ngx_del_timer(u->peer.connection->read);
|
ngx_del_timer(upstream->read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1922,22 +1923,22 @@ static void
|
|||||||
ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
||||||
ngx_uint_t ft_type)
|
ngx_uint_t ft_type)
|
||||||
{
|
{
|
||||||
ngx_uint_t status, down;
|
ngx_uint_t status, state;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
"http next upstream, %xD", ft_type);
|
"http next upstream, %xi", ft_type);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
|
ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) {
|
if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) {
|
||||||
down = 0;
|
state = NGX_PEER_NEXT;
|
||||||
} else {
|
} else {
|
||||||
down = 1;
|
state = NGX_PEER_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_event_connect_peer_failed(&u->peer, down);
|
u->peer.free(&u->peer, u->peer.data, state);
|
||||||
|
|
||||||
if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) {
|
if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) {
|
||||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT,
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT,
|
||||||
@ -2003,11 +2004,15 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
|||||||
"close http upstream connection: %d",
|
"close http upstream connection: %d",
|
||||||
u->peer.connection->fd);
|
u->peer.connection->fd);
|
||||||
#if (NGX_HTTP_SSL)
|
#if (NGX_HTTP_SSL)
|
||||||
|
|
||||||
if (u->peer.connection->ssl) {
|
if (u->peer.connection->ssl) {
|
||||||
ngx_http_upstream_ssl_shutdown(u->peer.connection,
|
u->peer.connection->ssl->no_wait_shutdown = 1;
|
||||||
&u->peer.peers->peer[u->peer.cur_peer]);
|
u->peer.connection->ssl->no_send_shutdown = 1;
|
||||||
|
|
||||||
|
(void) ngx_ssl_shutdown(u->peer.connection);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ngx_close_connection(u->peer.connection);
|
ngx_close_connection(u->peer.connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2054,19 +2059,32 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
|||||||
|
|
||||||
u->finalize_request(r, rc);
|
u->finalize_request(r, rc);
|
||||||
|
|
||||||
|
u->peer.free(&u->peer, u->peer.data, 0);
|
||||||
|
|
||||||
if (u->peer.connection) {
|
if (u->peer.connection) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
|
||||||
"close http upstream connection: %d",
|
|
||||||
u->peer.connection->fd);
|
|
||||||
#if (NGX_HTTP_SSL)
|
#if (NGX_HTTP_SSL)
|
||||||
|
|
||||||
/* TODO: do not shutdown persistent connection */
|
/* TODO: do not shutdown persistent connection */
|
||||||
|
|
||||||
if (u->peer.connection->ssl) {
|
if (u->peer.connection->ssl) {
|
||||||
ngx_http_upstream_ssl_shutdown(u->peer.connection,
|
|
||||||
&u->peer.peers->peer[u->peer.cur_peer]);
|
/*
|
||||||
|
* We send the "close notify" shutdown alert to the upstream only
|
||||||
|
* and do not wait its "close notify" shutdown alert.
|
||||||
|
* It is acceptable according to the TLS standard.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u->peer.connection->ssl->no_wait_shutdown = 1;
|
||||||
|
|
||||||
|
(void) ngx_ssl_shutdown(u->peer.connection);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"close http upstream connection: %d",
|
||||||
|
u->peer.connection->fd);
|
||||||
|
|
||||||
ngx_close_connection(u->peer.connection);
|
ngx_close_connection(u->peer.connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2105,35 +2123,6 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (NGX_HTTP_SSL)
|
|
||||||
|
|
||||||
static void
|
|
||||||
ngx_http_upstream_ssl_shutdown(ngx_connection_t *c, ngx_peer_t *peer)
|
|
||||||
{
|
|
||||||
/* lock peer mutex */
|
|
||||||
|
|
||||||
if (peer->ssl_session) {
|
|
||||||
ngx_ssl_free_session(peer->ssl_session);
|
|
||||||
}
|
|
||||||
|
|
||||||
peer->ssl_session = ngx_ssl_get_session(c);
|
|
||||||
|
|
||||||
/* unlock peer mutex */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We send the "close notify" shutdown alert to the upstream only
|
|
||||||
* and do not wait its "close notify" shutdown alert.
|
|
||||||
* It is acceptable according to the TLS standard.
|
|
||||||
*/
|
|
||||||
|
|
||||||
c->ssl->no_wait_shutdown = 1;
|
|
||||||
|
|
||||||
(void) ngx_ssl_shutdown(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
ngx_uint_t offset)
|
ngx_uint_t offset)
|
||||||
@ -2595,31 +2584,41 @@ ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
|
|||||||
static char *
|
static char *
|
||||||
ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
||||||
{
|
{
|
||||||
char *rv;
|
char *rv;
|
||||||
void *mconf;
|
void *mconf;
|
||||||
ngx_str_t *value;
|
ngx_str_t *value;
|
||||||
ngx_url_t u;
|
ngx_url_t u;
|
||||||
ngx_uint_t i, j, m, n;
|
ngx_uint_t m;
|
||||||
ngx_conf_t pcf;
|
ngx_conf_t pcf;
|
||||||
ngx_peers_t **peers;
|
ngx_http_module_t *module;
|
||||||
ngx_http_module_t *module;
|
ngx_http_conf_ctx_t *ctx, *http_ctx;
|
||||||
ngx_http_conf_ctx_t *ctx;
|
ngx_http_upstream_srv_conf_t *uscf;
|
||||||
ngx_http_upstream_srv_conf_t *uscf;
|
|
||||||
|
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||||
|
|
||||||
|
value = cf->args->elts;
|
||||||
|
u.host = value[1];
|
||||||
|
u.upstream = 1;
|
||||||
|
u.no_resolve = 1;
|
||||||
|
|
||||||
|
uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE
|
||||||
|
|NGX_HTTP_UPSTREAM_WEIGHT
|
||||||
|
|NGX_HTTP_UPSTREAM_MAX_FAILS
|
||||||
|
|NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
|
||||||
|
|NGX_HTTP_UPSTREAM_DOWN
|
||||||
|
|NGX_HTTP_UPSTREAM_BACKUP);
|
||||||
|
if (uscf == NULL) {
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
|
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
http_ctx = cf->ctx;
|
||||||
|
ctx->main_conf = http_ctx->main_conf;
|
||||||
value = cf->args->elts;
|
|
||||||
u.host = value[1];
|
|
||||||
|
|
||||||
uscf = ngx_http_upstream_add(cf, &u);
|
|
||||||
if (uscf == NULL) {
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the upstream{}'s srv_conf */
|
/* the upstream{}'s srv_conf */
|
||||||
|
|
||||||
@ -2630,6 +2629,8 @@ ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
|||||||
|
|
||||||
ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf;
|
ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf;
|
||||||
|
|
||||||
|
uscf->srv_conf = ctx->srv_conf;
|
||||||
|
|
||||||
|
|
||||||
/* the upstream{}'s loc_conf */
|
/* the upstream{}'s loc_conf */
|
||||||
|
|
||||||
@ -2645,6 +2646,15 @@ ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
|||||||
|
|
||||||
module = ngx_modules[m]->ctx;
|
module = ngx_modules[m]->ctx;
|
||||||
|
|
||||||
|
if (module->create_srv_conf) {
|
||||||
|
mconf = module->create_srv_conf(cf);
|
||||||
|
if (mconf == NULL) {
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf;
|
||||||
|
}
|
||||||
|
|
||||||
if (module->create_loc_conf) {
|
if (module->create_loc_conf) {
|
||||||
mconf = module->create_loc_conf(cf);
|
mconf = module->create_loc_conf(cf);
|
||||||
if (mconf == NULL) {
|
if (mconf == NULL) {
|
||||||
@ -2676,34 +2686,6 @@ ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
|||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
peers = uscf->servers->elts;
|
|
||||||
|
|
||||||
if (uscf->servers->nelts == 1) {
|
|
||||||
uscf->peers = peers[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < uscf->servers->nelts; i++) {
|
|
||||||
n += peers[i]->number;
|
|
||||||
}
|
|
||||||
|
|
||||||
uscf->peers = ngx_pcalloc(cf->pool,
|
|
||||||
sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (n - 1));
|
|
||||||
if (uscf->peers == NULL) {
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
uscf->peers->number = n;
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < uscf->servers->nelts; i++) {
|
|
||||||
for (j = 0; j < peers[i]->number; j++) {
|
|
||||||
uscf->peers->peer[n++] = peers[i]->peer[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2713,24 +2695,28 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
{
|
{
|
||||||
ngx_http_upstream_srv_conf_t *uscf = conf;
|
ngx_http_upstream_srv_conf_t *uscf = conf;
|
||||||
|
|
||||||
ngx_str_t *value;
|
time_t fail_timeout;
|
||||||
ngx_url_t u;
|
ngx_str_t *value, s;
|
||||||
ngx_int_t weight;
|
ngx_url_t u;
|
||||||
ngx_uint_t i;
|
ngx_int_t weight, max_fails;
|
||||||
ngx_peers_t **peers;
|
ngx_uint_t i;
|
||||||
|
ngx_http_upstream_server_t *us;
|
||||||
|
|
||||||
if (uscf->servers == NULL) {
|
if (uscf->servers == NULL) {
|
||||||
uscf->servers = ngx_array_create(cf->pool, 4, sizeof(ngx_peers_t *));
|
uscf->servers = ngx_array_create(cf->pool, 4,
|
||||||
|
sizeof(ngx_http_upstream_server_t));
|
||||||
if (uscf->servers == NULL) {
|
if (uscf->servers == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
peers = ngx_array_push(uscf->servers);
|
us = ngx_array_push(uscf->servers);
|
||||||
if (peers == NULL) {
|
if (us == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
|
||||||
|
|
||||||
value = cf->args->elts;
|
value = cf->args->elts;
|
||||||
|
|
||||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||||
@ -2748,51 +2734,100 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
weight = 1;
|
weight = 1;
|
||||||
|
max_fails = 1;
|
||||||
|
fail_timeout = 10;
|
||||||
|
|
||||||
if (cf->args->nelts == 3) {
|
for (i = 2; i < cf->args->nelts; i++) {
|
||||||
|
|
||||||
value = &value[2];
|
if (ngx_strncmp(value[i].data, "weight=", 7) == 0) {
|
||||||
|
|
||||||
if (ngx_strncmp(value->data, "weight=", 7) == 0) {
|
if (!(uscf->flags & NGX_HTTP_UPSTREAM_WEIGHT)) {
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
|
||||||
weight = ngx_atoi(&value->data[7], value->len - 7);
|
weight = ngx_atoi(&value[i].data[7], value[i].len - 7);
|
||||||
|
|
||||||
if (weight == NGX_ERROR || weight == 0) {
|
if (weight == NGX_ERROR || weight == 0) {
|
||||||
goto invalid;
|
goto invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
continue;
|
||||||
goto invalid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) {
|
||||||
|
|
||||||
|
if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_FAILS)) {
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10);
|
||||||
|
|
||||||
|
if (max_fails == NGX_ERROR) {
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) {
|
||||||
|
|
||||||
|
if (!(uscf->flags & NGX_HTTP_UPSTREAM_FAIL_TIMEOUT)) {
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
s.len = value[i].len - 13;
|
||||||
|
s.data = &value[i].data[13];
|
||||||
|
|
||||||
|
fail_timeout = ngx_parse_time(&s, 1);
|
||||||
|
|
||||||
|
if (fail_timeout < 0) {
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_strncmp(value[i].data, "down", 4) == 0) {
|
||||||
|
|
||||||
|
if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) {
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
us->down = 1;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < u.peers->number; i++) {
|
us->addrs = u.addrs;
|
||||||
u.peers->peer[i].weight = weight;
|
us->naddrs = u.naddrs;
|
||||||
u.peers->peer[i].current_weight = weight;
|
us->weight = weight;
|
||||||
u.peers->peer[i].max_fails = NGX_CONF_UNSET_UINT;
|
us->max_fails = max_fails;
|
||||||
u.peers->peer[i].fail_timeout = NGX_CONF_UNSET;
|
us->fail_timeout = fail_timeout;
|
||||||
}
|
|
||||||
|
|
||||||
*peers = u.peers;
|
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
|
|
||||||
invalid:
|
invalid:
|
||||||
|
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", value);
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"invalid parameter \"%V\"", &value[i]);
|
||||||
|
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_http_upstream_srv_conf_t *
|
ngx_http_upstream_srv_conf_t *
|
||||||
ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u)
|
ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
|
||||||
{
|
{
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
|
ngx_http_upstream_server_t *us;
|
||||||
ngx_http_upstream_srv_conf_t *uscf, **uscfp;
|
ngx_http_upstream_srv_conf_t *uscf, **uscfp;
|
||||||
ngx_http_upstream_main_conf_t *umcf;
|
ngx_http_upstream_main_conf_t *umcf;
|
||||||
|
|
||||||
if (u->upstream) {
|
if (!(flags & NGX_HTTP_UPSTREAM_CREATE)) {
|
||||||
|
|
||||||
if (ngx_parse_url(cf, u) != NGX_OK) {
|
if (ngx_parse_url(cf, u) != NGX_OK) {
|
||||||
if (u->err) {
|
if (u->err) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
@ -2801,17 +2836,6 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->peers) {
|
|
||||||
uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t));
|
|
||||||
if (uscf == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uscf->peers = u->peers;
|
|
||||||
|
|
||||||
return uscf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module);
|
umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module);
|
||||||
@ -2819,15 +2843,28 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
uscfp = umcf->upstreams.elts;
|
uscfp = umcf->upstreams.elts;
|
||||||
|
|
||||||
for (i = 0; i < umcf->upstreams.nelts; i++) {
|
for (i = 0; i < umcf->upstreams.nelts; i++) {
|
||||||
if (uscfp[i]->host.len != u->host.len) {
|
if (uscfp[i]->host.len != u->host.len
|
||||||
|
|| ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len)
|
||||||
|
!= 0)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len)
|
if ((flags & NGX_HTTP_UPSTREAM_CREATE)
|
||||||
== 0)
|
&& (uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE))
|
||||||
{
|
{
|
||||||
return uscfp[i];
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"duplicate upstream \"%V\"", &u->host);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uscfp[i]->port == 0 && u->portn && !u->no_port) {
|
||||||
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
|
"upstream \"%V\" port %d is ignored",
|
||||||
|
&u->host, u->portn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return uscfp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t));
|
uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t));
|
||||||
@ -2835,10 +2872,29 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uscf->flags = flags;
|
||||||
uscf->host = u->host;
|
uscf->host = u->host;
|
||||||
uscf->file_name = cf->conf_file->file.name;
|
uscf->file_name = cf->conf_file->file.name;
|
||||||
uscf->line = cf->conf_file->line;
|
uscf->line = cf->conf_file->line;
|
||||||
uscf->port = u->default_portn;
|
uscf->port = u->portn;
|
||||||
|
|
||||||
|
if (u->naddrs == 1) {
|
||||||
|
uscf->servers = ngx_array_create(cf->pool, 1,
|
||||||
|
sizeof(ngx_http_upstream_server_t));
|
||||||
|
if (uscf->servers == NULL) {
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
us = ngx_array_push(uscf->servers);
|
||||||
|
if (us == NULL) {
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
|
||||||
|
|
||||||
|
us->addrs = u->addrs;
|
||||||
|
us->naddrs = u->naddrs;
|
||||||
|
}
|
||||||
|
|
||||||
uscfp = ngx_array_push(&umcf->upstreams);
|
uscfp = ngx_array_push(&umcf->upstreams);
|
||||||
if (uscfp == NULL) {
|
if (uscfp == NULL) {
|
||||||
@ -2881,32 +2937,25 @@ ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf)
|
|||||||
ngx_array_t headers_in;
|
ngx_array_t headers_in;
|
||||||
ngx_hash_key_t *hk;
|
ngx_hash_key_t *hk;
|
||||||
ngx_hash_init_t hash;
|
ngx_hash_init_t hash;
|
||||||
|
ngx_http_upstream_init_pt init;
|
||||||
ngx_http_upstream_header_t *header;
|
ngx_http_upstream_header_t *header;
|
||||||
ngx_http_upstream_srv_conf_t **uscfp;
|
ngx_http_upstream_srv_conf_t **uscfp;
|
||||||
|
|
||||||
uscfp = umcf->upstreams.elts;
|
uscfp = umcf->upstreams.elts;
|
||||||
|
|
||||||
for (i = 0; i < umcf->upstreams.nelts; i++) {
|
for (i = 0; i < umcf->upstreams.nelts; i++) {
|
||||||
if (uscfp[i]->peers) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uscfp[i]->peers = ngx_inet_resolve_peer(cf, &uscfp[i]->host,
|
init = uscfp[i]->peer.init_upstream ? uscfp[i]->peer.init_upstream:
|
||||||
uscfp[i]->port);
|
ngx_http_upstream_init_round_robin;
|
||||||
if (uscfp[i]->peers == NULL) {
|
|
||||||
return NGX_CONF_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uscfp[i]->peers == NGX_CONF_ERROR) {
|
if (init(cf, uscfp[i]) != NGX_OK) {
|
||||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
|
||||||
"upstream host \"%V\" is not found in %s:%ui",
|
|
||||||
&uscfp[i]->host, uscfp[i]->file_name.data,
|
|
||||||
uscfp[i]->line);
|
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* upstream_headers_in_hash */
|
||||||
|
|
||||||
if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
|
if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
|
@ -44,23 +44,61 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_hash_t headers_in_hash;
|
ngx_hash_t headers_in_hash;
|
||||||
ngx_array_t upstreams;
|
ngx_array_t upstreams;
|
||||||
/* ngx_http_upstream_srv_conf_t */
|
/* ngx_http_upstream_srv_conf_t */
|
||||||
} ngx_http_upstream_main_conf_t;
|
} ngx_http_upstream_main_conf_t;
|
||||||
|
|
||||||
|
typedef struct ngx_http_upstream_srv_conf_s ngx_http_upstream_srv_conf_t;
|
||||||
|
|
||||||
|
typedef ngx_int_t (*ngx_http_upstream_init_pt)(ngx_conf_t *cf,
|
||||||
|
ngx_http_upstream_srv_conf_t *us);
|
||||||
|
typedef ngx_int_t (*ngx_http_upstream_init_peer_pt)(ngx_http_request_t *r,
|
||||||
|
ngx_http_upstream_srv_conf_t *us);
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_peers_t *peers;
|
ngx_http_upstream_init_pt init_upstream;
|
||||||
|
ngx_http_upstream_init_peer_pt init;
|
||||||
|
void *data;
|
||||||
|
} ngx_http_upstream_peer_t;
|
||||||
|
|
||||||
ngx_array_t *servers;
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_peer_addr_t *addrs;
|
||||||
|
ngx_uint_t naddrs;
|
||||||
|
ngx_uint_t weight;
|
||||||
|
ngx_uint_t max_fails;
|
||||||
|
time_t fail_timeout;
|
||||||
|
|
||||||
|
unsigned down:1;
|
||||||
|
unsigned backup:1;
|
||||||
|
} ngx_http_upstream_server_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define NGX_HTTP_UPSTREAM_CREATE 0x0001
|
||||||
|
#define NGX_HTTP_UPSTREAM_WEIGHT 0x0002
|
||||||
|
#define NGX_HTTP_UPSTREAM_MAX_FAILS 0x0004
|
||||||
|
#define NGX_HTTP_UPSTREAM_FAIL_TIMEOUT 0x0008
|
||||||
|
#define NGX_HTTP_UPSTREAM_DOWN 0x0010
|
||||||
|
#define NGX_HTTP_UPSTREAM_BACKUP 0x0020
|
||||||
|
|
||||||
|
|
||||||
|
struct ngx_http_upstream_srv_conf_s {
|
||||||
|
ngx_http_upstream_peer_t peer;
|
||||||
|
void **srv_conf;
|
||||||
|
|
||||||
|
ngx_array_t *servers; /* ngx_http_upstream_server_t */
|
||||||
|
|
||||||
|
ngx_uint_t flags;
|
||||||
ngx_str_t host;
|
ngx_str_t host;
|
||||||
ngx_str_t file_name;
|
ngx_str_t file_name;
|
||||||
ngx_uint_t line;
|
ngx_uint_t line;
|
||||||
in_port_t port;
|
in_port_t port;
|
||||||
} ngx_http_upstream_srv_conf_t;
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
ngx_http_upstream_srv_conf_t *upstream;
|
||||||
|
|
||||||
ngx_msec_t connect_timeout;
|
ngx_msec_t connect_timeout;
|
||||||
ngx_msec_t send_timeout;
|
ngx_msec_t send_timeout;
|
||||||
ngx_msec_t read_timeout;
|
ngx_msec_t read_timeout;
|
||||||
@ -78,9 +116,6 @@ typedef struct {
|
|||||||
size_t temp_file_write_size_conf;
|
size_t temp_file_write_size_conf;
|
||||||
|
|
||||||
ngx_uint_t next_upstream;
|
ngx_uint_t next_upstream;
|
||||||
ngx_uint_t max_fails;
|
|
||||||
|
|
||||||
time_t fail_timeout;
|
|
||||||
|
|
||||||
ngx_bufs_t bufs;
|
ngx_bufs_t bufs;
|
||||||
|
|
||||||
@ -213,7 +248,11 @@ struct ngx_http_upstream_s {
|
|||||||
|
|
||||||
void ngx_http_upstream_init(ngx_http_request_t *r);
|
void ngx_http_upstream_init(ngx_http_request_t *r);
|
||||||
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
|
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
|
||||||
ngx_url_t *u);
|
ngx_url_t *u, ngx_uint_t flags);
|
||||||
|
|
||||||
|
|
||||||
|
#define ngx_http_conf_upstream_srv_conf(uscf, module) \
|
||||||
|
uscf->srv_conf[module.ctx_index]
|
||||||
|
|
||||||
|
|
||||||
extern ngx_module_t ngx_http_upstream_module;
|
extern ngx_module_t ngx_http_upstream_module;
|
||||||
|
430
src/http/ngx_http_upstream_round_robin.c
Normal file
430
src/http/ngx_http_upstream_round_robin.c
Normal file
@ -0,0 +1,430 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Igor Sysoev
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ngx_config.h>
|
||||||
|
#include <ngx_core.h>
|
||||||
|
#include <ngx_http.h>
|
||||||
|
|
||||||
|
|
||||||
|
ngx_int_t
|
||||||
|
ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
||||||
|
ngx_http_upstream_srv_conf_t *us)
|
||||||
|
{
|
||||||
|
ngx_url_t u;
|
||||||
|
ngx_uint_t i, j, n;
|
||||||
|
ngx_http_upstream_server_t *server;
|
||||||
|
ngx_http_upstream_rr_peers_t *peers;
|
||||||
|
|
||||||
|
us->peer.init = ngx_http_upstream_init_round_robin_peer;
|
||||||
|
|
||||||
|
if (us->servers) {
|
||||||
|
n = 0;
|
||||||
|
server = us->servers->elts;
|
||||||
|
|
||||||
|
for (i = 0; i < us->servers->nelts; i++) {
|
||||||
|
n += server[i].naddrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
|
||||||
|
+ sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
|
||||||
|
if (peers == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
peers->number = n;
|
||||||
|
peers->name = &us->host;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < us->servers->nelts; i++) {
|
||||||
|
for (j = 0; j < server[i].naddrs; j++) {
|
||||||
|
peers->peer[n].sockaddr = server[i].addrs[j].sockaddr;
|
||||||
|
peers->peer[n].socklen = server[i].addrs[j].socklen;
|
||||||
|
peers->peer[n].name = server[i].addrs[j].name;
|
||||||
|
peers->peer[n].weight = server[i].weight;
|
||||||
|
peers->peer[n].current_weight = server[i].weight;
|
||||||
|
peers->peer[n].max_fails = server[i].max_fails;
|
||||||
|
peers->peer[n].fail_timeout = server[i].fail_timeout;
|
||||||
|
peers->peer[n].down = server[i].down;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
us->peer.data = peers;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* an upstream implicitly defined by proxy_pass, etc. */
|
||||||
|
|
||||||
|
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||||
|
|
||||||
|
u.host = us->host;
|
||||||
|
u.portn = us->port;
|
||||||
|
|
||||||
|
if (ngx_inet_resolve_host(cf, &u) != NGX_OK) {
|
||||||
|
if (u.err) {
|
||||||
|
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||||
|
"%s in upstream host \"%V\" is not found in %s:%ui",
|
||||||
|
u.err, &us->host, us->file_name.data, us->line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = u.naddrs;
|
||||||
|
|
||||||
|
peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
|
||||||
|
+ sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
|
||||||
|
if (peers == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
peers->number = n;
|
||||||
|
peers->name = &us->host;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < u.naddrs; i++) {
|
||||||
|
peers->peer[n].sockaddr = u.addrs[i].sockaddr;
|
||||||
|
peers->peer[n].socklen = u.addrs[i].socklen;
|
||||||
|
peers->peer[n].name = u.addrs[i].name;
|
||||||
|
peers->peer[n].weight = 1;
|
||||||
|
peers->peer[n].current_weight = 1;
|
||||||
|
peers->peer[n].max_fails = 1;
|
||||||
|
peers->peer[n].fail_timeout = 10;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
us->peer.data = peers;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ngx_int_t
|
||||||
|
ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
|
||||||
|
ngx_http_upstream_srv_conf_t *us)
|
||||||
|
{
|
||||||
|
ngx_uint_t n;
|
||||||
|
ngx_http_upstream_rr_peer_data_t *rrp;
|
||||||
|
|
||||||
|
rrp = r->upstream->peer.data;
|
||||||
|
|
||||||
|
if (rrp == NULL) {
|
||||||
|
rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t));
|
||||||
|
if (rrp == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->upstream->peer.data = rrp;
|
||||||
|
}
|
||||||
|
|
||||||
|
rrp->peers = us->peer.data;
|
||||||
|
rrp->current = 0;
|
||||||
|
|
||||||
|
if (rrp->peers->number <= 8 * sizeof(uintptr_t)) {
|
||||||
|
rrp->tried = &rrp->data;
|
||||||
|
rrp->data = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
|
||||||
|
/ (8 * sizeof(uintptr_t));
|
||||||
|
|
||||||
|
rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t));
|
||||||
|
if (rrp->tried == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;
|
||||||
|
r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
|
||||||
|
r->upstream->peer.tries = rrp->peers->number;
|
||||||
|
#if (NGX_HTTP_SSL)
|
||||||
|
r->upstream->peer.save_session = ngx_http_upstream_save_round_robin_peer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ngx_int_t
|
||||||
|
ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
|
||||||
|
{
|
||||||
|
ngx_http_upstream_rr_peer_data_t *rrp = data;
|
||||||
|
|
||||||
|
time_t now;
|
||||||
|
uintptr_t m;
|
||||||
|
ngx_uint_t i, n;
|
||||||
|
ngx_connection_t *c;
|
||||||
|
ngx_http_upstream_rr_peer_t *peer;
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||||
|
"get rr peer, try: %ui", pc->tries);
|
||||||
|
|
||||||
|
now = ngx_time();
|
||||||
|
|
||||||
|
/* ngx_lock_mutex(rrp->peers->mutex); */
|
||||||
|
|
||||||
|
if (rrp->peers->last_cached) {
|
||||||
|
|
||||||
|
/* cached connection */
|
||||||
|
|
||||||
|
c = rrp->peers->cached[rrp->peers->last_cached];
|
||||||
|
rrp->peers->last_cached--;
|
||||||
|
|
||||||
|
/* ngx_unlock_mutex(ppr->peers->mutex); */
|
||||||
|
|
||||||
|
#if (NGX_THREADS)
|
||||||
|
c->read->lock = c->read->own_lock;
|
||||||
|
c->write->lock = c->write->own_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pc->connection = c;
|
||||||
|
pc->cached = 1;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
pc->cached = 0;
|
||||||
|
pc->connection = NULL;
|
||||||
|
|
||||||
|
if (rrp->peers->number == 1) {
|
||||||
|
peer = &rrp->peers->peer[0];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* there are several peers */
|
||||||
|
|
||||||
|
if (pc->tries == rrp->peers->number) {
|
||||||
|
|
||||||
|
/* it's a first try - get a current peer */
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
rrp->current = rrp->peers->current;
|
||||||
|
|
||||||
|
n = rrp->current / (8 * sizeof(uintptr_t));
|
||||||
|
m = 1 << rrp->current % (8 * sizeof(uintptr_t));
|
||||||
|
|
||||||
|
if (!(rrp->tried[n] & m)) {
|
||||||
|
peer = &rrp->peers->peer[rrp->current];
|
||||||
|
|
||||||
|
if (!peer->down) {
|
||||||
|
|
||||||
|
if (peer->max_fails == 0
|
||||||
|
|| peer->fails < peer->max_fails)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now - peer->accessed > peer->fail_timeout) {
|
||||||
|
peer->fails = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
rrp->tried[n] |= m;
|
||||||
|
}
|
||||||
|
|
||||||
|
pc->tries--;
|
||||||
|
}
|
||||||
|
|
||||||
|
rrp->peers->current++;
|
||||||
|
|
||||||
|
if (rrp->peers->current >= rrp->peers->number) {
|
||||||
|
rrp->peers->current = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pc->tries) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
peer->current_weight--;
|
||||||
|
|
||||||
|
if (peer->current_weight == 0) {
|
||||||
|
peer->current_weight = peer->weight;
|
||||||
|
|
||||||
|
rrp->peers->current++;
|
||||||
|
|
||||||
|
if (rrp->peers->current >= rrp->peers->number) {
|
||||||
|
rrp->peers->current = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for ( ;; ) {
|
||||||
|
n = rrp->current / (8 * sizeof(uintptr_t));
|
||||||
|
m = 1 << rrp->current % (8 * sizeof(uintptr_t));
|
||||||
|
|
||||||
|
if (!(rrp->tried[n] & m)) {
|
||||||
|
|
||||||
|
peer = &rrp->peers->peer[rrp->current];
|
||||||
|
|
||||||
|
if (!peer->down) {
|
||||||
|
|
||||||
|
if (peer->max_fails == 0
|
||||||
|
|| peer->fails < peer->max_fails)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now - peer->accessed > peer->fail_timeout) {
|
||||||
|
peer->fails = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
rrp->tried[n] |= m;
|
||||||
|
}
|
||||||
|
|
||||||
|
pc->tries--;
|
||||||
|
}
|
||||||
|
|
||||||
|
rrp->current++;
|
||||||
|
|
||||||
|
if (rrp->current >= rrp->peers->number) {
|
||||||
|
rrp->current = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pc->tries) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
peer->current_weight--;
|
||||||
|
|
||||||
|
if (peer->current_weight == 0) {
|
||||||
|
peer->current_weight = peer->weight;
|
||||||
|
|
||||||
|
if (rrp->current == rrp->peers->current) {
|
||||||
|
rrp->peers->current++;
|
||||||
|
|
||||||
|
if (rrp->peers->current >= rrp->peers->number) {
|
||||||
|
rrp->peers->current = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rrp->tried[n] |= m;
|
||||||
|
}
|
||||||
|
|
||||||
|
pc->sockaddr = peer->sockaddr;
|
||||||
|
pc->socklen = peer->socklen;
|
||||||
|
pc->name = &peer->name;
|
||||||
|
#if (NGX_SSL)
|
||||||
|
pc->ssl_session = peer->ssl_session;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ngx_unlock_mutex(rrp->peers->mutex); */
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
|
||||||
|
/* all peers failed, mark them as live for quick recovery */
|
||||||
|
|
||||||
|
for (i = 0; i < rrp->peers->number; i++) {
|
||||||
|
rrp->peers->peer[i].fails = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ngx_unlock_mutex(rrp->peers->mutex); */
|
||||||
|
|
||||||
|
pc->name = rrp->peers->name;
|
||||||
|
|
||||||
|
return NGX_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
|
||||||
|
ngx_uint_t state)
|
||||||
|
{
|
||||||
|
ngx_http_upstream_rr_peer_data_t *rrp = data;
|
||||||
|
|
||||||
|
time_t now;
|
||||||
|
ngx_http_upstream_rr_peer_t *peer;
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
||||||
|
"free rr peer %ui %ui", pc->tries, state);
|
||||||
|
|
||||||
|
if (state == 0 && pc->tries == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: NGX_PEER_KEEPALIVE */
|
||||||
|
|
||||||
|
if (rrp->peers->number == 1) {
|
||||||
|
pc->tries = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state & NGX_PEER_FAILED) {
|
||||||
|
now = ngx_time();
|
||||||
|
|
||||||
|
peer = &rrp->peers->peer[rrp->current];
|
||||||
|
|
||||||
|
/* ngx_lock_mutex(rrp->peers->mutex); */
|
||||||
|
|
||||||
|
peer->fails++;
|
||||||
|
peer->accessed = now;
|
||||||
|
|
||||||
|
if (peer->current_weight > 1) {
|
||||||
|
peer->current_weight /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ngx_unlock_mutex(rrp->peers->mutex); */
|
||||||
|
}
|
||||||
|
|
||||||
|
rrp->current++;
|
||||||
|
|
||||||
|
if (rrp->current >= rrp->peers->number) {
|
||||||
|
rrp->current = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pc->tries) {
|
||||||
|
pc->tries--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ngx_unlock_mutex(rrp->peers->mutex); */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_HTTP_SSL)
|
||||||
|
|
||||||
|
void
|
||||||
|
ngx_http_upstream_save_round_robin_peer(ngx_peer_connection_t *pc, void *data)
|
||||||
|
{
|
||||||
|
ngx_http_upstream_rr_peer_data_t *rrp = data;
|
||||||
|
|
||||||
|
ngx_ssl_session_t *ssl_session;
|
||||||
|
ngx_http_upstream_rr_peer_t *peer;
|
||||||
|
|
||||||
|
ssl_session = ngx_ssl_get_session(pc->connection);
|
||||||
|
|
||||||
|
if (ssl_session == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
peer = &rrp->peers->peer[rrp->current];
|
||||||
|
|
||||||
|
/* ngx_lock_mutex(rrp->peers->mutex); */
|
||||||
|
peer->ssl_session = ssl_session;
|
||||||
|
/* ngx_unlock_mutex(rrp->peers->mutex); */
|
||||||
|
|
||||||
|
if (pc->ssl_session) {
|
||||||
|
/* TODO: may block */
|
||||||
|
ngx_ssl_free_session(pc->ssl_session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
77
src/http/ngx_http_upstream_round_robin.h
Normal file
77
src/http/ngx_http_upstream_round_robin.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Igor Sysoev
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
|
||||||
|
#define _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
|
#include <ngx_config.h>
|
||||||
|
#include <ngx_core.h>
|
||||||
|
#include <ngx_http.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct sockaddr *sockaddr;
|
||||||
|
socklen_t socklen;
|
||||||
|
ngx_str_t name;
|
||||||
|
|
||||||
|
ngx_uint_t current_weight;
|
||||||
|
ngx_uint_t weight;
|
||||||
|
|
||||||
|
ngx_uint_t fails;
|
||||||
|
time_t accessed;
|
||||||
|
|
||||||
|
ngx_uint_t max_fails;
|
||||||
|
time_t fail_timeout;
|
||||||
|
|
||||||
|
ngx_uint_t down; /* unsigned down:1; */
|
||||||
|
|
||||||
|
#if (NGX_SSL)
|
||||||
|
ngx_ssl_session_t *ssl_session;
|
||||||
|
#endif
|
||||||
|
} ngx_http_upstream_rr_peer_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_uint_t current;
|
||||||
|
|
||||||
|
ngx_uint_t number;
|
||||||
|
ngx_uint_t last_cached;
|
||||||
|
|
||||||
|
/* ngx_mutex_t *mutex; */
|
||||||
|
ngx_connection_t **cached;
|
||||||
|
|
||||||
|
ngx_str_t *name;
|
||||||
|
|
||||||
|
ngx_http_upstream_rr_peer_t peer[1];
|
||||||
|
} ngx_http_upstream_rr_peers_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_http_upstream_rr_peers_t *peers;
|
||||||
|
ngx_uint_t current;
|
||||||
|
uintptr_t *tried;
|
||||||
|
uintptr_t data;
|
||||||
|
} ngx_http_upstream_rr_peer_data_t;
|
||||||
|
|
||||||
|
|
||||||
|
ngx_int_t ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
||||||
|
ngx_http_upstream_srv_conf_t *us);
|
||||||
|
ngx_int_t ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
|
||||||
|
ngx_http_upstream_srv_conf_t *us);
|
||||||
|
ngx_int_t ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc,
|
||||||
|
void *data);
|
||||||
|
void ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,
|
||||||
|
void *data, ngx_uint_t state);
|
||||||
|
|
||||||
|
#if (NGX_HTTP_SSL)
|
||||||
|
void ngx_http_upstream_save_round_robin_peer(ngx_peer_connection_t *pc,
|
||||||
|
void *data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ */
|
@ -266,7 +266,7 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s);
|
|||||||
|
|
||||||
|
|
||||||
/* STUB */
|
/* STUB */
|
||||||
void ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peers_t *peers);
|
void ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peer_addr_t *peer);
|
||||||
void ngx_imap_auth_http_init(ngx_imap_session_t *s);
|
void ngx_imap_auth_http_init(ngx_imap_session_t *s);
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_peers_t *peers;
|
ngx_peer_addr_t *peer;
|
||||||
|
|
||||||
ngx_msec_t timeout;
|
ngx_msec_t timeout;
|
||||||
|
|
||||||
@ -175,7 +175,10 @@ ngx_imap_auth_http_init(ngx_imap_session_t *s)
|
|||||||
|
|
||||||
ngx_imap_set_ctx(s, ctx, ngx_imap_auth_http_module);
|
ngx_imap_set_ctx(s, ctx, ngx_imap_auth_http_module);
|
||||||
|
|
||||||
ctx->peer.peers = ahcf->peers;
|
ctx->peer.sockaddr = ahcf->peer->sockaddr;
|
||||||
|
ctx->peer.socklen = ahcf->peer->socklen;
|
||||||
|
ctx->peer.name = &ahcf->peer->name;
|
||||||
|
ctx->peer.get = ngx_event_get_peer;
|
||||||
ctx->peer.log = s->connection->log;
|
ctx->peer.log = s->connection->log;
|
||||||
ctx->peer.log_error = NGX_ERROR_ERR;
|
ctx->peer.log_error = NGX_ERROR_ERR;
|
||||||
|
|
||||||
@ -229,8 +232,7 @@ ngx_imap_auth_http_write_handler(ngx_event_t *wev)
|
|||||||
|
|
||||||
if (wev->timedout) {
|
if (wev->timedout) {
|
||||||
ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
|
ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
|
||||||
"auth http server %V timed out",
|
"auth http server %V timed out", ctx->peer.name);
|
||||||
&ctx->peer.peers->peer[0].name);
|
|
||||||
ngx_close_connection(ctx->peer.connection);
|
ngx_close_connection(ctx->peer.connection);
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
@ -293,8 +295,7 @@ ngx_imap_auth_http_read_handler(ngx_event_t *rev)
|
|||||||
|
|
||||||
if (rev->timedout) {
|
if (rev->timedout) {
|
||||||
ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
|
ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
|
||||||
"auth http server %V timed out",
|
"auth http server %V timed out", ctx->peer.name);
|
||||||
&ctx->peer.peers->peer[0].name);
|
|
||||||
ngx_close_connection(ctx->peer.connection);
|
ngx_close_connection(ctx->peer.connection);
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
@ -413,7 +414,7 @@ ngx_imap_auth_http_ignore_status_line(ngx_imap_session_t *s,
|
|||||||
|
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"auth http server &V sent invalid response",
|
"auth http server &V sent invalid response",
|
||||||
&ctx->peer.peers->peer[0].name);
|
ctx->peer.name);
|
||||||
ngx_close_connection(ctx->peer.connection);
|
ngx_close_connection(ctx->peer.connection);
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
@ -447,7 +448,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
|
|||||||
time_t timer;
|
time_t timer;
|
||||||
size_t len, size;
|
size_t len, size;
|
||||||
ngx_int_t rc, port, n;
|
ngx_int_t rc, port, n;
|
||||||
ngx_peers_t *peers;
|
ngx_peer_addr_t *peer;
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
|
||||||
@ -662,7 +663,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
|
|||||||
if (ctx->addr.len == 0 || ctx->port.len == 0) {
|
if (ctx->addr.len == 0 || ctx->port.len == 0) {
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"auth http server %V did not send server or port",
|
"auth http server %V did not send server or port",
|
||||||
&ctx->peer.peers->peer[0].name);
|
ctx->peer.name);
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
return;
|
return;
|
||||||
@ -671,14 +672,14 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
|
|||||||
if (s->passwd.data == NULL) {
|
if (s->passwd.data == NULL) {
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"auth http server %V did not send password",
|
"auth http server %V did not send password",
|
||||||
&ctx->peer.peers->peer[0].name);
|
ctx->peer.name);
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
peers = ngx_pcalloc(s->connection->pool, sizeof(ngx_peers_t));
|
peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_peer_addr_t));
|
||||||
if (peers == NULL) {
|
if (peer == NULL) {
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
return;
|
return;
|
||||||
@ -698,7 +699,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
|
|||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"auth http server %V sent invalid server "
|
"auth http server %V sent invalid server "
|
||||||
"port:\"%V\"",
|
"port:\"%V\"",
|
||||||
&ctx->peer.peers->peer[0].name, &ctx->port);
|
ctx->peer.name, &ctx->port);
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
return;
|
return;
|
||||||
@ -712,23 +713,21 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
|
|||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"auth http server %V sent invalid server "
|
"auth http server %V sent invalid server "
|
||||||
"address:\"%V\"",
|
"address:\"%V\"",
|
||||||
&ctx->peer.peers->peer[0].name, &ctx->addr);
|
ctx->peer.name, &ctx->addr);
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
peers->number = 1;
|
peer->sockaddr = (struct sockaddr *) sin;
|
||||||
|
peer->socklen = sizeof(struct sockaddr_in);
|
||||||
peers->peer[0].sockaddr = (struct sockaddr *) sin;
|
|
||||||
peers->peer[0].socklen = sizeof(struct sockaddr_in);
|
|
||||||
|
|
||||||
len = ctx->addr.len + 1 + ctx->port.len;
|
len = ctx->addr.len + 1 + ctx->port.len;
|
||||||
|
|
||||||
peers->peer[0].name.len = len;
|
peer->name.len = len;
|
||||||
|
|
||||||
peers->peer[0].name.data = ngx_palloc(s->connection->pool, len);
|
peer->name.data = ngx_palloc(s->connection->pool, len);
|
||||||
if (peers->peer[0].name.data == NULL) {
|
if (peer->name.data == NULL) {
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
return;
|
return;
|
||||||
@ -736,17 +735,14 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
|
|||||||
|
|
||||||
len = ctx->addr.len;
|
len = ctx->addr.len;
|
||||||
|
|
||||||
ngx_memcpy(peers->peer[0].name.data, ctx->addr.data, len);
|
ngx_memcpy(peer->name.data, ctx->addr.data, len);
|
||||||
|
|
||||||
peers->peer[0].name.data[len++] = ':';
|
peer->name.data[len++] = ':';
|
||||||
|
|
||||||
ngx_memcpy(peers->peer[0].name.data + len,
|
ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len);
|
||||||
ctx->port.data, ctx->port.len);
|
|
||||||
|
|
||||||
peers->peer[0].uri_separator = "";
|
|
||||||
|
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_proxy_init(s, peers);
|
ngx_imap_proxy_init(s, peer);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -759,7 +755,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
|
|||||||
|
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"auth http server %V sent invalid header in response",
|
"auth http server %V sent invalid header in response",
|
||||||
&ctx->peer.peers->peer[0].name);
|
ctx->peer.name);
|
||||||
ngx_close_connection(ctx->peer.connection);
|
ngx_close_connection(ctx->peer.connection);
|
||||||
ngx_destroy_pool(ctx->pool);
|
ngx_destroy_pool(ctx->pool);
|
||||||
ngx_imap_session_internal_server_error(s);
|
ngx_imap_session_internal_server_error(s);
|
||||||
@ -1242,8 +1238,8 @@ ngx_imap_auth_http_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_table_elt_t *header;
|
ngx_table_elt_t *header;
|
||||||
|
|
||||||
if (conf->peers == NULL) {
|
if (conf->peer == NULL) {
|
||||||
conf->peers = prev->peers;
|
conf->peer = prev->peer;
|
||||||
conf->host_header = prev->host_header;
|
conf->host_header = prev->host_header;
|
||||||
conf->uri = prev->uri;
|
conf->uri = prev->uri;
|
||||||
}
|
}
|
||||||
@ -1297,6 +1293,7 @@ ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
u.url = value[1];
|
u.url = value[1];
|
||||||
u.default_portn = 80;
|
u.default_portn = 80;
|
||||||
u.uri_part = 1;
|
u.uri_part = 1;
|
||||||
|
u.one_addr = 1;
|
||||||
|
|
||||||
if (ngx_parse_url(cf, &u) != NGX_OK) {
|
if (ngx_parse_url(cf, &u) != NGX_OK) {
|
||||||
if (u.err) {
|
if (u.err) {
|
||||||
@ -1305,8 +1302,7 @@ ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ahcf->peers = u.peers;
|
ahcf->peer = u.addrs;
|
||||||
ahcf->peers->number = 1;
|
|
||||||
|
|
||||||
ahcf->host_header = u.host_header;
|
ahcf->host_header = u.host_header;
|
||||||
ahcf->uri = u.uri;
|
ahcf->uri = u.uri;
|
||||||
|
@ -1279,8 +1279,7 @@ ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = ngx_snprintf(buf, len, ", upstream: %V",
|
p = ngx_snprintf(buf, len, ", upstream: %V", s->proxy->upstream.name);
|
||||||
&s->proxy->upstream.peers->peer[0].name);
|
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ ngx_module_t ngx_imap_proxy_module = {
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peers_t *peers)
|
ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peer_addr_t *peer)
|
||||||
{
|
{
|
||||||
int keepalive;
|
int keepalive;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
@ -125,7 +125,10 @@ ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peers_t *peers)
|
|||||||
|
|
||||||
s->proxy = p;
|
s->proxy = p;
|
||||||
|
|
||||||
p->upstream.peers = peers;
|
p->upstream.sockaddr = peer->sockaddr;
|
||||||
|
p->upstream.socklen = peer->socklen;
|
||||||
|
p->upstream.name = &peer->name;
|
||||||
|
p->upstream.get = ngx_event_get_peer;
|
||||||
p->upstream.log = s->connection->log;
|
p->upstream.log = s->connection->log;
|
||||||
p->upstream.log_error = NGX_ERROR_ERR;
|
p->upstream.log_error = NGX_ERROR_ERR;
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_peers_t *peers;
|
ngx_peer_addr_t *peers;
|
||||||
|
ngx_uint_t npeers;
|
||||||
} ngx_http_mysql_test_conf_t;
|
} ngx_http_mysql_test_conf_t;
|
||||||
|
|
||||||
|
|
||||||
@ -94,10 +95,15 @@ ngx_http_mysql_test_handler(ngx_http_request_t *r)
|
|||||||
m->passwd = &ngx_mysql_passwd;
|
m->passwd = &ngx_mysql_passwd;
|
||||||
m->database = &ngx_mysql_database;
|
m->database = &ngx_mysql_database;
|
||||||
|
|
||||||
|
/* STUB */
|
||||||
|
m->peer.sockaddr = mtcf->peers[0].sockaddr;
|
||||||
|
m->peer.socklen = mtcf->peers[0].socklen;
|
||||||
|
m->peer.name = &mtcf->peers[0].name;
|
||||||
|
m->peer.tries = mtcf->npeers;
|
||||||
|
m->peer.get = ngx_event_get_peer;
|
||||||
|
/**/
|
||||||
m->peer.log = r->connection->log;
|
m->peer.log = r->connection->log;
|
||||||
m->peer.log_error = NGX_ERROR_ERR;
|
m->peer.log_error = NGX_ERROR_ERR;
|
||||||
m->peer.peers = mtcf->peers;
|
|
||||||
m->peer.tries = mtcf->peers->number;
|
|
||||||
|
|
||||||
rc = ngx_mysql_connect(m);
|
rc = ngx_mysql_connect(m);
|
||||||
|
|
||||||
@ -190,7 +196,8 @@ ngx_http_mysql_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtcf->peers = u.peers;
|
mtcf->peers = u.addrs;
|
||||||
|
mtcf->npeers = u.naddrs;
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
@ -150,8 +150,7 @@ ngx_mysql_read_server_greeting(ngx_event_t *rev)
|
|||||||
|
|
||||||
if (rev->timedout) {
|
if (rev->timedout) {
|
||||||
ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
|
ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
|
||||||
"mysql server %V timed out",
|
"mysql server %V timed out", m->peer.name);
|
||||||
&m->peer.peers->peer[0].name);
|
|
||||||
|
|
||||||
ngx_mysql_close(m, NGX_ERROR);
|
ngx_mysql_close(m, NGX_ERROR);
|
||||||
return;
|
return;
|
||||||
@ -183,7 +182,7 @@ ngx_mysql_read_server_greeting(ngx_event_t *rev)
|
|||||||
if (ngx_m24toh(gr1->pktlen) > n - 4) {
|
if (ngx_m24toh(gr1->pktlen) > n - 4) {
|
||||||
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
||||||
"mysql server %V sent incomplete greeting packet",
|
"mysql server %V sent incomplete greeting packet",
|
||||||
&m->peer.peers->peer[0].name);
|
m->peer.name);
|
||||||
|
|
||||||
ngx_mysql_close(m, NGX_ERROR);
|
ngx_mysql_close(m, NGX_ERROR);
|
||||||
return;
|
return;
|
||||||
@ -192,7 +191,7 @@ ngx_mysql_read_server_greeting(ngx_event_t *rev)
|
|||||||
if (gr1->protocol < 10) {
|
if (gr1->protocol < 10) {
|
||||||
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
||||||
"mysql server %V sent unsupported protocol version %ud",
|
"mysql server %V sent unsupported protocol version %ud",
|
||||||
&m->peer.peers->peer[0].name, gr1->protocol);
|
m->peer.name, gr1->protocol);
|
||||||
|
|
||||||
ngx_mysql_close(m, NGX_ERROR);
|
ngx_mysql_close(m, NGX_ERROR);
|
||||||
return;
|
return;
|
||||||
@ -273,7 +272,7 @@ ngx_mysql_read_server_greeting(ngx_event_t *rev)
|
|||||||
if (n < (ssize_t) len) {
|
if (n < (ssize_t) len) {
|
||||||
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
||||||
"the incomplete packet was sent to mysql server %V",
|
"the incomplete packet was sent to mysql server %V",
|
||||||
&m->peer.peers->peer[0].name);
|
m->peer.name);
|
||||||
|
|
||||||
ngx_mysql_close(m, NGX_ERROR);
|
ngx_mysql_close(m, NGX_ERROR);
|
||||||
return;
|
return;
|
||||||
@ -329,7 +328,7 @@ ngx_mysql_read_auth_result(ngx_event_t *rev)
|
|||||||
if (len > n - 4) {
|
if (len > n - 4) {
|
||||||
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
||||||
"mysql server %V sent incomplete response packet",
|
"mysql server %V sent incomplete response packet",
|
||||||
&m->peer.peers->peer[0].name);
|
m->peer.name);
|
||||||
|
|
||||||
ngx_mysql_close(m, NGX_ERROR);
|
ngx_mysql_close(m, NGX_ERROR);
|
||||||
return;
|
return;
|
||||||
@ -353,7 +352,7 @@ ngx_mysql_read_auth_result(ngx_event_t *rev)
|
|||||||
|
|
||||||
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
||||||
"mysql server %V sent error (%ud): \"%V\"",
|
"mysql server %V sent error (%ud): \"%V\"",
|
||||||
&m->peer.peers->peer[0].name, ngx_m16toh(epkt->code), &msg);
|
m->peer.name, ngx_m16toh(epkt->code), &msg);
|
||||||
|
|
||||||
ngx_mysql_close(m, NGX_ERROR);
|
ngx_mysql_close(m, NGX_ERROR);
|
||||||
}
|
}
|
||||||
@ -376,7 +375,7 @@ ngx_mysql_query(ngx_mysql_t *m)
|
|||||||
if (n < (ssize_t) m->query.len) {
|
if (n < (ssize_t) m->query.len) {
|
||||||
ngx_log_error(NGX_LOG_ERR, m->peer.log, 0,
|
ngx_log_error(NGX_LOG_ERR, m->peer.log, 0,
|
||||||
"the incomplete packet was sent to mysql server %V",
|
"the incomplete packet was sent to mysql server %V",
|
||||||
&m->peer.peers->peer[0].name);
|
m->peer.name);
|
||||||
|
|
||||||
ngx_mysql_close(m, NGX_ERROR);
|
ngx_mysql_close(m, NGX_ERROR);
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@ -427,7 +426,7 @@ ngx_mysql_read_query_result(ngx_event_t *rev)
|
|||||||
if (len > n - 4) {
|
if (len > n - 4) {
|
||||||
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
||||||
"mysql server %V sent incomplete response packet",
|
"mysql server %V sent incomplete response packet",
|
||||||
&m->peer.peers->peer[0].name);
|
m->peer.name);
|
||||||
|
|
||||||
ngx_mysql_close(m, NGX_ERROR);
|
ngx_mysql_close(m, NGX_ERROR);
|
||||||
return;
|
return;
|
||||||
@ -451,7 +450,7 @@ ngx_mysql_read_query_result(ngx_event_t *rev)
|
|||||||
|
|
||||||
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
||||||
"mysql server %V sent error (%ud): \"%V\"",
|
"mysql server %V sent error (%ud): \"%V\"",
|
||||||
&m->peer.peers->peer[0].name, ngx_m16toh(epkt->code), &msg);
|
m->peer.name, ngx_m16toh(epkt->code), &msg);
|
||||||
|
|
||||||
ngx_mysql_close(m, NGX_ERROR);
|
ngx_mysql_close(m, NGX_ERROR);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user