summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES40
-rw-r--r--CHANGES.ru38
-rw-r--r--auto/options2
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/event/ngx_event_openssl.c97
-rw-r--r--src/event/ngx_event_openssl.h7
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c30
-rw-r--r--src/http/modules/ngx_http_geo_module.c157
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c176
-rw-r--r--src/http/modules/ngx_http_memcached_module.c17
-rw-r--r--src/http/modules/ngx_http_proxy_module.c27
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c2
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c1
-rw-r--r--src/http/modules/ngx_http_ssl_module.c50
-rw-r--r--src/http/modules/ngx_http_ssl_module.h1
-rw-r--r--src/http/modules/ngx_http_xslt_filter_module.c2
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_parse.c72
-rw-r--r--src/http/ngx_http_request.c26
-rw-r--r--src/http/ngx_http_request.h2
-rw-r--r--src/http/ngx_http_upstream.c42
-rw-r--r--src/http/ngx_http_upstream.h1
-rw-r--r--src/mail/ngx_mail_ssl_module.c32
23 files changed, 522 insertions, 306 deletions
diff --git a/CHANGES b/CHANGES
index 50001b277..cd2e3f68f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,42 @@
+Changes with nginx 0.8.7 27 Jul 2009
+
+ *) Change: minimum supported OpenSSL version is 0.9.7.
+
+ *) Change: the "ask" parameter of the "ssl_verify_client" directive was
+ changed to the "optional" parameter and now it checks a client
+ certificate if it was offered.
+ Thanks to Brice Figureau.
+
+ *) Feature: the $ssl_client_verify variable.
+ Thanks to Brice Figureau.
+
+ *) Feature: the "ssl_crl" directive.
+ Thanks to Brice Figureau.
+
+ *) Feature: the "proxy" parameter of the "geo" directive.
+
+ *) Feature: the "image_filter" directive supports variables for setting
+ size.
+
+ *) Bugfix: the $ssl_client_cert variable usage corrupted memory; the
+ bug had appeared in 0.7.7.
+ Thanks to Sergey Zhuravlev.
+
+ *) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did
+ not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate",
+ "X-Accel-Buffering", and "X-Accel-Charset" lines from backend
+ response header.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend
+ response header lines; the bug had appeared in 0.7.44.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: the "[alert] zero size buf" error if subrequest returns an
+ empty response; the bug had appeared in 0.8.5.
+
+
Changes with nginx 0.8.6 20 Jul 2009
*) Feature: the ngx_http_geoip_module.
@@ -8,7 +46,7 @@ Changes with nginx 0.8.6 20 Jul 2009
Thanks to Kuramoto Eiji.
*) Bugfix: now in MacOSX, Cygwin, and nginx/Windows locations given by
- a regular expression are always tested in case insensitive mode;
+ a regular expression are always tested in case insensitive mode.
*) Bugfix: now nginx/Windows ignores trailing dots in URI.
Thanks to Hugo Leisink.
diff --git a/CHANGES.ru b/CHANGES.ru
index 0ab59202d..5eb1033b3 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,42 @@
+Изменения в nginx 0.8.7 27.07.2009
+
+ *) Изменение: минимальная поддерживаемая версия OpenSSL - 0.9.7.
+
+ *) Изменение: параметр ask директивы ssl_verify_client изменён на
+ параметр optional и теперь он проверяет клиентский сертификат, если
+ он был предложен.
+ Спасибо Brice Figureau.
+
+ *) Добавление: переменная $ssl_client_verify.
+ Спасибо Brice Figureau.
+
+ *) Добавление: директива ssl_crl.
+ Спасибо Brice Figureau.
+
+ *) Добавление: параметр proxy директивы geo.
+
+ *) Добавление: директива image_filter поддерживает переменные для
+ задания размеров.
+
+ *) Исправление: использование переменной $ssl_client_cert портило
+ память; ошибка появилась в 0.7.7.
+ Спасибо Сергею Журавлёву.
+
+ *) Исправление: директивы proxy_pass_header и fastcgi_pass_header" не
+ передавали клиенту строки "X-Accel-Redirect", "X-Accel-Limit-Rate",
+ "X-Accel-Buffering" и "X-Accel-Charset" из заголовка ответа
+ бэкенда.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: в обработке строк "Last-Modified" и "Accept-Ranges" в
+ заголовке ответа бэкенда; ошибка появилась в 0.7.44
+ Спасибо Максиму Дунину.
+
+ *) Исправление: ошибки "[alert] zero size buf" при получении пустых
+ ответы в подзапросах; ошибка появилась в 0.8.5.
+
+
Изменения в nginx 0.8.6 20.07.2009
*) Добавление: модуль ngx_http_geoip_module.
diff --git a/auto/options b/auto/options
index 32328cbac..bc9e80917 100644
--- a/auto/options
+++ b/auto/options
@@ -312,7 +312,7 @@ cat << END
--with-http_addition_module enable ngx_http_addition_module
--with-http_xslt_module enable ngx_http_xslt_module
--with-http_image_filter_module enable ngx_http_image_filter_module
- --with-http_geoip_module enable ngx_http_geoip_link_module
+ --with-http_geoip_module enable ngx_http_geoip_module
--with-http_sub_module enable ngx_http_sub_module
--with-http_dav_module enable ngx_http_dav_module
--with-http_flv_module enable ngx_http_flv_module
diff --git a/src/core/nginx.h b/src/core/nginx.h
index f8761ff44..41b3a8933 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 8006
-#define NGINX_VERSION "0.8.6"
+#define nginx_version 8007
+#define NGINX_VERSION "0.8.7"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 1607814ce..846114077 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -97,16 +97,12 @@ int ngx_ssl_session_cache_index;
ngx_int_t
ngx_ssl_init(ngx_log_t *log)
{
-#if OPENSSL_VERSION_NUMBER >= 0x00907000
OPENSSL_config(NULL);
-#endif
SSL_library_init();
SSL_load_error_strings();
-#if (NGX_SSL_ENGINE)
ENGINE_load_builtin_engines();
-#endif
ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
@@ -169,9 +165,7 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
-#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
-#endif
SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE);
@@ -267,6 +261,51 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
}
+ngx_int_t
+ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
+{
+ X509_STORE *store;
+ X509_LOOKUP *lookup;
+
+ if (crl->len == 0) {
+ return NGX_OK;
+ }
+
+ if (ngx_conf_full_name(cf->cycle, crl, 1) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ store = SSL_CTX_get_cert_store(ssl->ctx);
+
+ if (store == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_CTX_get_cert_store() failed");
+ return NGX_ERROR;
+ }
+
+ lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
+
+ if (lookup == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "X509_STORE_add_lookup() failed");
+ return NGX_ERROR;
+ }
+
+ if (X509_LOOKUP_load_file(lookup, (char *) crl->data, X509_FILETYPE_PEM)
+ == 0)
+ {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "X509_LOOKUP_load_file(\"%s\") failed", crl->data);
+ return NGX_ERROR;
+ }
+
+ X509_STORE_set_flags(store,
+ X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+
+ return NGX_OK;
+}
+
+
static int
ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
{
@@ -1201,9 +1240,7 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
if (err == NGX_ECONNRESET
|| err == NGX_EPIPE
|| err == NGX_ENOTCONN
-#if !(NGX_CRIT_ETIMEDOUT)
|| err == NGX_ETIMEDOUT
-#endif
|| err == NGX_ECONNREFUSED
|| err == NGX_ENETDOWN
|| err == NGX_ENETUNREACH
@@ -1974,7 +2011,7 @@ ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
p = s->data;
- for (i = 0; i < len; i++) {
+ for (i = 0; i < cert.len - 1; i++) {
*p++ = cert.data[i];
if (cert.data[i] == LF) {
*p++ = '\t';
@@ -2108,6 +2145,35 @@ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
}
+ngx_int_t
+ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+ X509 *cert;
+
+ if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) {
+ s->len = sizeof("FAILED") - 1;
+ s->data = (u_char *) "FAILED";
+
+ return NGX_OK;
+ }
+
+ cert = SSL_get_peer_certificate(c->ssl->connection);
+
+ if (cert) {
+ s->len = sizeof("SUCCESS") - 1;
+ s->data = (u_char *) "SUCCESS";
+
+ } else {
+ s->len = sizeof("NONE") - 1;
+ s->data = (u_char *) "NONE";
+ }
+
+ X509_free(cert);
+
+ return NGX_OK;
+}
+
+
static void *
ngx_openssl_create_conf(ngx_cycle_t *cycle)
{
@@ -2131,7 +2197,6 @@ ngx_openssl_create_conf(ngx_cycle_t *cycle)
static char *
ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
-#if (NGX_SSL_ENGINE)
ngx_openssl_conf_t *oscf = conf;
ENGINE *engine;
@@ -2166,23 +2231,11 @@ ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ENGINE_free(engine);
return NGX_CONF_OK;
-
-#else
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"ssl_engine\" directive is available only in "
- "OpenSSL 0.9.7 and higher,");
-
- return NGX_CONF_ERROR;
-
-#endif
}
static void
ngx_openssl_exit(ngx_cycle_t *cycle)
{
-#if (NGX_SSL_ENGINE)
ENGINE_cleanup();
-#endif
}
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 1e83606fd..2b9dd284e 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -13,12 +13,8 @@
#include <openssl/ssl.h>
#include <openssl/err.h>
-
-#if OPENSSL_VERSION_NUMBER >= 0x00907000
#include <openssl/conf.h>
#include <openssl/engine.h>
-#define NGX_SSL_ENGINE 1
-#endif
#define NGX_SSL_NAME "OpenSSL"
@@ -100,6 +96,7 @@ ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_str_t *key);
ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_int_t depth);
+ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl);
ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
@@ -131,6 +128,8 @@ ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
+ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool,
+ ngx_str_t *s);
ngx_int_t ngx_ssl_handshake(ngx_connection_t *c);
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index abf02720a..1855e3ccb 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -543,19 +543,16 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
- if (f == NULL) {
- return NGX_ERROR;
+ if (ngx_http_upstream_create(r) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
-
- u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
- if (u == NULL) {
+ f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
+ if (f == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- r->upstream = u;
+ ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
@@ -565,15 +562,11 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
}
}
+ u = r->upstream;
+
u->schema.len = sizeof("fastcgi://") - 1;
u->schema.data = (u_char *) "fastcgi://";
- u->peer.log = r->connection->log;
- u->peer.log_error = NGX_ERROR_ERR;
-#if (NGX_THREADS)
- u->peer.lock = &r->connection->lock;
-#endif
-
u->output.tag = (ngx_buf_tag_t) &ngx_http_fastcgi_module;
u->conf = &flcf->upstream;
@@ -2438,8 +2431,13 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+
clcf->handler = ngx_http_fastcgi_handler;
+ if (clcf->name.data[clcf->name.len - 1] == '/') {
+ clcf->auto_redirect = 1;
+ }
+
value = cf->args->elts;
url = &value[1];
@@ -2475,10 +2473,6 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c
index a38985632..271b686d9 100644
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -35,6 +35,7 @@ typedef struct {
ngx_radix_tree_t *tree;
ngx_rbtree_t rbtree;
ngx_rbtree_node_t sentinel;
+ ngx_array_t *proxies;
ngx_pool_t *pool;
ngx_pool_t *temp_pool;
} ngx_http_geo_conf_ctx_t;
@@ -46,12 +47,16 @@ typedef struct {
ngx_http_geo_high_ranges_t *high;
} u;
+ ngx_array_t *proxies;
+
ngx_int_t index;
} ngx_http_geo_ctx_t;
static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r,
ngx_http_geo_ctx_t *ctx);
+static in_addr_t ngx_http_geo_real_addr(ngx_http_request_t *r,
+ ngx_http_geo_ctx_t *ctx);
static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
@@ -64,6 +69,10 @@ static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_str_t *value);
static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf,
ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value);
+static char *ngx_http_geo_add_proxy(ngx_conf_t *cf,
+ ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr);
+static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
+ ngx_cidr_t *cidr);
static ngx_command_t ngx_http_geo_commands[] = {
@@ -168,6 +177,50 @@ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
static in_addr_t
ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
{
+ u_char *p, *ip;
+ size_t len;
+ in_addr_t addr;
+ ngx_uint_t i, n;
+ ngx_in_cidr_t *proxies;
+ ngx_table_elt_t *xfwd;
+
+ addr = ngx_http_geo_real_addr(r, ctx);
+
+ xfwd = r->headers_in.x_forwarded_for;
+
+ if (xfwd == NULL || ctx->proxies == NULL) {
+ return addr;
+ }
+
+ proxies = ctx->proxies->elts;
+ n = ctx->proxies->nelts;
+
+ for (i = 0; i < n; i++) {
+ if ((addr & proxies[i].mask) == proxies[i].addr) {
+
+ len = xfwd->value.len;
+ ip = xfwd->value.data;
+
+ for (p = ip + len - 1; p > ip; p--) {
+ if (*p == ' ' || *p == ',') {
+ p++;
+ len -= p - ip;
+ ip = p;
+ break;
+ }
+ }
+
+ return ntohl(ngx_inet_addr(ip, len));
+ }
+ }
+
+ return addr;
+}
+
+
+static in_addr_t
+ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
+{
struct sockaddr_in *sin;
ngx_http_variable_value_t *v;
@@ -259,6 +312,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ctx.high = NULL;
ctx.tree = NULL;
+ ctx.proxies = NULL;
ctx.pool = cf->pool;
save = *cf;
@@ -271,6 +325,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
*cf = save;
+ geo->proxies = ctx.proxies;
+
if (ctx.high) {
for (i = 0; i < 0x10000; i++) {
@@ -341,6 +397,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
{
char *rv;
ngx_str_t *value, file;
+ ngx_cidr_t cidr;
ngx_http_geo_conf_ctx_t *ctx;
ctx = cf->ctx;
@@ -394,6 +451,16 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
rv = ngx_conf_parse(cf, &file);
goto done;
+
+ } else if (ngx_strcmp(value[0].data, "proxy") == 0) {
+
+ if (ngx_http_geo_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
+ goto failed;
+ }
+
+ rv = ngx_http_geo_add_proxy(cf, ctx, &cidr);
+
+ goto done;
}
if (ctx->high) {
@@ -803,33 +870,8 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
del = 0;
}
- if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
- cidr.u.in.addr = 0xffffffff;
- cidr.u.in.mask = 0xffffffff;
-
- } else {
- rc = ngx_ptocidr(net, &cidr);
-
- if (rc == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid network \"%V\"", net);
- return NGX_CONF_ERROR;
- }
-
- if (cidr.family != AF_INET) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"geo\" supports IPv4 only");
- return NGX_CONF_ERROR;
- }
-
- if (rc == NGX_DONE) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "low address bits of %V are meaningless",
- net);
- }
-
- cidr.u.in.addr = ntohl(cidr.u.in.addr);
- cidr.u.in.mask = ntohl(cidr.u.in.mask);
+ if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
+ return NGX_CONF_ERROR;
}
if (del) {
@@ -927,3 +969,64 @@ ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
return val;
}
+
+
+static char *
+ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
+ ngx_cidr_t *cidr)
+{
+ ngx_in_cidr_t *c;
+
+ if (ctx->proxies == NULL) {
+ ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_in_cidr_t));
+ if (ctx->proxies == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ c = ngx_array_push(ctx->proxies);
+ if (c == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ c->addr = cidr->u.in.addr;
+ c->mask = cidr->u.in.mask;
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
+{
+ ngx_int_t rc;
+
+ if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
+ cidr->u.in.addr = 0xffffffff;
+ cidr->u.in.mask = 0xffffffff;
+
+ return NGX_OK;
+ }
+
+ rc = ngx_ptocidr(net, cidr);
+
+ if (rc == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
+ return NGX_ERROR;
+ }
+
+ if (cidr->family != AF_INET) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"geo\" supports IPv4 only");
+ return NGX_ERROR;
+ }
+
+ if (rc == NGX_DONE) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "low address bits of %V are meaningless", net);
+ }
+
+ cidr->u.in.addr = ntohl(cidr->u.in.addr);
+ cidr->u.in.mask = ntohl(cidr->u.in.mask);
+
+ return NGX_OK;
+}
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index 469d703f6..4af2912c7 100644
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -40,6 +40,9 @@ typedef struct {
ngx_uint_t height;
ngx_int_t jpeg_quality;
+ ngx_http_complex_value_t *wcv;
+ ngx_http_complex_value_t *hcv;
+
size_t buffer_size;
} ngx_http_image_filter_conf_t;
@@ -53,6 +56,9 @@ typedef struct {
ngx_uint_t width;
ngx_uint_t height;
+ ngx_uint_t max_width;
+ ngx_uint_t max_height;
+
ngx_uint_t phase;
ngx_uint_t type;
} ngx_http_image_filter_ctx_t;
@@ -80,6 +86,9 @@ static gdImagePtr ngx_http_image_new(ngx_http_request_t *r, int w, int h,
static u_char *ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type,
gdImagePtr img, int *size);
static void ngx_http_image_cleanup(void *data);
+static ngx_uint_t ngx_http_image_filter_get_value(ngx_http_request_t *r,
+ ngx_http_complex_value_t *cv, ngx_uint_t v);
+static ngx_uint_t ngx_http_image_filter_value(ngx_str_t *value);
static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf);
@@ -454,7 +463,6 @@ ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in)
static ngx_buf_t *
ngx_http_image_process(ngx_http_request_t *r)
{
- ngx_buf_t *b;
ngx_int_t rc;
ngx_http_image_filter_ctx_t *ctx;
ngx_http_image_filter_conf_t *conf;
@@ -468,20 +476,28 @@ ngx_http_image_process(ngx_http_request_t *r)
conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
+ return ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL);
+ }
- b = ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL);
+ ctx->max_width = ngx_http_image_filter_get_value(r, conf->wcv, conf->width);
+ if (ctx->max_width == 0) {
+ return NULL;
+ }
- } else if (rc == NGX_OK
- && ctx->width <= conf->width
- && ctx->height <= conf->height)
- {
- b = ngx_http_image_asis(r, ctx);
+ ctx->max_height = ngx_http_image_filter_get_value(r, conf->hcv,
+ conf->height);
+ if (ctx->max_height == 0) {
+ return NULL;
+ }
- } else {
- b = ngx_http_image_resize(r, ctx);
+ if (rc == NGX_OK
+ && ctx->width <= ctx->max_width
+ && ctx->height <= ctx->max_height)
+ {
+ return ngx_http_image_asis(r, ctx);
}
- return b;
+ return ngx_http_image_resize(r, ctx);
}
@@ -682,7 +698,9 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
- if ((ngx_uint_t) sx <= conf->width && (ngx_uint_t) sy <= conf->height) {
+ if ((ngx_uint_t) sx <= ctx->max_width
+ && (ngx_uint_t) sy <= ctx->max_height)
+ {
gdImageDestroy(src);
return ngx_http_image_asis(r, ctx);
}
@@ -695,16 +713,16 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {
- if ((ngx_uint_t) dx > conf->width) {
- dy = dy * conf->width / dx;
+ if ((ngx_uint_t) dx > ctx->max_width) {
+ dy = dy * ctx->max_width / dx;
dy = dy ? dy : 1;
- dx = conf->width;
+ dx = ctx->max_width;
}
- if ((ngx_uint_t) dy > conf->height) {
- dx = dx * conf->height / dy;
+ if ((ngx_uint_t) dy > ctx->max_height) {
+ dx = dx * ctx->max_height / dy;
dx = dx ? dx : 1;
- dy = conf->height;
+ dy = ctx->max_height;
}
resize = 1;
@@ -713,20 +731,21 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
resize = 0;
- if ((ngx_uint_t) (dx * 100 / dy) < conf->width * 100 / conf->height) {
-
- if ((ngx_uint_t) dx > conf->width) {
- dy = dy * conf->width / dx;
+ if ((ngx_uint_t) (dx * 100 / dy)
+ < ctx->max_width * 100 / ctx->max_height)
+ {
+ if ((ngx_uint_t) dx > ctx->max_width) {
+ dy = dy * ctx->max_width / dx;
dy = dy ? dy : 1;
- dx = conf->width;
+ dx = ctx->max_width;
resize = 1;
}
} else {
- if ((ngx_uint_t) dy > conf->height) {
- dx = dx * conf->height / dy;
+ if ((ngx_uint_t) dy > ctx->max_height) {
+ dx = dx * ctx->max_height / dy;
dx = dx ? dx : 1;
- dy = conf->height;
+ dy = ctx->max_height;
resize = 1;
}
}
@@ -751,15 +770,15 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
src = dst;
- if ((ngx_uint_t) dx > conf->width) {
- ox = dx - conf->width;
+ if ((ngx_uint_t) dx > ctx->max_width) {
+ ox = dx - ctx->max_width;
} else {
ox = 0;
}
- if ((ngx_uint_t) dy > conf->height) {
- oy = dy - conf->height;
+ if ((ngx_uint_t) dy > ctx->max_height) {
+ oy = dy - ctx->max_height;
} else {
oy = 0;
@@ -941,6 +960,43 @@ ngx_http_image_cleanup(void *data)
}
+static ngx_uint_t
+ngx_http_image_filter_get_value(ngx_http_request_t *r,
+ ngx_http_complex_value_t *cv, ngx_uint_t v)
+{
+ ngx_str_t val;
+
+ if (cv == NULL) {
+ return v;
+ }
+
+ if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
+ return 0;
+ }
+
+ return ngx_http_image_filter_value(&val);
+}
+
+
+static ngx_uint_t
+ngx_http_image_filter_value(ngx_str_t *value)
+{
+ ngx_int_t n;
+
+ if (value->len == 1 && value->data[0] == '-') {
+ return (ngx_uint_t) -1;
+ }
+
+ n = ngx_atoi(value->data, value->len);
+
+ if (n > 0) {
+ return (ngx_uint_t) n;
+ }
+
+ return 0;
+}
+
+
static void *
ngx_http_image_filter_create_conf(ngx_conf_t *cf)
{
@@ -974,6 +1030,8 @@ ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
conf->filter = prev->filter;
conf->width = prev->width;
conf->height = prev->height;
+ conf->wcv = prev->wcv;
+ conf->hcv = prev->hcv;
}
}
@@ -992,9 +1050,11 @@ ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_image_filter_conf_t *imcf = conf;
- ngx_str_t *value;
- ngx_int_t n;
- ngx_uint_t i;
+ ngx_str_t *value;
+ ngx_int_t n;
+ ngx_uint_t i;
+ ngx_http_complex_value_t cv;
+ ngx_http_compile_complex_value_t ccv;
value = cf->args->elts;
@@ -1027,32 +1087,60 @@ ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
goto failed;
}
- i++;
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
- if (value[i].len == 1 && value[i].data[0] == '-') {
- imcf->width = (ngx_uint_t) -1;
+ ccv.cf = cf;
+ ccv.value = &value[++i];
+ ccv.complex_value = &cv;
- } else {
- n = ngx_atoi(value[i].data, value[i].len);
- if (n == NGX_ERROR) {
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cv.lengths == NULL) {
+ n = ngx_http_image_filter_value(&value[i]);
+
+ if (n == 0) {
goto failed;
}
imcf->width = (ngx_uint_t) n;
+
+ } else {
+ imcf->wcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+ if (imcf->wcv == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *imcf->wcv = cv;
}
- i++;
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
- if (value[i].len == 1 && value[i].data[0] == '-') {
- imcf->height = (ngx_uint_t) -1;
+ ccv.cf = cf;
+ ccv.value = &value[++i];
+ ccv.complex_value = &cv;
- } else {
- n = ngx_atoi(value[i].data, value[i].len);
- if (n == NGX_ERROR) {
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cv.lengths == NULL) {
+ n = ngx_http_image_filter_value(&value[i]);
+
+ if (n == 0) {
goto failed;
}
imcf->height = (ngx_uint_t) n;
+
+ } else {
+ imcf->hcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+ if (imcf->hcv == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *imcf->hcv = cv;
}
return NGX_CONF_OK;
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index e613a2079..dc7c76719 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -176,24 +176,19 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
-
- u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
- if (u == NULL) {
+ if (ngx_http_upstream_create(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ u = r->upstream;
+
u->schema.len = sizeof("memcached://") - 1;
u->schema.data = (u_char *) "memcached://";
- u->peer.log = r->connection->log;
- u->peer.log_error = NGX_ERROR_ERR;
-#if (NGX_THREADS)
- u->peer.lock = &r->connection->lock;
-#endif
-
u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;
+ mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
+
u->conf = &mlcf->upstream;
u->create_request = ngx_http_memcached_create_request;
@@ -202,8 +197,6 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
u->abort_request = ngx_http_memcached_abort_request;
u->finalize_request = ngx_http_memcached_finalize_request;
- r->upstream = u;
-
ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t));
if (ctx == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index f2d939ed7..88530e1db 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -590,13 +590,10 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
ngx_http_proxy_ctx_t *ctx;
ngx_http_proxy_loc_conf_t *plcf;
- u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
- if (u == NULL) {
+ if (ngx_http_upstream_create(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- r->upstream = u;
-
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@@ -606,6 +603,8 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
+ u = r->upstream;
+
if (plcf->proxy_lengths == 0) {
ctx->vars = plcf->vars;
u->schema = plcf->vars.schema;
@@ -619,12 +618,6 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
}
}
- u->peer.log = r->connection->log;
- u->peer.log_error = NGX_ERROR_ERR;
-#if (NGX_THREADS)
- u->peer.lock = &r->connection->lock;
-#endif
-
u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_module;
u->conf = &plcf->upstream;
@@ -2592,6 +2585,12 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+ clcf->handler = ngx_http_proxy_handler;
+
+ if (clcf->name.data[clcf->name.len - 1] == '/') {
+ clcf->auto_redirect = 1;
+ }
+
value = cf->args->elts;
url = &value[1];
@@ -2620,8 +2619,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
#endif
- clcf->handler = ngx_http_proxy_handler;
-
return NGX_CONF_OK;
}
@@ -2668,8 +2665,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_proxy_set_vars(&u, &plcf->vars);
- clcf->handler = ngx_http_proxy_handler;
-
plcf->location = clcf->name;
if (clcf->named
@@ -2693,10 +2688,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
plcf->url = *url;
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 840c05330..f7c138dbb 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -568,7 +568,7 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_script_if_code_t));
if (if_code == NULL) {
- return NULL;
+ return NGX_CONF_ERROR;
}
if_code->code = ngx_http_script_if_code;
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 97b58fa0a..24b30a8fa 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -360,6 +360,7 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
if (r == r->main) {
ngx_http_clear_content_length(r);
ngx_http_clear_last_modified(r);
+ ngx_http_clear_accept_ranges(r);
}
return ngx_http_next_header_filter(r);
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index c0fd6fdda..42854b479 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -31,15 +31,6 @@ static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
-
-static char *ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-static char ngx_http_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
-
-#endif
-
static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
{ ngx_string("SSLv2"), NGX_SSL_SSLv2 },
@@ -52,7 +43,7 @@ static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
static ngx_conf_enum_t ngx_http_ssl_verify[] = {
{ ngx_string("off"), 0 },
{ ngx_string("on"), 1 },
- { ngx_string("ask"), 2 },
+ { ngx_string("optional"), 2 },
{ ngx_null_string, 0 }
};
@@ -124,14 +115,10 @@ static ngx_command_t ngx_http_ssl_commands[] = {
{ ngx_string("ssl_prefer_server_ciphers"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
-#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
ngx_conf_set_flag_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
NULL },
-#else
- ngx_http_ssl_nosupported, 0, 0, ngx_http_ssl_openssl097 },
-#endif
{ ngx_string("ssl_session_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
@@ -147,6 +134,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
NULL },
+ { ngx_string("ssl_crl"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_ssl_srv_conf_t, crl),
+ NULL },
+
ngx_null_command
};
@@ -206,6 +200,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
{ ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
+ { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable,
+ (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
@@ -313,6 +310,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
* sscf->certificate_key = { 0, NULL };
* sscf->dhparam = { 0, NULL };
* sscf->client_certificate = { 0, NULL };
+ * sscf->crl = { 0, NULL };
* sscf->ciphers.len = 0;
* sscf->ciphers.data = NULL;
* sscf->shm_zone = NULL;
@@ -359,6 +357,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
"");
+ ngx_conf_merge_str_value(conf->crl, prev->crl, "");
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
@@ -453,16 +452,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
{
return NGX_CONF_ERROR;
}
- }
-#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
+ if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
if (conf->prefer_server_ciphers) {
SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
}
-#endif
-
/* a temporary 512-bit RSA key is required for export versions of MSIE */
if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
return NGX_CONF_ERROR;
@@ -620,18 +619,3 @@ invalid:
return NGX_CONF_ERROR;
}
-
-
-#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
-
-static char *
-ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" directive is available only in %s,",
- &cmd->name, cmd->post);
-
- return NGX_CONF_ERROR;
-}
-
-#endif
diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
index da7f04736..29eedc8ae 100644
--- a/src/http/modules/ngx_http_ssl_module.h
+++ b/src/http/modules/ngx_http_ssl_module.h
@@ -33,6 +33,7 @@ typedef struct {
ngx_str_t certificate_key;
ngx_str_t dhparam;
ngx_str_t client_certificate;
+ ngx_str_t crl;
ngx_str_t ciphers;
diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c
index ca9e15dc6..cfaa8e1b3 100644
--- a/src/http/modules/ngx_http_xslt_filter_module.c
+++ b/src/http/modules/ngx_http_xslt_filter_module.c
@@ -720,7 +720,7 @@ ngx_http_xslt_sax_error(void *data, const char *msg, ...)
while (--n && (buf[n] == CR || buf[n] == LF)) { /* void */ }
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
- "libxml2 error: \"%*s\"", n, buf);
+ "libxml2 error: \"%*s\"", n + 1, buf);
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index c8f77a466..75d0a1307 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.8.6';
+our $VERSION = '0.8.7';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 5bb6bb7cf..fd48fcdff 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -950,9 +950,6 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
sw_slash,
sw_dot,
sw_dot_dot,
-#if (NGX_WIN32)
- sw_dot_dot_dot,
-#endif
sw_quoted,
sw_quoted_second
} state, quoted_state;
@@ -1154,12 +1151,6 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
goto args;
case '#':
goto done;
-#if (NGX_WIN32)
- case '.':
- state = sw_dot_dot_dot;
- *u++ = ch;
- break;
-#endif
case '+':
r->plus_in_uri = 1;
default:
@@ -1171,55 +1162,6 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
ch = *p++;
break;
-#if (NGX_WIN32)
- case sw_dot_dot_dot:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- state = sw_usual;
- *u++ = ch;
- ch = *p++;
- break;
- }
-
- switch(ch) {
- case '\\':
- case '/':
- state = sw_slash;
- u -= 5;
- if (u < r->uri.data) {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- while (*u != '/') {
- u--;
- }
- if (u < r->uri.data) {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- while (*(u - 1) != '/') {
- u--;
- }
- break;
- case '%':
- quoted_state = state;
- state = sw_quoted;
- break;
- case '?':
- r->args_start = p;
- goto args;
- case '#':
- goto done;
- case '+':
- r->plus_in_uri = 1;
- default:
- state = sw_usual;
- *u++ = ch;
- break;
- }
-
- ch = *p++;
- break;
-#endif
-
case sw_quoted:
r->quoted_uri = 1;
@@ -1369,20 +1311,6 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
if (p[0] == '.' && p[1] == '.' && ngx_path_separator(p[2])) {
goto unsafe;
}
-
-#if (NGX_WIN32)
-
- if (len > 3) {
-
- /* detect "/.../" */
-
- if (p[0] == '.' && p[1] == '.' && p[2] == '.'
- && ngx_path_separator(p[3]))
- {
- goto unsafe;
- }
- }
-#endif
}
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index cc75939e6..4cd1d8f61 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -129,7 +129,7 @@ ngx_http_header_t ngx_http_headers_in[] = {
{ ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
ngx_http_process_header_line },
-#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP)
+#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
{ ngx_string("X-Forwarded-For"),
offsetof(ngx_http_headers_in_t, x_forwarded_for),
ngx_http_process_header_line },
@@ -384,6 +384,7 @@ ngx_http_init_request(ngx_event_t *rev)
r->loc_conf = cscf->ctx->loc_conf;
rev->handler = ngx_http_process_request_line;
+ r->read_event_handler = ngx_http_block_reading;
#if (NGX_HTTP_SSL)
@@ -1524,7 +1525,7 @@ ngx_http_process_request(ngx_http_request_t *r)
sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
- if (sscf->verify == 1) {
+ if (sscf->verify) {
rc = SSL_get_verify_result(c->ssl->connection);
if (rc != X509_V_OK) {
@@ -1539,20 +1540,22 @@ ngx_http_process_request(ngx_http_request_t *r)
return;
}
- cert = SSL_get_peer_certificate(c->ssl->connection);
+ if (sscf->verify == 1) {
+ cert = SSL_get_peer_certificate(c->ssl->connection);
- if (cert == NULL) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent no required SSL certificate");
+ if (cert == NULL) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent no required SSL certificate");
- ngx_ssl_remove_cached_session(sscf->ssl.ctx,
+ ngx_ssl_remove_cached_session(sscf->ssl.ctx,
(SSL_get0_session(c->ssl->connection)));
- ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
- return;
- }
+ ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
+ return;
+ }
- X509_free(cert);
+ X509_free(cert);
+ }
}
}
@@ -2715,6 +2718,7 @@ ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
b->last_buf = 1;
} else {
+ b->sync = 1;
b->last_in_chain = 1;
}
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index fd830b2a5..51f8419b4 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -184,7 +184,7 @@ typedef struct {
ngx_table_elt_t *keep_alive;
-#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP)
+#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
ngx_table_elt_t *x_forwarded_for;
#endif
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index cc303b431..23cf1b605 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -224,19 +224,19 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
{ ngx_string("X-Accel-Redirect"),
ngx_http_upstream_process_header_line,
offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect),
- ngx_http_upstream_ignore_header_line, 0, 0 },
+ ngx_http_upstream_copy_header_line, 0, 0 },
{ ngx_string("X-Accel-Limit-Rate"),
ngx_http_upstream_process_limit_rate, 0,
- ngx_http_upstream_ignore_header_line, 0, 0 },
+ ngx_http_upstream_copy_header_line, 0, 0 },
{ ngx_string("X-Accel-Buffering"),
ngx_http_upstream_process_buffering, 0,
- ngx_http_upstream_ignore_header_line, 0, 0 },
+ ngx_http_upstream_copy_header_line, 0, 0 },
{ ngx_string("X-Accel-Charset"),
ngx_http_upstream_process_charset, 0,
- ngx_http_upstream_ignore_header_line, 0, 0 },
+ ngx_http_upstream_copy_header_line, 0, 0 },
#if (NGX_HTTP_GZIP)
{ ngx_string("Content-Encoding"),
@@ -348,6 +348,35 @@ ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = {
};
+ngx_int_t
+ngx_http_upstream_create(ngx_http_request_t *r)
+{
+ ngx_http_upstream_t *u;
+
+ u = r->upstream;
+
+ if (u && u->cleanup) {
+ ngx_http_upstream_cleanup(r);
+ *u->cleanup = NULL;
+ }
+
+ u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
+ if (u == NULL) {
+ return NGX_ERROR;
+ }
+
+ r->upstream = u;
+
+ u->peer.log = r->connection->log;
+ u->peer.log_error = NGX_ERROR_ERR;
+#if (NGX_THREADS)
+ u->peer.lock = &r->connection->lock;
+#endif
+
+ return NGX_OK;
+}
+
+
void
ngx_http_upstream_init(ngx_http_request_t *r)
{
@@ -3301,10 +3330,11 @@ ngx_http_upstream_copy_last_modified(ngx_http_request_t *r, ngx_table_elt_t *h,
*ho = *h;
+ r->headers_out.last_modified = ho;
+
#if (NGX_HTTP_CACHE)
if (r->upstream->cacheable) {
- r->headers_out.last_modified = ho;
r->headers_out.last_modified_time = ngx_http_parse_time(h->value.data,
h->value.len);
}
@@ -3428,6 +3458,8 @@ ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
*ho = *h;
+ r->headers_out.accept_ranges = ho;
+
return NGX_OK;
}
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index fc777670e..ac2682d6f 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -317,6 +317,7 @@ typedef struct {
ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r);
void ngx_http_upstream_init(ngx_http_request_t *r);
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
ngx_url_t *u, ngx_uint_t flags);
diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c
index 1fcdb7559..025df54d7 100644
--- a/src/mail/ngx_mail_ssl_module.c
+++ b/src/mail/ngx_mail_ssl_module.c
@@ -22,15 +22,6 @@ static char *ngx_mail_ssl_starttls(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
-
-static char *ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-static char ngx_mail_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
-
-#endif
-
static ngx_conf_enum_t ngx_http_starttls_state[] = {
{ ngx_string("off"), NGX_MAIL_STARTTLS_OFF },
@@ -102,14 +93,10 @@ static ngx_command_t ngx_mail_ssl_commands[] = {
{ ngx_string("ssl_prefer_server_ciphers"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
-#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
ngx_conf_set_flag_slot,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, prefer_server_ciphers),
NULL },
-#else
- ngx_mail_ssl_nosupported, 0, 0, ngx_mail_ssl_openssl097 },
-#endif
{ ngx_string("ssl_session_cache"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
@@ -297,14 +284,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
}
}
-#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
-
if (conf->prefer_server_ciphers) {
SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
}
-#endif
-
if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
return NGX_CONF_ERROR;
}
@@ -492,18 +475,3 @@ invalid:
return NGX_CONF_ERROR;
}
-
-
-#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
-
-static char *
-ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" directive is available only in %s,",
- &cmd->name, cmd->post);
-
- return NGX_CONF_ERROR;
-}
-
-#endif