summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2011-08-01 14:54:44 +0000
committerJonathan Kolb <jon@b0g.us>2011-08-01 14:54:44 +0000
commit0b76d8bdf4e6afd8a695ce6112eec2abbd888aa8 (patch)
treea0c5da94e97715f284207856ffc93e6139fd3343
parent027ef10992914a8a09077f21c76768c842b22f98 (diff)
downloadnginx-0b76d8bdf4e6afd8a695ce6112eec2abbd888aa8.tar.gz
Changes with nginx 1.1.0 01 Aug 2011v1.1.0
*) Feature: cache loader run time decrease. *) Feature: "loader_files", "loader_sleep", and "loader_threshold" options of the "proxy/fastcgi/scgi/uwsgi_cache_path" directives. *) Feature: loading time decrease of configuration with large number of HTTPS sites. *) Feature: now nginx supports ECDHE key exchange ciphers. Thanks to Adrian Kotelba. *) Feature: the "lingering_close" directive. Thanks to Maxim Dounin. *) Bugfix: in closing connection for pipelined requests. Thanks to Maxim Dounin. *) Bugfix: nginx did not disable gzipping if client sent "gzip;q=0" in "Accept-Encoding" request header line. *) Bugfix: in timeout in unbuffered proxied mode. Thanks to Maxim Dounin. *) Bugfix: memory leaks when a "proxy_pass" directive contains variables and proxies to an HTTPS backend. Thanks to Maxim Dounin. *) Bugfix: in parameter validaiton of a "proxy_pass" directive with variables. Thanks to Lanshun Zhou. *) Bugfix: SSL did not work on QNX. Thanks to Maxim Dounin. *) Bugfix: SSL modules could not be built by gcc 4.6 without --with-debug option.
-rw-r--r--CHANGES46
-rw-r--r--CHANGES.ru40
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_config.h2
-rw-r--r--src/core/ngx_file.c1
-rw-r--r--src/core/ngx_file.h1
-rw-r--r--src/event/ngx_event_openssl.c81
-rw-r--r--src/event/ngx_event_openssl.h3
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c2
-rw-r--r--src/http/modules/ngx_http_proxy_module.c12
-rw-r--r--src/http/modules/ngx_http_scgi_module.c2
-rw-r--r--src/http/modules/ngx_http_ssl_module.c20
-rw-r--r--src/http/modules/ngx_http_ssl_module.h1
-rw-r--r--src/http/modules/ngx_http_uwsgi_module.c2
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_cache.h5
-rw-r--r--src/http/ngx_http_core_module.c175
-rw-r--r--src/http/ngx_http_core_module.h6
-rw-r--r--src/http/ngx_http_file_cache.c176
-rw-r--r--src/http/ngx_http_request.c14
-rw-r--r--src/http/ngx_http_request.h1
-rw-r--r--src/http/ngx_http_upstream.c11
-rw-r--r--src/http/ngx_http_upstream.h1
-rw-r--r--src/http/ngx_http_upstream_round_robin.c29
-rw-r--r--src/mail/ngx_mail_ssl_module.c18
-rw-r--r--src/mail/ngx_mail_ssl_module.h1
-rw-r--r--src/os/unix/ngx_files.h1
27 files changed, 504 insertions, 153 deletions
diff --git a/CHANGES b/CHANGES
index 3273f482b..0bb03e93b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,44 @@
+Changes with nginx 1.1.0 01 Aug 2011
+
+ *) Feature: cache loader run time decrease.
+
+ *) Feature: "loader_files", "loader_sleep", and "loader_threshold"
+ options of the "proxy/fastcgi/scgi/uwsgi_cache_path" directives.
+
+ *) Feature: loading time decrease of configuration with large number of
+ HTTPS sites.
+
+ *) Feature: now nginx supports ECDHE key exchange ciphers.
+ Thanks to Adrian Kotelba.
+
+ *) Feature: the "lingering_close" directive.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: in closing connection for pipelined requests.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: nginx did not disable gzipping if client sent "gzip;q=0" in
+ "Accept-Encoding" request header line.
+
+ *) Bugfix: in timeout in unbuffered proxied mode.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: memory leaks when a "proxy_pass" directive contains
+ variables and proxies to an HTTPS backend.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: in parameter validaiton of a "proxy_pass" directive with
+ variables.
+ Thanks to Lanshun Zhou.
+
+ *) Bugfix: SSL did not work on QNX.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: SSL modules could not be built by gcc 4.6 without
+ --with-debug option.
+
+
Changes with nginx 1.0.5 19 Jul 2011
*) Change: now default SSL ciphers are "HIGH:!aNULL:!MD5".
@@ -53,9 +93,9 @@ Changes with nginx 1.0.3 25 May 2011
testing IPv4 address mapped to IPv6 address, if access or deny rules
were defined only for IPv6; the bug had appeared in 0.8.22.
- *) Bugfix: a cached response may be broken if proxy/fastcgi/scgi/
- uwsgi_cache_bypass and proxy/fastcgi/scgi/uwsgi_no_cache directive
- values were different; the bug had appeared in 0.8.46.
+ *) Bugfix: a cached response may be broken if "proxy/fastcgi/scgi/
+ uwsgi_cache_bypass" and "proxy/fastcgi/scgi/uwsgi_no_cache"
+ directive values were different; the bug had appeared in 0.8.46.
Changes with nginx 1.0.2 10 May 2011
diff --git a/CHANGES.ru b/CHANGES.ru
index feebff2a5..781333c96 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,44 @@
+Изменения в nginx 1.1.0 01.08.2011
+
+ *) Добавление: уменьшение времени работы загрузчика кэша.
+
+ *) Добавление: параметры loader_files, loader_sleep и loader_threshold
+ директив proxy/fastcgi/scgi/uwsgi_cache_path.
+
+ *) Добавление: уменьшение времени загрузки конфигураций с большим
+ количеством HTTPS серверов.
+
+ *) Добавление: теперь nginx поддерживает шифры с обменом ECDHE-ключами.
+ Спасибо Adrian Kotelba.
+
+ *) Добавление: директива lingering_close.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: закрытия соединения для pipelined-запросов.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: nginx не запрещал сжатие при получении значения
+ "gzip;q=0" в строке "Accept-Encoding" в заголовке запроса клиента.
+
+ *) Исправление: таймаута при небуферизированном проксировании.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: утечки памяти при использовании переменных в директиве
+ proxy_pass при работе с бэкендом по HTTPS.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: в проверке параметра директивы proxy_pass, заданного
+ переменными.
+ Спасибо Lanshun Zhou.
+
+ *) Исправление: SSL не работал на QNX.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: SSL модули не собирались gcc 4.6 без параметра
+ --with-debug.
+
+
Изменения в nginx 1.0.5 19.07.2011
*) Изменение: теперь по умолчанию используются следующие шифры SSL:
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 0809927e4..cca3b694c 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1000005
-#define NGINX_VERSION "1.0.5"
+#define nginx_version 1001000
+#define NGINX_VERSION "1.1.0"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index ab73079a6..9762b18ca 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -127,5 +127,7 @@ typedef intptr_t ngx_flag_t;
#define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffff
#endif
+#define NGX_MAX_INT32_VALUE (uint32_t) 0x7fffffff
+
#endif /* _NGX_CONFIG_H_INCLUDED_ */
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index ed6d8426c..7704c3e17 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -926,6 +926,7 @@ ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree)
"tree file \"%s\"", file.data);
ctx->size = ngx_de_size(&dir);
+ ctx->fs_size = ngx_de_fs_size(&dir);
ctx->access = ngx_de_access(&dir);
ctx->mtime = ngx_de_mtime(&dir);
diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h
index 8b502539a..88035172d 100644
--- a/src/core/ngx_file.h
+++ b/src/core/ngx_file.h
@@ -104,6 +104,7 @@ typedef ngx_int_t (*ngx_tree_handler_pt) (ngx_tree_ctx_t *ctx, ngx_str_t *name);
struct ngx_tree_ctx_s {
off_t size;
+ off_t fs_size;
ngx_uint_t access;
time_t mtime;
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 0527c9c30..692f50639 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -371,28 +371,18 @@ ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
}
-ngx_int_t
-ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl)
+RSA *
+ngx_ssl_rsa512_key_callback(SSL *ssl, int is_export, int key_length)
{
- RSA *key;
-
- if (SSL_CTX_need_tmp_RSA(ssl->ctx) == 0) {
- return NGX_OK;
- }
-
- key = RSA_generate_key(512, RSA_F4, NULL, NULL);
-
- if (key) {
- SSL_CTX_set_tmp_rsa(ssl->ctx, key);
+ static RSA *key;
- RSA_free(key);
-
- return NGX_OK;
+ if (key_length == 512) {
+ if (key == NULL) {
+ key = RSA_generate_key(512, RSA_F4, NULL, NULL);
+ }
}
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "RSA_generate_key(512) failed");
-
- return NGX_ERROR;
+ return key;
}
@@ -478,6 +468,45 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
return NGX_OK;
}
+ngx_int_t
+ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
+#ifndef OPENSSL_NO_ECDH
+ int nid;
+ EC_KEY *ecdh;
+
+ /*
+ * Elliptic-Curve Diffie-Hellman parameters are either "named curves"
+ * from RFC 4492 section 5.1.1, or explicitely described curves over
+ * binary fields. OpenSSL only supports the "named curves", which provide
+ * maximum interoperability.
+ */
+
+ nid = OBJ_sn2nid((const char *) name->data);
+ if (nid == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "Unknown curve name \"%s\"", name->data);
+ return NGX_ERROR;
+ }
+
+ ecdh = EC_KEY_new_by_curve_name(nid);
+ if (ecdh == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "Unable to create curve \"%s\"", name->data);
+ return NGX_ERROR;
+ }
+
+ SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
+
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
+
+ EC_KEY_free(ecdh);
+#endif
+#endif
+
+ return NGX_OK;
+}
ngx_int_t
ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
@@ -957,10 +986,10 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
}
- /* the maximum limit size is the maximum uint32_t value - the page size */
+ /* the maximum limit size is the maximum int32_t value - the page size */
- if (limit == 0 || limit > (off_t) (NGX_MAX_UINT32_VALUE - ngx_pagesize)) {
- limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
+ if (limit == 0 || limit > (off_t) (NGX_MAX_INT32_VALUE - ngx_pagesize)) {
+ limit = NGX_MAX_INT32_VALUE - ngx_pagesize;
}
buf = c->ssl->buf;
@@ -1687,20 +1716,24 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
ngx_int_t rc;
ngx_shm_zone_t *shm_zone;
ngx_slab_pool_t *shpool;
- ngx_connection_t *c;
ngx_rbtree_node_t *node, *sentinel;
ngx_ssl_session_t *sess;
ngx_ssl_sess_id_t *sess_id;
ngx_ssl_session_cache_t *cache;
u_char buf[NGX_SSL_MAX_SESSION_SIZE];
-
- c = ngx_ssl_get_connection(ssl_conn);
+#if (NGX_DEBUG)
+ ngx_connection_t *c;
+#endif
hash = ngx_crc32_short(id, (size_t) len);
*copy = 0;
+#if (NGX_DEBUG)
+ c = ngx_ssl_get_connection(ssl_conn);
+
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"ssl get session: %08XD:%d", hash, len);
+#endif
shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn),
ngx_ssl_session_cache_index);
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index a8f9d8757..204d5f08e 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -99,8 +99,9 @@ ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
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);
+RSA *ngx_ssl_rsa512_key_callback(SSL *ssl, int is_export, int key_length);
ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
+ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout);
ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, 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 12d5b1d8f..71194fd20 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2003,6 +2003,8 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
conf->catch_stderr = NGX_CONF_UNSET_PTR;
+ ngx_str_set(&conf->upstream.module, "fastcgi");
+
return conf;
}
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 214fe6a26..495b1743d 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -642,15 +642,17 @@ ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
return NGX_ERROR;
}
- if (ngx_strncasecmp(proxy.data, (u_char *) "http://", 7) == 0) {
-
+ if (proxy.len > 7
+ && ngx_strncasecmp(proxy.data, (u_char *) "http://", 7) == 0)
+ {
add = 7;
port = 80;
#if (NGX_HTTP_SSL)
- } else if (ngx_strncasecmp(proxy.data, (u_char *) "https://", 8) == 0) {
-
+ } else if (proxy.len > 8
+ && ngx_strncasecmp(proxy.data, (u_char *) "https://", 8) == 0)
+ {
add = 8;
port = 443;
r->upstream->ssl = 1;
@@ -1707,6 +1709,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf->headers_hash_max_size = NGX_CONF_UNSET_UINT;
conf->headers_hash_bucket_size = NGX_CONF_UNSET_UINT;
+ ngx_str_set(&conf->upstream.module, "proxy");
+
return conf;
}
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index d745551f2..c83d77044 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -1030,6 +1030,8 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t *cf)
/* "scgi_cyclic_temp_file" is disabled */
conf->upstream.cyclic_temp_file = 0;
+ ngx_str_set(&conf->upstream.module, "scgi");
+
return conf;
}
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index 1860050d3..120a858df 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -13,7 +13,8 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
ngx_pool_t *pool, ngx_str_t *s);
-#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
+#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
+#define NGX_DEFAULT_ECDH_CURVE "prime256v1"
static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
@@ -78,6 +79,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
offsetof(ngx_http_ssl_srv_conf_t, dhparam),
NULL },
+ { ngx_string("ssl_ecdh_curve"),
+ 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, ecdh_curve),
+ NULL },
+
{ ngx_string("ssl_protocols"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
ngx_conf_set_bitmask_slot,
@@ -312,6 +320,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
* sscf->certificate = { 0, NULL };
* sscf->certificate_key = { 0, NULL };
* sscf->dhparam = { 0, NULL };
+ * sscf->ecdh_curve = { 0, NULL };
* sscf->client_certificate = { 0, NULL };
* sscf->crl = { 0, NULL };
* sscf->ciphers = { 0, NULL };
@@ -360,6 +369,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
"");
ngx_conf_merge_str_value(conf->crl, prev->crl, "");
+ ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
+ NGX_DEFAULT_ECDH_CURVE);
+
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
@@ -465,11 +477,13 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
}
/* a temporary 512-bit RSA key is required for export versions of MSIE */
- if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
+ SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback);
+
+ if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
return NGX_CONF_ERROR;
}
- if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
+ if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
index 29eedc8ae..0a5dd1d8d 100644
--- a/src/http/modules/ngx_http_ssl_module.h
+++ b/src/http/modules/ngx_http_ssl_module.h
@@ -32,6 +32,7 @@ typedef struct {
ngx_str_t certificate;
ngx_str_t certificate_key;
ngx_str_t dhparam;
+ ngx_str_t ecdh_curve;
ngx_str_t client_certificate;
ngx_str_t crl;
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index cd3c7c124..a907e53b8 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -1083,6 +1083,8 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
/* "uwsgi_cyclic_temp_file" is disabled */
conf->upstream.cyclic_temp_file = 0;
+ ngx_str_set(&conf->upstream.module, "uwsgi");
+
return conf;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 10f43ad21..a86f004c0 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -48,7 +48,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '1.0.5';
+our $VERSION = '1.1.0';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
index 3cf113f4a..bd02100da 100644
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -118,8 +118,11 @@ struct ngx_http_file_cache_s {
time_t inactive;
- ngx_msec_t last;
ngx_uint_t files;
+ ngx_uint_t loader_files;
+ ngx_msec_t last;
+ ngx_msec_t loader_sleep;
+ ngx_msec_t loader_threshold;
ngx_shm_zone_t *shm_zone;
};
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 597b64c51..f7ebacb40 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -70,6 +70,7 @@ static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
#if (NGX_HTTP_GZIP)
+static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae);
static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
#endif
@@ -125,6 +126,14 @@ static ngx_conf_enum_t ngx_http_core_satisfy[] = {
};
+static ngx_conf_enum_t ngx_http_core_lingering_close[] = {
+ { ngx_string("off"), NGX_HTTP_LINGERING_OFF },
+ { ngx_string("on"), NGX_HTTP_LINGERING_ON },
+ { ngx_string("always"), NGX_HTTP_LINGERING_ALWAYS },
+ { ngx_null_string, 0 }
+};
+
+
static ngx_conf_enum_t ngx_http_core_if_modified_since[] = {
{ ngx_string("off"), NGX_HTTP_IMS_OFF },
{ ngx_string("exact"), NGX_HTTP_IMS_EXACT },
@@ -530,6 +539,13 @@ static ngx_command_t ngx_http_core_commands[] = {
0,
NULL },
+ { ngx_string("lingering_close"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_enum_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, lingering_close),
+ &ngx_http_core_lingering_close },
+
{ ngx_string("lingering_time"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
@@ -2016,24 +2032,35 @@ ngx_http_gzip_ok(ngx_http_request_t *r)
time_t date, expires;
ngx_uint_t p;
ngx_array_t *cc;
- ngx_table_elt_t *e, *d;
+ ngx_table_elt_t *e, *d, *ae;
ngx_http_core_loc_conf_t *clcf;
r->gzip_tested = 1;
- if (r != r->main
- || r->headers_in.accept_encoding == NULL
- || ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
- "gzip", 4 - 1)
- == NULL
+ if (r != r->main) {
+ return NGX_DECLINED;
+ }
- /*
- * if the URL (without the "http://" prefix) is longer than 253 bytes,
- * then MSIE 4.x can not handle the compressed stream - it waits
- * too long, hangs up or crashes
- */
+ ae = r->headers_in.accept_encoding;
+ if (ae == NULL) {
+ return NGX_DECLINED;
+ }
+
+ if (ae->value.len < sizeof("gzip") - 1) {
+ return NGX_DECLINED;
+ }
- || (r->headers_in.msie4 && r->unparsed_uri.len > 200))
+ /*
+ * test first for the most common case "gzip,...":
+ * MSIE: "gzip, deflate"
+ * Firefox: "gzip,deflate"
+ * Chrome: "gzip,deflate,sdch"
+ * Safari: "gzip, deflate"
+ * Opera: "gzip, deflate"
+ */
+
+ if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0
+ && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)
{
return NGX_DECLINED;
}
@@ -2159,6 +2186,127 @@ ok:
return NGX_OK;
}
+
+/*
+ * gzip is enabled for the following quantities:
+ * "gzip; q=0.001" ... "gzip; q=0.999", "gzip; q=1"
+ * gzip is disabled for the following quantities:
+ * "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases
+ */
+
+static ngx_int_t
+ngx_http_gzip_accept_encoding(ngx_str_t *ae)
+{
+ u_char c, *p, *start, *last;
+ ngx_uint_t n, q;
+
+ start = ae->data;
+ last = start + ae->len;
+
+ for ( ;; ) {
+ p = ngx_strcasestrn(start, "gzip", 4 - 1);
+ if (p == NULL) {
+ return NGX_DECLINED;
+ }
+
+ if (p == start || (*(p - 1) == ',' || *(p - 1) == ' ')) {
+ break;
+ }
+
+ start = p + 4;
+ }
+
+ p += 4;
+
+ while (p < last) {
+ switch(*p++) {
+ case ',':
+ return NGX_OK;
+ case ';':
+ goto quantity;
+ case ' ':
+ continue;
+ default:
+ return NGX_DECLINED;
+ }
+ }
+
+ return NGX_OK;
+
+quantity:
+
+ while (p < last) {
+ switch(*p++) {
+ case 'q':
+ case 'Q':
+ goto equal;
+ case ' ':
+ continue;
+ default:
+ return NGX_DECLINED;
+ }
+ }
+
+ return NGX_OK;
+
+equal:
+
+ if (p + 2 > last || *p++ != '=') {
+ return NGX_DECLINED;
+ }
+
+ c = *p++;
+
+ if (c == '1') {
+ if (p == last || *p == ',' || *p == ' ') {
+ return NGX_OK;
+ }
+ return NGX_DECLINED;
+ }
+
+ if (c != '0') {
+ return NGX_DECLINED;
+ }
+
+ if (p == last) {
+ return NGX_DECLINED;
+ }
+
+ if (*p++ != '.') {
+ return NGX_DECLINED;
+ }
+
+ n = 0;
+ q = 0;
+
+ while (p < last) {
+ c = *p++;
+
+ if (c == ',') {
+ break;
+ }
+
+ if (c >= '1' && c <= '9') {
+ n++;
+ q++;
+ continue;
+ }
+
+ if (c == '0') {
+ n++;
+ continue;
+ }
+
+ return NGX_DECLINED;
+ }
+
+ if (n < 4 && q != 0) {
+ return NGX_OK;
+ }
+
+ return NGX_DECLINED;
+}
+
#endif
@@ -3117,6 +3265,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
+ clcf->lingering_close = NGX_CONF_UNSET_UINT;
clcf->lingering_time = NGX_CONF_UNSET_MSEC;
clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
@@ -3333,6 +3482,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->keepalive_header, 0);
ngx_conf_merge_uint_value(conf->keepalive_requests,
prev->keepalive_requests, 100);
+ ngx_conf_merge_msec_value(conf->lingering_close,
+ prev->lingering_close, NGX_HTTP_LINGERING_ON);
ngx_conf_merge_msec_value(conf->lingering_time,
prev->lingering_time, 30000);
ngx_conf_merge_msec_value(conf->lingering_timeout,
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 729ef9721..165e7c051 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -33,6 +33,11 @@
#define NGX_HTTP_SATISFY_ANY 1
+#define NGX_HTTP_LINGERING_OFF 0
+#define NGX_HTTP_LINGERING_ON 1
+#define NGX_HTTP_LINGERING_ALWAYS 2
+
+
#define NGX_HTTP_IMS_OFF 0
#define NGX_HTTP_IMS_EXACT 1
#define NGX_HTTP_IMS_BEFORE 2
@@ -356,6 +361,7 @@ struct ngx_http_core_loc_conf_s {
ngx_uint_t keepalive_requests; /* keepalive_requests */
ngx_uint_t keepalive_disable; /* keepalive_disable */
ngx_uint_t satisfy; /* satisfy */
+ ngx_uint_t lingering_close; /* lingering_close */
ngx_uint_t if_modified_since; /* if_modified_since */
ngx_uint_t client_body_in_file_only; /* client_body_in_file_only */
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index f44fe1de1..b9ea606a2 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -31,7 +31,7 @@ static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache);
static void ngx_http_file_cache_delete(ngx_http_file_cache_t *cache,
ngx_queue_t *q, u_char *name);
static ngx_int_t
- ngx_http_file_cache_manager_sleep(ngx_http_file_cache_t *cache);
+ ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache);
static ngx_int_t ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx,
ngx_str_t *path);
static ngx_int_t ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx,
@@ -376,7 +376,7 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
if ((size_t) n < c->header_start) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
"cache file \"%s\" is too small", c->file.name.data);
- return NGX_ERROR;
+ return NGX_DECLINED;
}
h = (ngx_http_file_cache_header_t *) c->buf->pos;
@@ -530,26 +530,19 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
goto done;
}
- if (fcn->exists) {
+ if (fcn->exists || fcn->uses >= c->min_uses) {
c->exists = fcn->exists;
- c->body_start = fcn->body_start;
+ if (fcn->body_start) {
+ c->body_start = fcn->body_start;
+ }
rc = NGX_OK;
goto done;
}
- if (fcn->uses >= c->min_uses) {
-
- c->exists = fcn->exists;
- c->body_start = fcn->body_start;
-
- rc = NGX_OK;
-
- } else {
- rc = NGX_AGAIN;
- }
+ rc = NGX_AGAIN;
goto done;
}
@@ -858,7 +851,7 @@ ngx_http_cache_send(ngx_http_request_t *r)
c = r->cache;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache send: %s", c->file.name.data);
+ "http file cache send: %s", c->file.name.data);
/* we need to allocate all before the header would be sent */
@@ -1214,7 +1207,7 @@ ngx_http_file_cache_manager(void *data)
return wait;
}
- if (ngx_http_file_cache_manager_sleep(cache) != NGX_OK) {
+ if (ngx_quit || ngx_terminate) {
return next;
}
}
@@ -1268,32 +1261,39 @@ ngx_http_file_cache_loader(void *data)
static ngx_int_t
-ngx_http_file_cache_manager_sleep(ngx_http_file_cache_t *cache)
+ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache)
{
ngx_msec_t elapsed;
- if (cache->files++ > 100) {
+ if (++cache->files >= cache->loader_files) {
ngx_time_update();
elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache manager time: %M", elapsed);
+ "http file cache loader time elapsed: %M", elapsed);
- if (elapsed > 200) {
+ if (elapsed >= cache->loader_threshold) {
- /*
- * if processing 100 files takes more than 200ms,
- * it seems that many operations require disk i/o,
- * therefore sleep 200ms
- */
+ if (cache->loader_files > 1) {
+ cache->loader_files /= 2;
+ ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
+ "cache %V loader_files decreased to %ui",
+ &cache->path->name, cache->loader_files);
- ngx_msleep(200);
-
- ngx_time_update();
+ } else {
+ cache->loader_sleep *= 2;
+ ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
+ "cache %V loader_sleep increased to %Mms",
+ &cache->path->name, cache->loader_sleep);
+ }
}
+ ngx_msleep(cache->loader_sleep);
+
+ ngx_time_update();
+
cache->last = ngx_current_msec;
cache->files = 0;
}
@@ -1320,75 +1320,34 @@ ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
(void) ngx_http_file_cache_delete_file(ctx, path);
}
- return ngx_http_file_cache_manager_sleep(cache);
+ return ngx_http_file_cache_loader_sleep(cache);
}
static ngx_int_t
ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx, ngx_str_t *name)
{
- u_char *p;
- ngx_fd_t fd;
- ngx_int_t n;
- ngx_uint_t i;
- ngx_file_info_t fi;
- ngx_http_cache_t c;
- ngx_http_file_cache_t *cache;
- ngx_http_file_cache_header_t h;
+ u_char *p;
+ ngx_int_t n;
+ ngx_uint_t i;
+ ngx_http_cache_t c;
+ ngx_http_file_cache_t *cache;
if (name->len < 2 * NGX_HTTP_CACHE_KEY_LEN) {
return NGX_ERROR;
}
- ngx_memzero(&c, sizeof(ngx_http_cache_t));
-
- fd = ngx_open_file(name->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
-
- if (fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
- ngx_open_file_n " \"%s\" failed", name->data);
- return NGX_ERROR;
- }
-
- c.file.fd = fd;
- c.file.name = *name;
- c.file.log = ctx->log;
-
- n = ngx_read_file(&c.file, (u_char *) &h,
- sizeof(ngx_http_file_cache_header_t), 0);
- if (n == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if ((size_t) n < sizeof(ngx_http_file_cache_header_t)) {
+ if (ctx->size < (off_t) sizeof(ngx_http_file_cache_header_t)) {
ngx_log_error(NGX_LOG_CRIT, ctx->log, 0,
"cache file \"%s\" is too small", name->data);
return NGX_ERROR;
}
+ ngx_memzero(&c, sizeof(ngx_http_cache_t));
cache = ctx->data;
- if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
- ngx_fd_info_n " \"%s\" failed", name->data);
-
- } else {
- c.uniq = ngx_file_uniq(&fi);
- c.valid_sec = h.valid_sec;
- c.valid_msec = h.valid_msec;
- c.body_start = h.body_start;
- c.length = ngx_file_size(&fi);
- c.fs_size = (ngx_file_fs_size(&fi) + cache->bsize - 1) / cache->bsize;
- }
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", name->data);
- }
-
- if (c.body_start == 0) {
- return NGX_ERROR;
- }
+ c.length = ctx->size;
+ c.fs_size = (ctx->fs_size + cache->bsize - 1) / cache->bsize;
p = &name->data[name->len - 2 * NGX_HTTP_CACHE_KEY_LEN];
@@ -1435,14 +1394,14 @@ ngx_http_file_cache_add(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
fcn->uses = 1;
fcn->count = 0;
- fcn->valid_msec = c->valid_msec;
+ fcn->valid_msec = 0;
fcn->error = 0;
fcn->exists = 1;
fcn->updating = 0;
fcn->deleting = 0;
- fcn->uniq = c->uniq;
- fcn->valid_sec = c->valid_sec;
- fcn->body_start = c->body_start;
+ fcn->uniq = 0;
+ fcn->valid_sec = 0;
+ fcn->body_start = 0;
fcn->fs_size = c->fs_size;
cache->sh->size += c->fs_size;
@@ -1510,6 +1469,7 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
time_t inactive;
ssize_t size;
ngx_str_t s, name, *value;
+ ngx_int_t loader_files, loader_sleep, loader_threshold;
ngx_uint_t i, n;
ngx_http_file_cache_t *cache;
@@ -1524,6 +1484,9 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
inactive = 600;
+ loader_files = 100;
+ loader_sleep = 50;
+ loader_threshold = 200;
name.len = 0;
size = 0;
@@ -1637,6 +1600,48 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
+ if (ngx_strncmp(value[i].data, "loader_files=", 13) == 0) {
+
+ loader_files = ngx_atoi(value[i].data + 13, value[i].len - 13);
+ if (loader_files == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid loader_files value \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "loader_sleep=", 13) == 0) {
+
+ s.len = value[i].len - 13;
+ s.data = value[i].data + 13;
+
+ loader_sleep = ngx_parse_time(&s, 0);
+ if (loader_sleep < 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid loader_sleep value \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "loader_threshold=", 17) == 0) {
+
+ s.len = value[i].len - 17;
+ s.data = value[i].data + 17;
+
+ loader_threshold = ngx_parse_time(&s, 0);
+ if (loader_threshold < 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid loader_threshold value \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[i]);
return NGX_CONF_ERROR;
@@ -1652,6 +1657,11 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
cache->path->manager = ngx_http_file_cache_manager;
cache->path->loader = ngx_http_file_cache_loader;
cache->path->data = cache;
+ cache->path->conf_file = cf->conf_file->file.name.data;
+ cache->path->line = cf->conf_file->line;
+ cache->loader_files = loader_files;
+ cache->loader_sleep = (ngx_msec_t) loader_sleep;
+ cache->loader_threshold = (ngx_msec_t) loader_threshold;
if (ngx_add_path(cf, &cache->path) != NGX_OK) {
return NGX_CONF_ERROR;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 2cef4fa5b..5e0b8e891 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1439,8 +1439,6 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
switch (msie[5]) {
case '4':
- r->headers_in.msie4 = 1;
- /* fall through */
case '5':
r->headers_in.msie6 = 1;
break;
@@ -1463,7 +1461,6 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
r->headers_in.opera = 1;
r->headers_in.msie = 0;
- r->headers_in.msie4 = 0;
r->headers_in.msie6 = 0;
}
@@ -2126,11 +2123,11 @@ ngx_http_finalize_connection(ngx_http_request_t *r)
if (r->discard_body) {
r->read_event_handler = ngx_http_discarded_request_body_handler;
+ ngx_add_timer(r->connection->read, clcf->lingering_timeout);
if (r->lingering_time == 0) {
r->lingering_time = ngx_time()
+ (time_t) (clcf->lingering_time / 1000);
- ngx_add_timer(r->connection->read, clcf->lingering_timeout);
}
}
@@ -2145,8 +2142,14 @@ ngx_http_finalize_connection(ngx_http_request_t *r)
{
ngx_http_set_keepalive(r);
return;
+ }
- } else if (r->lingering_close && clcf->lingering_timeout > 0) {
+ if (clcf->lingering_close == NGX_HTTP_LINGERING_ALWAYS
+ || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
+ && (r->lingering_close
+ || r->header_in->pos < r->header_in->last
+ || r->connection->read->ready)))
+ {
ngx_http_set_lingering_close(r);
return;
}
@@ -2772,7 +2775,6 @@ ngx_http_lingering_close_handler(ngx_event_t *rev)
"http lingering close handler");
if (rev->timedout) {
- c->timedout = 1;
ngx_http_close_request(r, 0);
return;
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index c20810ed5..6198d7ef2 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -221,7 +221,6 @@ typedef struct {
unsigned connection_type:2;
unsigned msie:1;
- unsigned msie4:1;
unsigned msie6:1;
unsigned opera:1;
unsigned gecko:1;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index ad5b449ec..29432dc14 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -661,10 +661,12 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
ngx_http_file_cache_create_key(r);
- if (r->cache->header_start >= u->conf->buffer_size) {
+ if (r->cache->header_start + 256 >= u->conf->buffer_size) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "cache key too large, increase upstream buffer size %uz",
- u->conf->buffer_size);
+ "%V_buffer_size %uz is not enough for cache key, "
+ "it should increased at least to %uz",
+ &u->conf->module, u->conf->buffer_size,
+ ngx_align(r->cache->header_start + 256, 1024));
r->cache = NULL;
return NGX_DECLINED;
@@ -2317,7 +2319,7 @@ ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r)
if (wev->timedout) {
c->timedout = 1;
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
- ngx_http_upstream_finalize_request(r, u, 0);
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT);
return;
}
@@ -3013,6 +3015,7 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
#endif
if (u->header_sent
+ && rc != NGX_HTTP_REQUEST_TIME_OUT
&& (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE))
{
rc = 0;
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index 01e2e1e51..fa848c0d3 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -179,6 +179,7 @@ typedef struct {
ngx_flag_t ssl_session_reuse;
#endif
+ ngx_str_t module;
} ngx_http_upstream_conf_t;
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index 52bd80858..de34b2884 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -14,6 +14,15 @@ static ngx_int_t ngx_http_upstream_cmp_servers(const void *one,
static ngx_uint_t
ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers);
+#if (NGX_HTTP_SSL)
+
+static ngx_int_t ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc,
+ void *data);
+static void ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc,
+ void *data);
+
+#endif
+
ngx_int_t
ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
@@ -343,10 +352,8 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
r->upstream->peer.tries = rrp->peers->number;
#if (NGX_HTTP_SSL)
- r->upstream->peer.set_session =
- ngx_http_upstream_set_round_robin_peer_session;
- r->upstream->peer.save_session =
- ngx_http_upstream_save_round_robin_peer_session;
+ r->upstream->peer.set_session = ngx_http_upstream_empty_set_session;
+ r->upstream->peer.save_session = ngx_http_upstream_empty_save_session;
#endif
return NGX_OK;
@@ -757,4 +764,18 @@ ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,
}
}
+
+static ngx_int_t
+ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data)
+{
+ return NGX_OK;
+}
+
+
+static void
+ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data)
+{
+ return;
+}
+
#endif
diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c
index 9dd9dfd15..5767a2fd4 100644
--- a/src/mail/ngx_mail_ssl_module.c
+++ b/src/mail/ngx_mail_ssl_module.c
@@ -9,7 +9,8 @@
#include <ngx_mail.h>
-#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
+#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
+#define NGX_DEFAULT_ECDH_CURVE "prime256v1"
static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf);
@@ -77,6 +78,13 @@ static ngx_command_t ngx_mail_ssl_commands[] = {
offsetof(ngx_mail_ssl_conf_t, dhparam),
NULL },
+ { ngx_string("ssl_ecdh_curve"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_MAIL_SRV_CONF_OFFSET,
+ offsetof(ngx_mail_ssl_conf_t, ecdh_curve),
+ NULL },
+
{ ngx_string("ssl_protocols"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
ngx_conf_set_bitmask_slot,
@@ -163,6 +171,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
* scf->certificate = { 0, NULL };
* scf->certificate_key = { 0, NULL };
* scf->dhparam = { 0, NULL };
+ * scf->ecdh_curve = { 0, NULL };
* scf->ciphers = { 0, NULL };
* scf->shm_zone = NULL;
*/
@@ -204,6 +213,9 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
+ ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
+ NGX_DEFAULT_ECDH_CURVE);
+
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
@@ -286,9 +298,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
}
- if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
+ SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback);
if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
return NGX_CONF_ERROR;
diff --git a/src/mail/ngx_mail_ssl_module.h b/src/mail/ngx_mail_ssl_module.h
index b27da41d9..61a275b36 100644
--- a/src/mail/ngx_mail_ssl_module.h
+++ b/src/mail/ngx_mail_ssl_module.h
@@ -34,6 +34,7 @@ typedef struct {
ngx_str_t certificate;
ngx_str_t certificate_key;
ngx_str_t dhparam;
+ ngx_str_t ecdh_curve;
ngx_str_t ciphers;
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 037c9a165..af41ea38e 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -253,6 +253,7 @@ ngx_de_info(u_char *name, ngx_dir_t *dir)
#define ngx_de_access(dir) (((dir)->info.st_mode) & 0777)
#define ngx_de_size(dir) (dir)->info.st_size
+#define ngx_de_fs_size(dir) ((dir)->info.st_blocks * 512)
#define ngx_de_mtime(dir) (dir)->info.st_mtime