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:
Igor Sysoev 2006-05-23 14:54:58 +00:00
parent e425c20bbe
commit 6f134cc275
19 changed files with 890 additions and 240 deletions

View File

@ -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">

View File

@ -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"

View File

@ -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

View File

@ -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>

View File

@ -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" );
}

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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++;
}
}

View File

@ -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, &params[NGX_HTTP_PERL_SSI_ARG],

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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;