summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2006-12-13 15:07:11 +0000
committerJonathan Kolb <jon@b0g.us>2006-12-13 15:07:11 +0000
commitea13a13873ecf0057eb8542f0bdf9704b2082363 (patch)
tree7df8c0bae9581fadf801d8d9c8deed92fc997bfc
parent27175fa568b752df7e49b04fecdf6e473d72a30b (diff)
downloadnginx-ea13a13873ecf0057eb8542f0bdf9704b2082363.tar.gz
Changes with nginx 0.5.3 13 Dec 2006v0.5.3
*) Feature: the ngx_http_perl_module supports the $r->status, $r->log_error, and $r->sleep methods. *) Feature: the $r->variable method supports variables that do not exist in nginx configuration. *) Bugfix: the $r->has_request_body method did work.
-rw-r--r--CHANGES18
-rw-r--r--CHANGES.ru18
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_inet.c104
-rw-r--r--src/core/ngx_inet.h8
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c1
-rw-r--r--src/http/modules/ngx_http_log_module.c2
-rw-r--r--src/http/modules/ngx_http_memcached_module.c1
-rw-r--r--src/http/modules/ngx_http_proxy_module.c50
-rw-r--r--src/http/modules/perl/nginx.pm75
-rw-r--r--src/http/modules/perl/nginx.xs137
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c66
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.h11
-rw-r--r--src/http/ngx_http_core_module.c4
-rw-r--r--src/http/ngx_http_upstream.c29
-rw-r--r--src/http/ngx_http_upstream.h1
-rw-r--r--src/http/ngx_http_upstream_round_robin.c16
-rw-r--r--src/imap/ngx_imap_auth_http_module.c4
-rw-r--r--src/imap/ngx_imap_core_module.c4
19 files changed, 400 insertions, 151 deletions
diff --git a/CHANGES b/CHANGES
index 0752636e2..c04ca36f8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,22 @@
+Changes with nginx 0.5.3 13 Dec 2006
+
+ *) Feature: the ngx_http_perl_module supports the $r->status,
+ $r->log_error, and $r->sleep methods.
+
+ *) Feature: the $r->variable method supports variables that do not
+ exist in nginx configuration.
+
+ *) Bugfix: the $r->has_request_body method did work.
+
+
+Changes with nginx 0.5.2 11 Dec 2006
+
+ *) Bugfix: if the "proxy_pass" directive used the name of the
+ "upstream" block, then nginx tried to resolve the name; bug appeared
+ in 0.5.1.
+
+
Changes with nginx 0.5.1 11 Dec 2006
*) Bugfix: the "post_action" directive might not run after a
diff --git a/CHANGES.ru b/CHANGES.ru
index 80b6c6fa1..e7bb146eb 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,22 @@
+Изменения в nginx 0.5.3 13.12.2006
+
+ *) Добавление: модуль ngx_http_perl_module поддерживает методы
+ $r->status, $r->log_error и $r->sleep.
+
+ *) Добавление: метод $r->variable поддерживает переменные, неописанные
+ в конфигурации nginx'а.
+
+ *) Исправление: метод $r->has_request_body не работал.
+
+
+Изменения в nginx 0.5.2 11.12.2006
+
+ *) Исправление: если в директивах proxy_pass использовалось имя,
+ указанное в upstream, то nginx пытался найти IP-адрес этого имени;
+ ошибка появилась в 0.5.1.
+
+
Изменения в nginx 0.5.1 11.12.2006
*) Исправление: директива post_action могла не работать после
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 2a40c8240..e15cfe8b4 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.5.2"
+#define NGINX_VERSION "0.5.3"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
index 73209c7e0..09ff01418 100644
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -221,8 +221,8 @@ 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, *host;
- size_t len;
+ u_char *p, *host, *port_start;
+ size_t len, port_len;
ngx_int_t port;
ngx_uint_t i;
struct hostent *h;
@@ -290,8 +290,7 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
u->host.len = len;
u->host.data = p;
- u->host_header.len = sizeof("localhost") - 1;
- u->host_header.data = (u_char *) "localhost";
+ u->unix_socket = 1;
return NGX_OK;
@@ -309,17 +308,18 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
}
u->host.data = p;
- u->host_header.len = len;
- u->host_header.data = p;
+
+ port_start = NULL;
+ port_len = 0;
for (i = 0; i < len; i++) {
if (p[i] == ':') {
- u->port.data = &p[i + 1];
+ port_start = &p[i + 1];
u->host.len = i;
if (!u->uri_part) {
- u->port.len = len - (i + 1);
+ port_len = len - (i + 1);
break;
}
}
@@ -327,20 +327,19 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
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) {
+ if (port_start == NULL) {
u->no_port = 1;
goto no_port;
}
- u->port.len = &p[i] - u->port.data;
+ port_len = &p[i] - port_start;
- if (u->port.len == 0) {
+ if (port_len == 0) {
u->err = "invalid port";
return NGX_ERROR;
}
@@ -349,18 +348,18 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
}
}
- if (u->port.data) {
+ if (port_start) {
- if (u->port.len == 0) {
- u->port.len = &p[i] - u->port.data;
+ if (port_len == 0) {
+ port_len = &p[i] - port_start;
- if (u->port.len == 0) {
+ if (port_len == 0) {
u->err = "invalid port";
return NGX_ERROR;
}
}
- port = ngx_atoi(u->port.data, u->port.len);
+ port = ngx_atoi(port_start, port_len);
if (port == NGX_ERROR || port < 1 || port > 65536) {
u->err = "invalid port";
@@ -377,24 +376,22 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
goto no_port;
}
- u->port.len = len;
- u->port.data = p;
u->wildcard = 1;
}
- u->portn = (in_port_t) port;
+ u->port = (in_port_t) port;
no_port:
if (u->listen) {
- if (u->portn == 0) {
- if (u->default_portn == 0) {
+ if (u->port == 0) {
+ if (u->default_port == 0) {
u->err = "no port";
return NGX_ERROR;
}
- u->portn = u->default_portn;
+ u->port = u->default_port;
}
if (u->host.len == 1 && u->host.data[0] == '*') {
@@ -422,7 +419,7 @@ no_port:
return NGX_ERROR;
}
- u->addr.in_addr = *(in_addr_t *)(h->h_addr_list[0]);
+ u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
}
} else {
@@ -432,28 +429,6 @@ no_port:
return NGX_OK;
}
- if (u->no_port) {
-
- if (u->default_portn == 0 && !u->upstream) {
- 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 == 0) {
-
- u->err = "no port";
- return NGX_ERROR;
- }
-
if (u->host.len == 0) {
u->err = "no host";
return NGX_ERROR;
@@ -463,6 +438,15 @@ no_port:
return NGX_OK;
}
+ if (u->no_port) {
+ u->port = u->default_port;
+ }
+
+ if (u->port == 0) {
+ u->err = "no port";
+ return NGX_ERROR;
+ }
+
if (ngx_inet_resolve_host(cf, u) != NGX_OK) {
return NGX_ERROR;
}
@@ -474,7 +458,7 @@ no_port:
ngx_int_t
ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
{
- u_char *host;
+ u_char *p, *host;
size_t len;
in_addr_t in_addr;
ngx_uint_t i;
@@ -524,7 +508,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
}
sin->sin_family = AF_INET;
- sin->sin_port = htons(u->portn);
+ sin->sin_port = htons(u->port);
sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
u->addrs[i].sockaddr = (struct sockaddr *) sin;
@@ -532,17 +516,15 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
- u->addrs[i].name.data = ngx_palloc(cf->pool, len);
- if (u->addrs[i].name.data == NULL) {
+ p = ngx_palloc(cf->pool, len);
+ if (p == NULL) {
return NGX_ERROR;
}
- len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin,
- u->addrs[i].name.data, len);
+ len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin, p, len);
- u->addrs[i].name.len = ngx_sprintf(&u->addrs[i].name.data[len],
- ":%d", u->portn)
- - u->addrs[i].name.data;
+ u->addrs[i].name.len = ngx_sprintf(&p[len], ":%d", u->port) - p;
+ u->addrs[i].name.data = p;
}
} else {
@@ -562,21 +544,19 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
u->naddrs = 1;
sin->sin_family = AF_INET;
- sin->sin_port = htons(u->portn);
+ sin->sin_port = htons(u->port);
sin->sin_addr.s_addr = in_addr;
u->addrs[0].sockaddr = (struct sockaddr *) sin;
u->addrs[0].socklen = sizeof(struct sockaddr_in);
- u->addrs[0].name.data = ngx_palloc(cf->pool,
- u->host.len + sizeof(":65536") - 1);
- if (u->addrs[0].name.data == NULL) {
+ p = ngx_palloc(cf->pool, u->host.len + sizeof(":65536") - 1);
+ if (p == NULL) {
return NGX_ERROR;
}
- u->addrs[0].name.len = ngx_sprintf(u->addrs[0].name.data, "%V:%d",
- &u->host, u->portn)
- - u->addrs[0].name.data;
+ u->addrs[0].name.len = ngx_sprintf(p, "%V:%d", &u->host, u->port) - p;
+ u->addrs[0].name.data = p;
}
return NGX_OK;
diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h
index 94f195f99..9079e37d0 100644
--- a/src/core/ngx_inet.h
+++ b/src/core/ngx_inet.h
@@ -35,21 +35,19 @@ typedef struct {
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;
+ in_port_t port;
+ in_port_t default_port;
unsigned listen:1;
unsigned uri_part:1;
- unsigned upstream:1;
unsigned no_resolve:1;
unsigned one_addr:1;
unsigned wildcard:1;
unsigned no_port:1;
+ unsigned unix_socket:1;
ngx_url_addr_t addr;
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index fdefb835c..ab214770e 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2010,7 +2010,6 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_memzero(&u, sizeof(ngx_url_t));
u.url = value[1];
- u.upstream = 1;
u.no_resolve = 1;
lcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index c035449ff..04ba03bff 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -546,6 +546,8 @@ ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
+ log->disk_full_time = 0;
+
lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
fmt = lmcf->formats.elts;
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index 5265c38cf..bd8b83716 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -583,7 +583,6 @@ ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_memzero(&u, sizeof(ngx_url_t));
u.url = value[1];
- u.upstream = 1;
u.no_resolve = 1;
/* u.uri_part = 1; may be used as namespace */
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index dbca2ab54..2c26df901 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -51,7 +51,7 @@ typedef struct {
ngx_str_t method;
ngx_str_t host_header;
- ngx_str_t port_text;
+ ngx_str_t port;
ngx_flag_t redirect;
} ngx_http_proxy_loc_conf_t;
@@ -1232,11 +1232,11 @@ ngx_http_proxy_port_variable(ngx_http_request_t *r,
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
- v->len = plcf->port_text.len;
+ v->len = plcf->port.len;
v->valid = 1;
v->no_cachable = 0;
v->not_found = 0;
- v->data = plcf->port_text.data;
+ v->data = plcf->port.data;
return NGX_OK;
}
@@ -1817,7 +1817,7 @@ peers:
conf->upstream.upstream = prev->upstream.upstream;
conf->host_header = prev->host_header;
- conf->port_text = prev->port_text;
+ conf->port = prev->port;
conf->upstream.schema = prev->upstream.schema;
}
@@ -2093,6 +2093,7 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_proxy_loc_conf_t *plcf = conf;
+ u_char *p;
size_t add;
u_short port;
ngx_str_t *value, *url;
@@ -2158,18 +2159,49 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
u.url.len = url->len - add;
u.url.data = url->data + add;
- u.default_portn = port;
- u.upstream = 1;
- u.no_resolve = 1;
+ u.default_port = port;
u.uri_part = 1;
+ u.no_resolve = 1;
plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
if (plcf->upstream.upstream == NULL) {
return NGX_CONF_ERROR;
}
- plcf->host_header = u.host_header;
- plcf->port_text = u.port;
+ if (!u.unix_socket) {
+ if (u.no_port || u.port == port) {
+ plcf->host_header = u.host;
+
+ if (port == 80) {
+ plcf->port.len = sizeof("80") - 1;
+ plcf->port.data = (u_char *) "80";
+ } else {
+ plcf->port.len = sizeof("443") - 1;
+ plcf->port.data = (u_char *) "443";
+ }
+
+ } else {
+ p = ngx_palloc(cf->pool, u.host.len + sizeof(":65536") - 1);
+ if (p == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ plcf->host_header.len = ngx_sprintf(p, "%V:%d", &u.host, u.port)
+ - p;
+ plcf->host_header.data = p;
+
+ plcf->port.len = plcf->host_header.len - u.host.len - 1;
+ plcf->port.data = p + u.host.len + 1;
+ }
+
+
+ } else {
+ plcf->host_header.len = sizeof("localhost") - 1;
+ plcf->host_header.data = (u_char *) "localhost";
+ plcf->port.len = 0;
+ plcf->port.data = (u_char *) "";
+ }
+
plcf->upstream.uri = u.uri;
plcf->upstream.schema.len = add;
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 9a3868c87..2f6a66306 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -11,26 +11,85 @@ our @ISA = qw(Exporter);
our @EXPORT = qw(
OK
DECLINED
+
HTTP_OK
+ HTTP_CREATED
+ HTTP_NO_CONTENT
+ HTTP_PARTIAL_CONTENT
+
+ HTTP_MOVED_PERMANENTLY
+ HTTP_MOVED_TEMPORARILY
HTTP_REDIRECT
+ HTTP_NOT_MODIFIED
+
+ HTTP_BAD_REQUEST
+ HTTP_UNAUTHORIZED
+ HTTP_PAYMENT_REQUIRED
+ HTTP_FORBIDDEN
HTTP_NOT_FOUND
+ HTTP_NOT_ALLOWED
+ HTTP_NOT_ACCEPTABLE
+ HTTP_REQUEST_TIME_OUT
+ HTTP_CONFLICT
+ HTTP_GONE
+ HTTP_LENGTH_REQUIRED
+ HTTP_REQUEST_ENTITY_TOO_LARGE
+ HTTP_REQUEST_URI_TOO_LARGE
+ HTTP_UNSUPPORTED_MEDIA_TYPE
+ HTTP_RANGE_NOT_SATISFIABLE
+
+ HTTP_INTERNAL_SERVER_ERROR
HTTP_SERVER_ERROR
+ HTTP_NOT_IMPLEMENTED
+ HTTP_BAD_GATEWAY
+ HTTP_SERVICE_UNAVAILABLE
+ HTTP_GATEWAY_TIME_OUT
+ HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.5.2';
+our $VERSION = '0.5.3';
require XSLoader;
XSLoader::load('nginx', $VERSION);
# Preloaded methods go here.
-use constant OK => 0;
-use constant DECLINED => -5;
-
-use constant HTTP_OK => 200;
-use constant HTTP_REDIRECT => 302;
-use constant HTTP_NOT_FOUND => 404;
-use constant HTTP_SERVER_ERROR => 500;
+use constant OK => 0;
+use constant DECLINED => -5;
+
+use constant HTTP_OK => 200;
+use constant HTTP_CREATED => 201;
+use constant HTTP_NO_CONTENT => 204;
+use constant HTTP_PARTIAL_CONTENT => 206;
+
+use constant HTTP_MOVED_PERMANENTLY => 301;
+use constant HTTP_MOVED_TEMPORARILY => 302;
+use constant HTTP_REDIRECT => 302;
+use constant HTTP_NOT_MODIFIED => 304;
+
+use constant HTTP_BAD_REQUEST => 400;
+use constant HTTP_UNAUTHORIZED => 401;
+use constant HTTP_PAYMENT_REQUIRED => 402;
+use constant HTTP_FORBIDDEN => 403;
+use constant HTTP_NOT_FOUND => 404;
+use constant HTTP_NOT_ALLOWED => 405;
+use constant HTTP_NOT_ACCEPTABLE => 406;
+use constant HTTP_REQUEST_TIME_OUT => 408;
+use constant HTTP_CONFLICT => 409;
+use constant HTTP_GONE => 410;
+use constant HTTP_LENGTH_REQUIRED => 411;
+use constant HTTP_REQUEST_ENTITY_TOO_LARGE => 413;
+use constant HTTP_REQUEST_URI_TOO_LARGE => 414;
+use constant HTTP_UNSUPPORTED_MEDIA_TYPE => 415;
+use constant HTTP_RANGE_NOT_SATISFIABLE => 416;
+
+use constant HTTP_INTERNAL_SERVER_ERROR => 500;
+use constant HTTP_SERVER_ERROR => 500;
+use constant HTTP_NOT_IMPLEMENTED => 501;
+use constant HTTP_BAD_GATEWAY => 502;
+use constant HTTP_SERVICE_UNAVAILABLE => 503;
+use constant HTTP_GATEWAY_TIME_OUT => 504;
+use constant HTTP_INSUFFICIENT_STORAGE => 507;
1;
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index 90b4c57a9..558922c38 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -94,6 +94,22 @@ MODULE = nginx PACKAGE = nginx
void
+status(r, code)
+ CODE:
+
+ ngx_http_request_t *r;
+
+ ngx_http_perl_set_request(r);
+
+ r->headers_out.status = SvIV(ST(1));
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "perl status: %d", r->headers_out.status);
+
+ XSRETURN_UNDEF;
+
+
+void
send_http_header(r, ...)
CODE:
@@ -334,7 +350,6 @@ has_request_body(r, next)
dXSTARG;
ngx_http_request_t *r;
- SV *next;
ngx_http_perl_ctx_t *ctx;
ngx_http_perl_set_request(r);
@@ -343,10 +358,8 @@ has_request_body(r, next)
XSRETURN_UNDEF;
}
- next = ST(1);
-
ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
- ctx->next = next;
+ ctx->next = SvRV(ST(1));
r->request_body_in_single_buf = 1;
r->request_body_in_persistent_file = 1;
@@ -776,6 +789,8 @@ variable(r, name, value = NULL)
STRLEN len;
ngx_str_t var, val;
ngx_uint_t i, hash;
+ ngx_http_perl_var_t *v;
+ ngx_http_perl_ctx_t *ctx;
ngx_http_variable_value_t *vv;
ngx_http_perl_set_request(r);
@@ -817,13 +832,69 @@ variable(r, name, value = NULL)
var.len = len;
var.data = lowcase;
+ #if (NGX_LOG_DEBUG)
+
+ if (value) {
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "perl variable: \"%V\"=\"%V\"", &var, &val);
+ } else {
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "perl variable: \"%V\"", &var);
+ }
+
+ #endif
+
vv = ngx_http_get_variable(r, &var, hash, 1);
if (vv == NULL) {
XSRETURN_UNDEF;
}
if (vv->not_found) {
- if (value == NULL) {
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
+
+ if (ctx->variables) {
+
+ v = ctx->variables->elts;
+ for (i = 0; i < ctx->variables->nelts; i++) {
+
+ if (hash != v[i].hash
+ || len != v[i].name.len
+ || ngx_strncmp(lowcase, v[i].name.data, len) != 0)
+ {
+ continue;
+ }
+
+ if (value) {
+ v[i].value = val;
+ XSRETURN_UNDEF;
+ }
+
+ ngx_http_perl_set_targ(v[i].value.data, v[i].value.len, 0);
+
+ goto done;
+ }
+ }
+
+ if (value) {
+ if (ctx->variables == NULL) {
+ ctx->variables = ngx_array_create(r->pool, 1,
+ sizeof(ngx_http_perl_var_t));
+ if (ctx->variables == NULL) {
+ XSRETURN_UNDEF;
+ }
+ }
+
+ v = ngx_array_push(ctx->variables);
+ if (v == NULL) {
+ XSRETURN_UNDEF;
+ }
+
+ v->hash = hash;
+ v->name.len = len;
+ v->name.data = lowcase;
+ v->value = val;
+
XSRETURN_UNDEF;
}
@@ -845,4 +916,60 @@ variable(r, name, value = NULL)
ngx_http_perl_set_targ(vv->data, vv->len, 0);
+ done:
+
ST(0) = TARG;
+
+
+void
+sleep(r, sleep, next)
+ CODE:
+
+ dXSTARG;
+ ngx_http_request_t *r;
+ ngx_http_perl_ctx_t *ctx;
+
+ ngx_http_perl_set_request(r);
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
+
+ ctx->sleep = SvIV(ST(1));
+ ctx->next = SvRV(ST(2));
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "perl sleep: %d", ctx->sleep);
+
+ XSRETURN_EMPTY;
+
+
+void
+log_error(r, err, msg)
+ CODE:
+
+ ngx_http_request_t *r;
+ SV *err, *msg;
+ u_char *p;
+ STRLEN len;
+ ngx_err_t e;
+
+ ngx_http_perl_set_request(r);
+
+ err = ST(1);
+
+ if (SvROK(err) && SvTYPE(SvRV(err)) == SVt_PV) {
+ err = SvRV(err);
+ }
+
+ e = SvIV(err);
+
+ msg = ST(2);
+
+ if (SvROK(msg) && SvTYPE(SvRV(msg)) == SVt_PV) {
+ msg = SvRV(msg);
+ }
+
+ p = (u_char *) SvPV(msg, len);
+
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, e, "perl: %s", p);
+
+ XSRETURN_EMPTY;
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index e460550d7..fb1642051 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -41,6 +41,7 @@ static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r,
ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params);
#endif
+static void ngx_http_perl_sleep_handler(ngx_http_request_t *r);
static char *ngx_http_perl_init_interpreter(ngx_conf_t *cf,
ngx_http_perl_main_conf_t *pmcf);
static PerlInterpreter *
@@ -62,7 +63,6 @@ static char *ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static void ngx_http_perl_cleanup_sv(void *data);
#if (NGX_HAVE_PERL_MULTIPLICITY)
static void ngx_http_perl_cleanup_perl(void *data);
@@ -246,6 +246,12 @@ ngx_http_perl_handle_request(ngx_http_request_t *r)
ctx->filename.data = NULL;
ctx->redirect_uri.len = 0;
+ if (ctx->sleep) {
+ ngx_add_timer(r->connection->write, (ngx_msec_t) ctx->sleep);
+ r->write_event_handler = ngx_http_perl_sleep_handler;
+ ctx->sleep = 0;
+ }
+
if (ctx->done || ctx->next) {
return;
}
@@ -264,6 +270,28 @@ ngx_http_perl_handle_request(ngx_http_request_t *r)
}
+static void
+ngx_http_perl_sleep_handler(ngx_http_request_t *r)
+{
+ ngx_event_t *wev;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "perl sleep handler");
+
+ wev = r->connection->write;
+
+ if (wev->timedout) {
+ wev->timedout = 0;
+ ngx_http_perl_handle_request(r);
+ return;
+ }
+
+ if (ngx_handle_write_event(wev, 0) == NGX_ERROR) {
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ }
+}
+
+
static ngx_int_t
ngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
uintptr_t data)
@@ -758,18 +786,6 @@ ngx_http_perl_cleanup_perl(void *data)
#endif
-static void
-ngx_http_perl_cleanup_sv(void *data)
-{
- ngx_http_perl_cleanup_t *cln = data;
-
- dTHXa(cln->perl);
- PERL_SET_CONTEXT(cln->perl);
-
- SvREFCNT_dec(cln->sv);
-}
-
-
static ngx_int_t
ngx_http_perl_preconfiguration(ngx_conf_t *cf)
{
@@ -860,8 +876,6 @@ ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_perl_loc_conf_t *plcf = conf;
ngx_str_t *value;
- ngx_pool_cleanup_t *cln;
- ngx_http_perl_cleanup_t *pcln;
ngx_http_core_loc_conf_t *clcf;
ngx_http_perl_main_conf_t *pmcf;
@@ -881,11 +895,6 @@ ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
- cln = ngx_pool_cleanup_add(cf->pool, sizeof(ngx_http_perl_cleanup_t));
- if (cln == NULL) {
- return NGX_CONF_ERROR;
- }
-
plcf->handler = value[1];
{
@@ -907,11 +916,6 @@ ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
- cln->handler = ngx_http_perl_cleanup_sv;
- pcln = cln->data;
- pcln->sv = plcf->sub;
- pcln->perl = pmcf->perl;
-
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_perl_handler;
@@ -924,9 +928,7 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_int_t index;
ngx_str_t *value;
- ngx_pool_cleanup_t *cln;
ngx_http_variable_t *v;
- ngx_http_perl_cleanup_t *pcln;
ngx_http_perl_variable_t *pv;
ngx_http_perl_main_conf_t *pmcf;
@@ -964,11 +966,6 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
- cln = ngx_pool_cleanup_add(cf->pool, sizeof(ngx_http_perl_cleanup_t));
- if (cln == NULL) {
- return NGX_CONF_ERROR;
- }
-
pv->handler = value[2];
{
@@ -990,11 +987,6 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
- cln->handler = ngx_http_perl_cleanup_sv;
- pcln = cln->data;
- pcln->sv = pv->sub;
- pcln->perl = pmcf->perl;
-
v->get_handler = ngx_http_perl_variable;
v->data = (uintptr_t) pv;
diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h
index af23f9ef7..6ae63e820 100644
--- a/src/http/modules/perl/ngx_http_perl_module.h
+++ b/src/http/modules/perl/ngx_http_perl_module.h
@@ -23,16 +23,27 @@ typedef struct {
ngx_str_t filename;
ngx_str_t redirect_uri;
ngx_str_t redirect_args;
+
SV *next;
+ int sleep;
ngx_uint_t done; /* unsigned done:1; */
+ ngx_array_t *variables; /* array of ngx_http_perl_var_t */
+
#if (NGX_HTTP_SSI)
ngx_http_ssi_ctx_t *ssi;
#endif
} ngx_http_perl_ctx_t;
+typedef struct {
+ ngx_uint_t hash;
+ ngx_str_t name;
+ ngx_str_t value;
+} ngx_http_perl_var_t;
+
+
extern ngx_module_t ngx_http_perl_module;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 7f12daef1..34149c49f 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -2390,7 +2390,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
u.url = value[1];
u.listen = 1;
- u.default_portn = 80;
+ u.default_port = 80;
if (ngx_parse_url(cf, &u) != NGX_OK) {
if (u.err) {
@@ -2411,7 +2411,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ls->family = AF_INET;
ls->addr = u.addr.in_addr;
- ls->port = u.portn;
+ ls->port = u.port;
ls->file_name = cf->conf_file->file.name;
ls->line = cf->conf_file->line;
ls->conf.backlog = -1;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index a917dcf49..00fa4575e 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2598,7 +2598,6 @@ ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
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
@@ -2722,7 +2721,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_memzero(&u, sizeof(ngx_url_t));
u.url = value[1];
- u.default_portn = 80;
+ u.default_port = 80;
if (ngx_parse_url(cf, &u) != NGX_OK) {
if (u.err) {
@@ -2843,8 +2842,8 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
uscfp = umcf->upstreams.elts;
for (i = 0; i < umcf->upstreams.nelts; i++) {
- if ((uscfp[i]->port && uscfp[i]->port != u->portn)
- || 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)
{
@@ -2859,10 +2858,23 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
return NULL;
}
- if (uscfp[i]->port == 0 && u->portn && !u->no_port) {
+ if ((uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE) && u->port) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "upstream \"%V\" port %d is ignored",
- &u->host, u->portn);
+ "upstream \"%V\" may not have port %d",
+ &u->host, u->port);
+ return NULL;
+ }
+
+ if ((flags & NGX_HTTP_UPSTREAM_CREATE) && uscfp[i]->port) {
+ ngx_log_error(NGX_LOG_WARN, cf->log, 0,
+ "upstream \"%V\" may not have port %d in %s:%ui",
+ &u->host, uscfp[i]->port,
+ uscfp[i]->file_name.data, uscfp[i]->line);
+ return NULL;
+ }
+
+ if (uscfp[i]->port != u->port) {
+ continue;
}
return uscfp[i];
@@ -2877,7 +2889,8 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
uscf->host = u->host;
uscf->file_name = cf->conf_file->file.name;
uscf->line = cf->conf_file->line;
- uscf->port = u->portn;
+ uscf->port = u->port;
+ uscf->default_port = u->default_port;
if (u->naddrs == 1) {
uscf->servers = ngx_array_create(cf->pool, 1,
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index 185964e2c..aa5cc3518 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -94,6 +94,7 @@ struct ngx_http_upstream_srv_conf_s {
ngx_str_t file_name;
ngx_uint_t line;
in_port_t port;
+ in_port_t default_port;
};
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index 82173e4b0..359a73624 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -61,10 +61,17 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
/* an upstream implicitly defined by proxy_pass, etc. */
+ if (us->port == 0 && us->default_port == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no port in upstream \"%V\" in %s:%ui",
+ &us->host, us->file_name.data, us->line);
+ return NGX_ERROR;
+ }
+
ngx_memzero(&u, sizeof(ngx_url_t));
u.host = us->host;
- u.portn = us->port;
+ u.port = (in_port_t) (us->port ? us->port : us->default_port);
if (ngx_inet_resolve_host(cf, &u) != NGX_OK) {
if (u.err) {
@@ -76,13 +83,6 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
return NGX_ERROR;
}
- if (us->port == 0) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no port in upstream \"%V\" in %s:%ui",
- &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)
diff --git a/src/imap/ngx_imap_auth_http_module.c b/src/imap/ngx_imap_auth_http_module.c
index e1518b8c3..668a952fa 100644
--- a/src/imap/ngx_imap_auth_http_module.c
+++ b/src/imap/ngx_imap_auth_http_module.c
@@ -1291,7 +1291,7 @@ ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_memzero(&u, sizeof(ngx_url_t));
u.url = value[1];
- u.default_portn = 80;
+ u.default_port = 80;
u.uri_part = 1;
u.one_addr = 1;
@@ -1304,7 +1304,7 @@ ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ahcf->peer = u.addrs;
- ahcf->host_header = u.host_header;
+ ahcf->host_header = u.host;
ahcf->uri = u.uri;
if (ahcf->uri.len == 0) {
diff --git a/src/imap/ngx_imap_core_module.c b/src/imap/ngx_imap_core_module.c
index 3cd3991ba..99aa9cc1d 100644
--- a/src/imap/ngx_imap_core_module.c
+++ b/src/imap/ngx_imap_core_module.c
@@ -541,7 +541,7 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
for (i = 0; i < cmcf->listen.nelts; i++) {
- if (imls[i].addr != u.addr.in_addr || imls[i].port != u.portn) {
+ if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) {
continue;
}
@@ -558,7 +558,7 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_memzero(imls, sizeof(ngx_imap_listen_t));
imls->addr = u.addr.in_addr;
- imls->port = u.portn;
+ imls->port = u.port;
imls->family = AF_INET;
imls->ctx = cf->ctx;