mirror of
https://github.com/nginx/nginx.git
synced 2025-01-19 01:42:58 +08:00
nginx-0.3.47-RELEASE import
*) Feature: the "upstream" directive. *) Change: now the "\" escape symbol in the "\"" and "\'" pairs in the SSI command is always removed.
This commit is contained in:
parent
e425c20bbe
commit
6f134cc275
@ -9,6 +9,30 @@
|
||||
<title lang="en">nginx changelog</title>
|
||||
|
||||
|
||||
<changes ver="0.3.47" date="23.05.2006">
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á upstream.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "upstream" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÓÉÍ×ÏÌ "\" × ÐÁÒÁÈ "\"" É "\'" × SSI ËÏÍÁÎÄÁÈ ÔÅÐÅÒØ ×ÓÅÇÄÁ ÕÂÉÒÁÅÔÓÑ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
now the "\" escape symbol in the "\"" and "\'" pairs in the SSI command
|
||||
is always removed.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="0.3.46" date="11.05.2006">
|
||||
|
||||
<change type="feature">
|
||||
@ -24,7 +48,7 @@ and "fastcgi_pass_header" directives.
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÄÉŇĹËÔÉ×Ů proxy_x_powered_by, fastcgi_x_powered_by É proxy_pass_server
|
||||
ÄÉÒÅËÔÉ×Ù proxy_pass_x_powered_by, fastcgi_x_powered_by É proxy_pass_server
|
||||
ÕÐÒÁÚÄÎÅÎÙ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define NGINX_VER "nginx/0.3.46"
|
||||
#define NGINX_VER "nginx/0.3.47"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
|
@ -61,7 +61,7 @@
|
||||
|
||||
|
||||
#define NGX_CONF_OK NULL
|
||||
#define NGX_CONF_ERROR (char *) -1
|
||||
#define NGX_CONF_ERROR (void *) -1
|
||||
|
||||
#define NGX_CONF_BLOCK_START 1
|
||||
#define NGX_CONF_BLOCK_DONE 2
|
||||
|
@ -63,6 +63,9 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
|
||||
#include <ngx_radix_tree.h>
|
||||
#include <ngx_times.h>
|
||||
#include <ngx_shmtx.h>
|
||||
#if (NGX_OPENSSL)
|
||||
#include <ngx_event_openssl.h>
|
||||
#endif
|
||||
#include <ngx_inet.h>
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
#include <ngx_unix_domain.h>
|
||||
@ -71,9 +74,6 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
|
||||
#include <ngx_process_cycle.h>
|
||||
#include <ngx_conf_file.h>
|
||||
#include <ngx_os.h>
|
||||
#if (NGX_OPENSSL)
|
||||
#include <ngx_event_openssl.h>
|
||||
#endif
|
||||
#include <ngx_connection.h>
|
||||
|
||||
|
||||
|
@ -31,16 +31,14 @@ ngx_cpuid(uint32_t i, uint32_t *buf)
|
||||
" mov %%ebx, %%esi; "
|
||||
|
||||
" cpuid; "
|
||||
" mov %%eax, %0; "
|
||||
" mov %%ebx, %1; "
|
||||
" mov %%edx, %2; "
|
||||
" mov %%ecx, %3; "
|
||||
" mov %%eax, (%1); "
|
||||
" mov %%ebx, 4(%1); "
|
||||
" mov %%edx, 8(%1); "
|
||||
" mov %%ecx, 12(%1); "
|
||||
|
||||
" mov %%esi, %%ebx; "
|
||||
|
||||
: "=m" (buf[0]), "=m" (buf[1]), "=m" (buf[2]), "=m" (buf[3])
|
||||
: "a" (i)
|
||||
: "ecx", "edx", "esi" );
|
||||
: : "a" (i), "D" (buf) : "ecx", "edx", "esi", "memory" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,6 +220,339 @@ ngx_ptocidr(ngx_str_t *text, void *cidr)
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
|
||||
{
|
||||
u_char *p;
|
||||
size_t len;
|
||||
ngx_int_t port;
|
||||
ngx_uint_t i;
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
struct sockaddr_un *saun;
|
||||
#endif
|
||||
|
||||
len = u->url.len;
|
||||
p = u->url.data;
|
||||
|
||||
if (ngx_strncasecmp(p, "unix:", 5) == 0) {
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
u->type = NGX_PARSE_URL_UNIX;
|
||||
|
||||
p += 5;
|
||||
len -= 5;
|
||||
|
||||
if (u->uri_part) {
|
||||
for (i = 0; i < len; i++) {
|
||||
|
||||
if (p[i] == ':') {
|
||||
len = i;
|
||||
|
||||
u->uri.len -= len + 1;
|
||||
u->uri.data += len + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
u->err = "no path in the unix domain socket";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (len + 1 > sizeof(saun->sun_path)) {
|
||||
u->err = "too long path in the unix domain socket";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t));
|
||||
if (u->peers == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
saun = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_un));
|
||||
if (saun == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->peers->number = 1;
|
||||
|
||||
saun->sun_family = AF_UNIX;
|
||||
(void) ngx_cpystrn((u_char *) saun->sun_path, p, len + 1);
|
||||
|
||||
u->peers->peer[0].sockaddr = (struct sockaddr *) saun;
|
||||
u->peers->peer[0].socklen = sizeof(struct sockaddr_un);
|
||||
u->peers->peer[0].name = u->url;
|
||||
u->peers->peer[0].uri_separator = ":";
|
||||
|
||||
u->host_header.len = sizeof("localhost") - 1;
|
||||
u->host_header.data = (u_char *) "localhost";
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
#else
|
||||
u->err = "the unix domain sockets are not supported on this platform";
|
||||
|
||||
return NGX_ERROR;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((p[0] == ':' || p[0] == '/') && !u->listen) {
|
||||
u->err = "invalid host";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->type = NGX_PARSE_URL_INET;
|
||||
|
||||
u->host.data = p;
|
||||
u->host_header.len = len;
|
||||
u->host_header.data = p;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
|
||||
if (p[i] == ':') {
|
||||
u->port.data = &p[i + 1];
|
||||
u->host.len = i;
|
||||
|
||||
if (!u->uri_part) {
|
||||
u->port.len = &p[len] - u->port.data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p[i] == '/') {
|
||||
u->uri.len = len - i;
|
||||
u->uri.data = &p[i];
|
||||
u->host_header.len = i;
|
||||
|
||||
if (u->host.len == 0) {
|
||||
u->host.len = i;
|
||||
}
|
||||
|
||||
if (u->port.data == NULL) {
|
||||
u->default_port = 1;
|
||||
goto port;
|
||||
}
|
||||
|
||||
u->port.len = &p[i] - u->port.data;
|
||||
|
||||
if (u->port.len == 0) {
|
||||
u->err = "invalid port";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (u->port.data) {
|
||||
|
||||
if (u->port.len == 0) {
|
||||
u->port.len = &p[i] - u->port.data;
|
||||
|
||||
if (u->port.len == 0) {
|
||||
u->err = "invalid port";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
port = ngx_atoi(u->port.data, u->port.len);
|
||||
|
||||
if (port == NGX_ERROR || port < 1 || port > 65536) {
|
||||
u->err = "invalid port";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
port = ngx_atoi(p, len);
|
||||
|
||||
if (port == NGX_ERROR) {
|
||||
u->default_port = 1;
|
||||
u->host.len = len;
|
||||
|
||||
goto port;
|
||||
}
|
||||
|
||||
u->port.len = len;
|
||||
u->port.data = p;
|
||||
u->wildcard = 1;
|
||||
}
|
||||
|
||||
u->portn = (in_port_t) port;
|
||||
|
||||
port:
|
||||
|
||||
if (u->listen) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (u->default_port) {
|
||||
|
||||
if (u->upstream) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (u->default_portn == 0) {
|
||||
u->err = "no port";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->portn = u->default_portn;
|
||||
|
||||
u->port.data = ngx_palloc(cf->pool, sizeof("65536") - 1);
|
||||
if (u->port.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->port.len = ngx_sprintf(u->port.data, "%d", u->portn) - u->port.data;
|
||||
|
||||
} else if (u->portn) {
|
||||
if (u->portn == u->default_portn) {
|
||||
u->default_port = 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
u->err = "no port";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (u->host.len == 0) {
|
||||
u->err = "no host";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->peers = ngx_inet_resolve_peer(cf, &u->host, u->portn);
|
||||
|
||||
if (u->peers == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (u->peers == NGX_CONF_ERROR) {
|
||||
u->err = "host not found";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_peers_t *
|
||||
ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name, in_port_t port)
|
||||
{
|
||||
u_char *host;
|
||||
size_t len;
|
||||
in_addr_t in_addr;
|
||||
ngx_uint_t i;
|
||||
ngx_peers_t *peers;
|
||||
struct hostent *h;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
host = ngx_palloc(cf->temp_pool, name->len + 1);
|
||||
if (host == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void) ngx_cpystrn(host, name->data, name->len + 1);
|
||||
|
||||
/* AF_INET only */
|
||||
|
||||
in_addr = inet_addr((char *) host);
|
||||
|
||||
if (in_addr == INADDR_NONE) {
|
||||
h = gethostbyname((char *) host);
|
||||
|
||||
if (h == NULL || h->h_addr_list[0] == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
|
||||
|
||||
/* MP: ngx_shared_palloc() */
|
||||
|
||||
peers = ngx_pcalloc(cf->pool,
|
||||
sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1));
|
||||
if (peers == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
peers->number = i;
|
||||
peers->weight = 1;
|
||||
|
||||
for (i = 0; h->h_addr_list[i] != NULL; i++) {
|
||||
|
||||
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
|
||||
if (sin == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = htons(port);
|
||||
sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
|
||||
|
||||
peers->peer[i].sockaddr = (struct sockaddr *) sin;
|
||||
peers->peer[i].socklen = sizeof(struct sockaddr_in);
|
||||
|
||||
len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
|
||||
|
||||
peers->peer[i].name.data = ngx_palloc(cf->pool, len);
|
||||
if (peers->peer[i].name.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin,
|
||||
peers->peer[i].name.data, len);
|
||||
|
||||
peers->peer[i].name.len =
|
||||
ngx_sprintf(&peers->peer[i].name.data[len],
|
||||
":%d", port)
|
||||
- peers->peer[i].name.data;
|
||||
|
||||
peers->peer[i].uri_separator = "";
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* MP: ngx_shared_palloc() */
|
||||
|
||||
peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t));
|
||||
if (peers == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
|
||||
if (sin == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
peers->number = 1;
|
||||
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = htons(port);
|
||||
sin->sin_addr.s_addr = in_addr;
|
||||
|
||||
peers->peer[0].sockaddr = (struct sockaddr *) sin;
|
||||
peers->peer[0].socklen = sizeof(struct sockaddr_in);
|
||||
|
||||
peers->peer[0].name.data = ngx_palloc(cf->pool,
|
||||
name->len + sizeof(":65536") - 1);
|
||||
if (peers->peer[0].name.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
peers->peer[0].name.len = ngx_sprintf(peers->peer[0].name.data, "%V:%d",
|
||||
name, port)
|
||||
- peers->peer[0].name.data;
|
||||
|
||||
peers->peer[0].uri_separator = "";
|
||||
}
|
||||
|
||||
return peers;
|
||||
}
|
||||
|
||||
|
||||
ngx_peers_t *
|
||||
ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u)
|
||||
{
|
||||
@ -241,6 +574,7 @@ ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u)
|
||||
}
|
||||
|
||||
if (u->default_port) {
|
||||
|
||||
if (u->default_port_value == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"no port in upstream \"%V\"", &u->name);
|
||||
@ -277,7 +611,7 @@ ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u)
|
||||
|
||||
u->port = htons(u->port);
|
||||
|
||||
host = ngx_palloc(cf->pool, u->host.len + 1);
|
||||
host = ngx_palloc(cf->temp_pool, u->host.len + 1);
|
||||
if (host == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -12,12 +12,76 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
#define NGX_PARSE_URL_INET 1
|
||||
#define NGX_PARSE_URL_UNIX 2
|
||||
|
||||
|
||||
typedef struct {
|
||||
in_addr_t addr;
|
||||
in_addr_t mask;
|
||||
} ngx_inet_cidr_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct sockaddr *sockaddr;
|
||||
socklen_t socklen;
|
||||
|
||||
ngx_str_t name;
|
||||
char *uri_separator;
|
||||
|
||||
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 weight;
|
||||
|
||||
ngx_uint_t number;
|
||||
ngx_uint_t last_cached;
|
||||
|
||||
/* ngx_mutex_t *mutex; */
|
||||
ngx_connection_t **cached;
|
||||
|
||||
ngx_peer_t peer[1];
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_int_t type;
|
||||
|
||||
ngx_peers_t *peers;
|
||||
|
||||
ngx_str_t url;
|
||||
ngx_str_t host;
|
||||
ngx_str_t host_header;
|
||||
ngx_str_t port;
|
||||
ngx_str_t uri;
|
||||
|
||||
in_port_t portn;
|
||||
in_port_t default_portn;
|
||||
|
||||
unsigned listen:1;
|
||||
unsigned uri_part:1;
|
||||
unsigned upstream:1;
|
||||
|
||||
unsigned default_port:1;
|
||||
unsigned wildcard:1;
|
||||
|
||||
char *err;
|
||||
} ngx_url_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name; /* "schema:host:port/uri" */
|
||||
ngx_str_t url; /* "host:port/uri" */
|
||||
@ -35,6 +99,7 @@ typedef struct {
|
||||
|
||||
unsigned uri_part:1;
|
||||
unsigned port_only:1;
|
||||
unsigned virtual:1;
|
||||
} ngx_inet_upstream_t;
|
||||
|
||||
|
||||
@ -45,7 +110,10 @@ 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_peers_t *ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u);
|
||||
ngx_peers_t *ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name,
|
||||
in_port_t port);
|
||||
char *ngx_inet_parse_host_port(ngx_inet_upstream_t *u);
|
||||
ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u);
|
||||
|
||||
|
||||
#endif /* _NGX_INET_H_INCLUDED_ */
|
||||
|
@ -50,10 +50,10 @@ ngx_parse_size(ngx_str_t *line)
|
||||
ngx_int_t
|
||||
ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
|
||||
{
|
||||
size_t len;
|
||||
u_char *start, last;
|
||||
ngx_int_t value, total, scale;
|
||||
ngx_uint_t max, i;
|
||||
size_t len;
|
||||
u_char *start, last;
|
||||
ngx_int_t value, total, scale;
|
||||
ngx_uint_t max, i;
|
||||
enum {
|
||||
st_start = 0,
|
||||
st_year,
|
||||
|
@ -13,41 +13,6 @@
|
||||
#include <ngx_event.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct sockaddr *sockaddr;
|
||||
socklen_t socklen;
|
||||
|
||||
ngx_str_t name;
|
||||
char *uri_separator;
|
||||
|
||||
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 weight;
|
||||
|
||||
ngx_uint_t number;
|
||||
ngx_uint_t last_cached;
|
||||
|
||||
/* ngx_mutex_t *mutex; */
|
||||
ngx_connection_t **cached;
|
||||
|
||||
ngx_peer_t peer[1];
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_peers_t *peers;
|
||||
ngx_uint_t cur_peer;
|
||||
|
@ -135,7 +135,7 @@ ngx_http_empty_gif_handler(ngx_http_request_t *r)
|
||||
}
|
||||
}
|
||||
|
||||
b = ngx_create_temp_buf(r->pool, sizeof(ngx_empty_gif));
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
@ -145,6 +145,7 @@ ngx_http_empty_gif_handler(ngx_http_request_t *r)
|
||||
|
||||
b->pos = ngx_empty_gif;
|
||||
b->last = ngx_empty_gif + sizeof(ngx_empty_gif);
|
||||
b->memory = 1;
|
||||
b->last_buf = 1;
|
||||
|
||||
r->headers_out.status = NGX_HTTP_OK;
|
||||
|
@ -11,16 +11,17 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_upstream_conf_t upstream;
|
||||
ngx_http_upstream_conf_t upstream;
|
||||
|
||||
ngx_peers_t *peers;
|
||||
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 *params_len;
|
||||
ngx_array_t *params;
|
||||
ngx_array_t *params_source;
|
||||
ngx_array_t *flushes;
|
||||
ngx_array_t *params_len;
|
||||
ngx_array_t *params;
|
||||
ngx_array_t *params_source;
|
||||
} ngx_http_fastcgi_loc_conf_t;
|
||||
|
||||
|
||||
@ -39,14 +40,14 @@ typedef enum {
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_fastcgi_state_e state;
|
||||
u_char *pos;
|
||||
u_char *last;
|
||||
ngx_uint_t type;
|
||||
size_t length;
|
||||
size_t padding;
|
||||
ngx_http_fastcgi_state_e state;
|
||||
u_char *pos;
|
||||
u_char *last;
|
||||
ngx_uint_t type;
|
||||
size_t length;
|
||||
size_t padding;
|
||||
|
||||
ngx_uint_t fastcgi_stdout;
|
||||
ngx_uint_t fastcgi_stdout;
|
||||
} ngx_http_fastcgi_ctx_t;
|
||||
|
||||
|
||||
@ -391,8 +392,8 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
|
||||
|
||||
u->peer.log = r->connection->log;
|
||||
u->peer.log_error = NGX_ERROR_ERR;
|
||||
u->peer.peers = flcf->peers;
|
||||
u->peer.tries = flcf->peers->number;
|
||||
u->peer.peers = flcf->upstream_peers->peers;
|
||||
u->peer.tries = flcf->upstream_peers->peers->number;
|
||||
#if (NGX_THREADS)
|
||||
u->peer.lock = &r->connection->lock;
|
||||
#endif
|
||||
@ -1687,11 +1688,13 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
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;
|
||||
if (conf->upstream_peers && !conf->upstream_peers->balanced) {
|
||||
for (i = 0; i < conf->upstream_peers->peers->number; i++) {
|
||||
conf->upstream_peers->peers->peer[i].weight = 1;
|
||||
conf->upstream_peers->peers->peer[i].max_fails =
|
||||
conf->upstream.max_fails;
|
||||
conf->upstream_peers->peers->peer[i].fail_timeout =
|
||||
conf->upstream.fail_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1813,8 +1816,8 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
peers:
|
||||
|
||||
if (conf->peers == NULL) {
|
||||
conf->peers = prev->peers;
|
||||
if (conf->upstream_peers == NULL) {
|
||||
conf->upstream_peers = prev->upstream_peers;
|
||||
conf->upstream.schema = prev->upstream.schema;
|
||||
}
|
||||
|
||||
@ -1989,12 +1992,9 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_fastcgi_loc_conf_t *lcf = conf;
|
||||
|
||||
ngx_url_t u;
|
||||
ngx_str_t *value;
|
||||
ngx_inet_upstream_t inet_upstream;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
ngx_unix_domain_upstream_t unix_upstream;
|
||||
#endif
|
||||
|
||||
if (lcf->upstream.schema.len) {
|
||||
return "is duplicate";
|
||||
@ -2002,40 +2002,14 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (ngx_strncasecmp(value[1].data, "unix:", 5) == 0) {
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
u.url = value[1];
|
||||
u.upstream = 1;
|
||||
|
||||
ngx_memzero(&unix_upstream, sizeof(ngx_unix_domain_upstream_t));
|
||||
|
||||
unix_upstream.name = value[1];
|
||||
unix_upstream.url = value[1];
|
||||
|
||||
lcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream);
|
||||
if (lcf->peers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
lcf->peers->peer[0].uri_separator = "";
|
||||
|
||||
#else
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the unix domain sockets are not supported "
|
||||
"on this platform");
|
||||
lcf->upstream_peers = ngx_http_upstream_add(cf, &u);
|
||||
if (lcf->upstream_peers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
|
||||
#endif
|
||||
|
||||
} else {
|
||||
ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t));
|
||||
|
||||
inet_upstream.name = value[1];
|
||||
inet_upstream.url = value[1];
|
||||
|
||||
lcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream);
|
||||
if (lcf->peers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
lcf->upstream.schema.len = sizeof("fastcgi://") - 1;
|
||||
|
@ -16,56 +16,56 @@ typedef ngx_int_t (*ngx_http_proxy_redirect_pt)(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, size_t prefix, ngx_http_proxy_redirect_t *pr);
|
||||
|
||||
struct ngx_http_proxy_redirect_s {
|
||||
ngx_http_proxy_redirect_pt handler;
|
||||
ngx_str_t redirect;
|
||||
ngx_http_proxy_redirect_pt handler;
|
||||
ngx_str_t redirect;
|
||||
|
||||
union {
|
||||
ngx_str_t text;
|
||||
ngx_str_t text;
|
||||
|
||||
struct {
|
||||
void *lengths;
|
||||
void *values;
|
||||
void *lengths;
|
||||
void *values;
|
||||
} vars;
|
||||
|
||||
void *regex;
|
||||
void *regex;
|
||||
} replacement;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_upstream_conf_t upstream;
|
||||
ngx_http_upstream_conf_t upstream;
|
||||
|
||||
ngx_peers_t *peers;
|
||||
ngx_http_upstream_srv_conf_t *upstream_peers;
|
||||
|
||||
ngx_array_t *flushes;
|
||||
ngx_array_t *body_set_len;
|
||||
ngx_array_t *body_set;
|
||||
ngx_array_t *headers_set_len;
|
||||
ngx_array_t *headers_set;
|
||||
ngx_hash_t headers_set_hash;
|
||||
ngx_array_t *flushes;
|
||||
ngx_array_t *body_set_len;
|
||||
ngx_array_t *body_set;
|
||||
ngx_array_t *headers_set_len;
|
||||
ngx_array_t *headers_set;
|
||||
ngx_hash_t headers_set_hash;
|
||||
|
||||
ngx_array_t *headers_source;
|
||||
ngx_array_t *headers_names;
|
||||
ngx_array_t *headers_source;
|
||||
ngx_array_t *headers_names;
|
||||
|
||||
ngx_array_t *redirects;
|
||||
ngx_array_t *redirects;
|
||||
|
||||
ngx_str_t body_source;
|
||||
ngx_str_t body_source;
|
||||
|
||||
ngx_str_t method;
|
||||
ngx_str_t host_header;
|
||||
ngx_str_t port_text;
|
||||
ngx_str_t method;
|
||||
ngx_str_t host_header;
|
||||
ngx_str_t port_text;
|
||||
|
||||
ngx_flag_t redirect;
|
||||
ngx_flag_t redirect;
|
||||
} ngx_http_proxy_loc_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t status;
|
||||
ngx_uint_t status_count;
|
||||
u_char *status_start;
|
||||
u_char *status_end;
|
||||
ngx_uint_t status;
|
||||
ngx_uint_t status_count;
|
||||
u_char *status_start;
|
||||
u_char *status_end;
|
||||
|
||||
size_t internal_body_length;
|
||||
size_t internal_body_length;
|
||||
} ngx_http_proxy_ctx_t;
|
||||
|
||||
|
||||
@ -407,8 +407,8 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||
|
||||
u->peer.log = r->connection->log;
|
||||
u->peer.log_error = NGX_ERROR_ERR;
|
||||
u->peer.peers = plcf->peers;
|
||||
u->peer.tries = plcf->peers->number;
|
||||
u->peer.peers = plcf->upstream_peers->peers;
|
||||
u->peer.tries = plcf->upstream_peers->peers->number;
|
||||
#if (NGX_THREADS)
|
||||
u->peer.lock = &r->connection->lock;
|
||||
#endif
|
||||
@ -1640,11 +1640,13 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
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;
|
||||
if (conf->upstream_peers && !conf->upstream_peers->balanced) {
|
||||
for (i = 0; i < conf->upstream_peers->peers->number; i++) {
|
||||
conf->upstream_peers->peers->peer[i].weight = 1;
|
||||
conf->upstream_peers->peers->peer[i].max_fails =
|
||||
conf->upstream.max_fails;
|
||||
conf->upstream_peers->peers->peer[i].fail_timeout =
|
||||
conf->upstream.fail_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1797,8 +1799,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
peers:
|
||||
|
||||
if (conf->peers == NULL) {
|
||||
conf->peers = prev->peers;
|
||||
if (conf->upstream_peers == NULL) {
|
||||
conf->upstream_peers = prev->upstream_peers;
|
||||
|
||||
conf->host_header = prev->host_header;
|
||||
conf->port_text = prev->port_text;
|
||||
@ -2106,14 +2108,11 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
size_t add;
|
||||
u_short port;
|
||||
ngx_str_t *value, *url;
|
||||
ngx_inet_upstream_t inet_upstream;
|
||||
ngx_url_t u;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
#if (NGX_HTTP_SSL)
|
||||
ngx_pool_cleanup_t *cln;
|
||||
#endif
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
ngx_unix_domain_upstream_t unix_upstream;
|
||||
#endif
|
||||
|
||||
if (plcf->upstream.schema.len) {
|
||||
return "is duplicate";
|
||||
@ -2167,53 +2166,23 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_strncasecmp(url->data + add, "unix:", 5) == 0) {
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
u.url.len = url->len - add;
|
||||
u.url.data = url->data + add;
|
||||
u.default_portn = port;
|
||||
u.uri_part = 1;
|
||||
u.upstream = 1;
|
||||
|
||||
ngx_memzero(&unix_upstream, sizeof(ngx_unix_domain_upstream_t));
|
||||
|
||||
unix_upstream.name = *url;
|
||||
unix_upstream.url.len = url->len - add;
|
||||
unix_upstream.url.data = url->data + add;
|
||||
unix_upstream.uri_part = 1;
|
||||
|
||||
plcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream);
|
||||
if (plcf->peers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
plcf->host_header.len = sizeof("localhost") - 1;
|
||||
plcf->host_header.data = (u_char *) "localhost";
|
||||
plcf->upstream.uri = unix_upstream.uri;
|
||||
|
||||
#else
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the unix domain sockets are not supported "
|
||||
"on this platform");
|
||||
plcf->upstream_peers = ngx_http_upstream_add(cf, &u);
|
||||
if (plcf->upstream_peers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
|
||||
#endif
|
||||
|
||||
} else {
|
||||
ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t));
|
||||
|
||||
inet_upstream.name = *url;
|
||||
inet_upstream.url.len = url->len - add;
|
||||
inet_upstream.url.data = url->data + add;
|
||||
inet_upstream.default_port_value = port;
|
||||
inet_upstream.uri_part = 1;
|
||||
|
||||
plcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream);
|
||||
if (plcf->peers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
plcf->host_header = inet_upstream.host_header;
|
||||
plcf->port_text = inet_upstream.port_text;
|
||||
plcf->upstream.uri = inet_upstream.uri;
|
||||
}
|
||||
|
||||
plcf->host_header = u.host_header;
|
||||
plcf->port_text = u.port;
|
||||
plcf->upstream.uri = u.uri;
|
||||
|
||||
plcf->upstream.schema.len = add;
|
||||
plcf->upstream.schema.data = url->data;
|
||||
|
||||
|
@ -1224,38 +1224,14 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
||||
case ssi_quoted_symbol_state:
|
||||
state = ctx->saved_state;
|
||||
|
||||
if (ch == '\\') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch == '"' && state == ssi_double_quoted_value_state) {
|
||||
ctx->param->value.data[ctx->param->value.len - 1] = ch;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch == '\'' && state == ssi_quoted_value_state) {
|
||||
ctx->param->value.data[ctx->param->value.len - 1] = ch;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx->param->value.len == ctx->value_len) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"too long \"%V%c...\" value of \"%V\" "
|
||||
"parameter in \"%V\" SSI command",
|
||||
&ctx->param->value, ch, &ctx->param->key,
|
||||
&ctx->command);
|
||||
state = ssi_error_state;
|
||||
break;
|
||||
}
|
||||
|
||||
ctx->param->value.data[ctx->param->value.len++] = ch;
|
||||
|
||||
break;
|
||||
|
||||
case ssi_postparam_state:
|
||||
|
||||
if (ctx->param->value.len < ctx->value_len / 2) {
|
||||
value = ngx_palloc(r->pool, ctx->param->value.len);
|
||||
if (ctx->param->value.len + 1 < ctx->value_len / 2) {
|
||||
value = ngx_palloc(r->pool, ctx->param->value.len + 1);
|
||||
if (value == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -1433,7 +1409,7 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
size_t *size, len, prefix, part_len;
|
||||
ngx_str_t var, *val;
|
||||
ngx_int_t key;
|
||||
ngx_uint_t i, j, n, bracket;
|
||||
ngx_uint_t i, j, n, bracket, quoted;
|
||||
ngx_array_t lengths, values;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
@ -1567,18 +1543,28 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
|
||||
} else {
|
||||
part_data = &text->data[i];
|
||||
quoted = 0;
|
||||
|
||||
for (p = part_data; i < text->len; i++) {
|
||||
ch = text->data[i];
|
||||
|
||||
if (ch == '$') {
|
||||
if (text->data[i - 1] != '\\') {
|
||||
if (!quoted) {
|
||||
|
||||
if (ch == '\\') {
|
||||
quoted = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '$') {
|
||||
break;
|
||||
}
|
||||
|
||||
*(p - 1) = ch;
|
||||
} else {
|
||||
quoted = 0;
|
||||
|
||||
continue;
|
||||
if (ch != '\\' && ch != '\'' && ch != '"' && ch != '$') {
|
||||
*p++ = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
*p++ = ch;
|
||||
@ -2016,7 +2002,7 @@ ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
flags = 0;
|
||||
|
||||
if (p < last - 1 && p[0] == '\\' && p[1] == '/') {
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,6 +399,24 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,
|
||||
|
||||
dTHXa(ctx->perl);
|
||||
|
||||
#if 0
|
||||
|
||||
/* the code is disabled to force the precompiled perl code using only */
|
||||
|
||||
ngx_http_perl_eval_anon_sub(aTHX_ handler, &sv);
|
||||
|
||||
if (sv == &PL_sv_undef) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"eval_pv(\"%V\") failed", handler);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (sv == NULL) {
|
||||
sv = newSVpvn((char *) handler->data, handler->len);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
sv = newSVpvn((char *) handler->data, handler->len);
|
||||
|
||||
rc = ngx_http_perl_call_handler(aTHX_ r, sv, ¶ms[NGX_HTTP_PERL_SSI_ARG],
|
||||
|
@ -106,7 +106,7 @@ static ngx_command_t ngx_http_core_commands[] = {
|
||||
NULL },
|
||||
|
||||
{ ngx_string("server"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_MULTI|NGX_CONF_NOARGS,
|
||||
ngx_http_core_server,
|
||||
0,
|
||||
0,
|
||||
@ -506,7 +506,6 @@ ngx_http_handler(ngx_http_request_t *r)
|
||||
r->valid_unparsed_uri = 1;
|
||||
r->valid_location = 1;
|
||||
r->uri_changed = 1;
|
||||
r->uri_changes = NGX_HTTP_MAX_REWRITE_CYCLES + 1;
|
||||
|
||||
r->phase = (r == r->main) ? NGX_HTTP_POST_READ_PHASE:
|
||||
NGX_HTTP_SERVER_REWRITE_PHASE;
|
||||
@ -547,7 +546,7 @@ ngx_http_core_run_phases(ngx_http_request_t *r)
|
||||
|
||||
if (r->uri_changes == 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"rewrite cycle");
|
||||
"rewrite or internal redirection cycle");
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
@ -1263,6 +1262,8 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
sr->discard_body = r->discard_body;
|
||||
sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
|
||||
|
||||
sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
|
||||
|
||||
ngx_http_handler(sr);
|
||||
|
||||
if (!c->destroyed) {
|
||||
@ -1331,6 +1332,8 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
|
||||
r->internal = 1;
|
||||
r->method = NGX_HTTP_GET;
|
||||
|
||||
r->uri_changes--;
|
||||
|
||||
ngx_http_handler(r);
|
||||
|
||||
return NGX_DONE;
|
||||
@ -1794,7 +1797,7 @@ ngx_http_core_create_main_conf(ngx_conf_t *cf)
|
||||
|
||||
if (ngx_array_init(&cmcf->servers, cf->pool, 4,
|
||||
sizeof(ngx_http_core_srv_conf_t *))
|
||||
== NGX_ERROR)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
@ -666,6 +666,8 @@ ngx_http_process_request_line(ngx_event_t *rev)
|
||||
c->write->handler = ngx_http_request_handler;
|
||||
r->read_event_handler = ngx_http_block_read;
|
||||
|
||||
r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
|
||||
|
||||
ngx_http_handler(r);
|
||||
|
||||
return;
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define _NGX_HTTP_REQUEST_H_INCLUDED_
|
||||
|
||||
|
||||
#define NGX_HTTP_MAX_REWRITE_CYCLES 10
|
||||
#define NGX_HTTP_MAX_URI_CHANGES 10
|
||||
|
||||
/* must be 2^n */
|
||||
#define NGX_HTTP_LC_HEADER_LEN 32
|
||||
|
@ -85,8 +85,12 @@ static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r,
|
||||
static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
|
||||
static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
|
||||
static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *,
|
||||
@ -206,12 +210,32 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
};
|
||||
|
||||
|
||||
ngx_http_module_t ngx_http_upstream_module_ctx = {
|
||||
static ngx_command_t ngx_http_upstream_commands[] = {
|
||||
|
||||
{ ngx_string("upstream"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
|
||||
ngx_http_upstream,
|
||||
0,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("server"),
|
||||
NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_upstream_server,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_module_t ngx_http_upstream_module_ctx = {
|
||||
ngx_http_upstream_add_variables, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
ngx_http_upstream_create_main_conf, /* create main configuration */
|
||||
ngx_http_core_init_main_conf, /* init main configuration */
|
||||
ngx_http_upstream_init_main_conf, /* init main configuration */
|
||||
|
||||
NULL, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
@ -224,7 +248,7 @@ ngx_http_module_t ngx_http_upstream_module_ctx = {
|
||||
ngx_module_t ngx_http_upstream_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_upstream_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
ngx_http_upstream_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
@ -868,6 +892,14 @@ ngx_http_upstream_send_request_handler(ngx_event_t *wev)
|
||||
|
||||
#endif
|
||||
|
||||
if (u->header_sent) {
|
||||
wev->handler = ngx_http_upstream_dummy_handler;
|
||||
|
||||
(void) ngx_handle_write_event(wev, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_http_upstream_send_request(r, u);
|
||||
}
|
||||
|
||||
@ -2547,6 +2579,232 @@ ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
||||
{
|
||||
char *rv;
|
||||
void *mconf;
|
||||
ngx_str_t *value;
|
||||
ngx_url_t u;
|
||||
ngx_uint_t i, j, m, n;
|
||||
ngx_conf_t pcf;
|
||||
ngx_peers_t **peers;
|
||||
ngx_http_module_t *module;
|
||||
ngx_http_conf_ctx_t *ctx;
|
||||
ngx_http_upstream_srv_conf_t *uscf;
|
||||
|
||||
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
|
||||
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 */
|
||||
|
||||
ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
|
||||
if (ctx->srv_conf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf;
|
||||
|
||||
|
||||
/* the upstream{}'s loc_conf */
|
||||
|
||||
ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
|
||||
if (ctx->loc_conf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (m = 0; ngx_modules[m]; m++) {
|
||||
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
module = ngx_modules[m]->ctx;
|
||||
|
||||
if (module->create_loc_conf) {
|
||||
mconf = module->create_loc_conf(cf);
|
||||
if (mconf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ctx->loc_conf[ngx_modules[m]->ctx_index] = mconf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* parse inside upstream{} */
|
||||
|
||||
pcf = *cf;
|
||||
cf->ctx = ctx;
|
||||
cf->cmd_type = NGX_HTTP_UPS_CONF;
|
||||
|
||||
rv = ngx_conf_parse(cf, NULL);
|
||||
|
||||
*cf = pcf;
|
||||
|
||||
if (rv != NGX_CONF_OK) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (uscf->servers == NULL) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"no servers are inside upstream");
|
||||
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;
|
||||
uscf->peers->weight = 1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_upstream_srv_conf_t *uscf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_url_t u;
|
||||
ngx_peers_t **peers;
|
||||
|
||||
if (uscf->servers == NULL) {
|
||||
uscf->servers = ngx_array_create(cf->pool, 4, sizeof(ngx_peers_t *));
|
||||
if (uscf->servers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
peers = ngx_array_push(uscf->servers);
|
||||
if (peers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
|
||||
u.url = value[1];
|
||||
u.default_portn = 80;
|
||||
|
||||
if (ngx_parse_url(cf, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in upstream \"%V\"", u.err, &u.url);
|
||||
}
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*peers = u.peers;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_http_upstream_srv_conf_t *
|
||||
ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_http_upstream_srv_conf_t *uscf, **uscfp;
|
||||
ngx_http_upstream_main_conf_t *umcf;
|
||||
|
||||
if (u->upstream) {
|
||||
if (ngx_parse_url(cf, u) != NGX_OK) {
|
||||
if (u->err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in upstream \"%V\"", u->err, &u->url);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
uscfp = umcf->upstreams.elts;
|
||||
|
||||
for (i = 0; i < umcf->upstreams.nelts; i++) {
|
||||
if (uscfp[i]->host.len != u->host.len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len)
|
||||
== 0)
|
||||
{
|
||||
return uscfp[i];
|
||||
}
|
||||
}
|
||||
|
||||
uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t));
|
||||
if (uscf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uscf->host = u->host;
|
||||
uscf->file_name = cf->conf_file->file.name;
|
||||
uscf->line = cf->conf_file->line;
|
||||
uscf->port = u->default_portn;
|
||||
|
||||
uscfp = ngx_array_push(&umcf->upstreams);
|
||||
if (uscfp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*uscfp = uscf;
|
||||
|
||||
return uscf;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
|
||||
{
|
||||
@ -2557,19 +2815,51 @@ ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&umcf->upstreams, cf->pool, 4,
|
||||
sizeof(ngx_http_upstream_srv_conf_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return umcf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
|
||||
ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf)
|
||||
{
|
||||
ngx_http_upstream_main_conf_t *umcf = conf;
|
||||
|
||||
ngx_array_t headers_in;
|
||||
ngx_hash_key_t *hk;
|
||||
ngx_hash_init_t hash;
|
||||
ngx_http_upstream_header_t *header;
|
||||
ngx_uint_t i;
|
||||
ngx_array_t headers_in;
|
||||
ngx_hash_key_t *hk;
|
||||
ngx_hash_init_t hash;
|
||||
ngx_http_upstream_header_t *header;
|
||||
ngx_http_upstream_srv_conf_t **uscfp;
|
||||
|
||||
uscfp = umcf->upstreams.elts;
|
||||
|
||||
for (i = 0; i < umcf->upstreams.nelts; i++) {
|
||||
if (uscfp[i]->peers) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uscfp[i]->peers = ngx_inet_resolve_peer(cf, &uscfp[i]->host,
|
||||
uscfp[i]->port);
|
||||
|
||||
if (uscfp[i]->peers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (uscfp[i]->peers == NGX_CONF_ERROR) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
|
||||
!= NGX_OK)
|
||||
|
@ -42,9 +42,25 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_t headers_in_hash;
|
||||
ngx_array_t upstreams;
|
||||
/* ngx_http_upstream_srv_conf_t */
|
||||
} ngx_http_upstream_main_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_peers_t *peers;
|
||||
|
||||
ngx_array_t *servers;
|
||||
|
||||
ngx_str_t host;
|
||||
ngx_str_t file_name;
|
||||
ngx_uint_t line;
|
||||
in_port_t port;
|
||||
|
||||
ngx_uint_t balanced; /* unsigned balanced:1; */
|
||||
} ngx_http_upstream_srv_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_msec_t connect_timeout;
|
||||
ngx_msec_t send_timeout;
|
||||
@ -199,6 +215,8 @@ struct ngx_http_upstream_s {
|
||||
|
||||
|
||||
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_url_t *u);
|
||||
|
||||
|
||||
extern ngx_module_t ngx_http_upstream_module;
|
||||
|
Loading…
Reference in New Issue
Block a user