summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2008-05-26 09:32:48 +0000
committerJonathan Kolb <jon@b0g.us>2008-05-26 09:32:48 +0000
commit97647a9b9023a209f1c33a092722ddcc100dfc1a (patch)
tree97b01690fdeba47c65deb1cb541b691c83e92f6d
parent013f90472501bd911bd82c90e6aa1879d3d4c4fe (diff)
downloadnginx-97647a9b9023a209f1c33a092722ddcc100dfc1a.tar.gz
Changes with nginx 0.7.1 26 May 2008v0.7.1
*) Change: now locations are searched in a tree. *) Change: the "optimize_server_names" directive was canceled due to the "server_name_in_redirect" directive introduction. *) Change: some long deprecated directives are not supported anymore. *) Change: the "none" parameter in the "ssl_session_cache" directive; now this is default parameter. Thanks to Rob Mueller. *) Bugfix: worker processes might not catch reconfiguration and log rotation signals. *) Bugfix: nginx could not be built on latest Fedora 9 Linux. Thanks to Roxis.
-rw-r--r--CHANGES20
-rw-r--r--CHANGES.ru21
-rw-r--r--auto/sources1
-rw-r--r--src/core/nginx.c2
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_connection.c2
-rw-r--r--src/core/ngx_queue.c79
-rw-r--r--src/core/ngx_queue.h43
-rw-r--r--src/event/modules/ngx_kqueue_module.c2
-rw-r--r--src/event/ngx_event.c4
-rw-r--r--src/event/ngx_event_openssl.c23
-rw-r--r--src/event/ngx_event_openssl.h7
-rw-r--r--src/event/ngx_event_pipe.c2
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c22
-rw-r--r--src/http/modules/ngx_http_proxy_module.c24
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c15
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_ssl_module.c7
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http.c1410
-rw-r--r--src/http/ngx_http.h8
-rw-r--r--src/http/ngx_http_core_module.c457
-rw-r--r--src/http/ngx_http_core_module.h79
-rw-r--r--src/http/ngx_http_header_filter_module.c2
-rw-r--r--src/http/ngx_http_request.c2
-rw-r--r--src/http/ngx_http_special_response.c6
-rw-r--r--src/mail/ngx_mail_ssl_module.c7
-rw-r--r--src/os/unix/ngx_linux_config.h1
-rw-r--r--src/os/unix/ngx_process_cycle.c90
29 files changed, 1450 insertions, 892 deletions
diff --git a/CHANGES b/CHANGES
index 2b4cc3cc2..24aa4ca80 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,24 @@
+Changes with nginx 0.7.1 26 May 2008
+
+ *) Change: now locations are searched in a tree.
+
+ *) Change: the "optimize_server_names" directive was canceled due to
+ the "server_name_in_redirect" directive introduction.
+
+ *) Change: some long deprecated directives are not supported anymore.
+
+ *) Change: the "none" parameter in the "ssl_session_cache" directive;
+ now this is default parameter.
+ Thanks to Rob Mueller.
+
+ *) Bugfix: worker processes might not catch reconfiguration and log
+ rotation signals.
+
+ *) Bugfix: nginx could not be built on latest Fedora 9 Linux.
+ Thanks to Roxis.
+
+
Changes with nginx 0.7.0 19 May 2008
*) Change: now the 0x00-0x1F, '"' and '\' characters are escaped as
diff --git a/CHANGES.ru b/CHANGES.ru
index a62db81f9..5f2575e6a 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,25 @@
+Изменения в nginx 0.7.1 26.05.2008
+
+ *) Изменение: теперь поиск location'а делается с помощью дерева.
+
+ *) Изменение: директива optimize_server_names упразднена в связи с
+ появлением директивы server_name_in_redirect.
+
+ *) Изменение: некоторые давно устаревшие директивы больше не
+ поддерживаются.
+
+ *) Изменение: параметр "none" в директиве ssl_session_cache; теперь
+ этот параметр используется по умолчанию.
+ Спасибо Rob Mueller.
+
+ *) Исправление: рабочие процессы могли не реагировать на сигналы
+ переконфигурации и ротации логов.
+
+ *) Исправление: nginx не собирался на последних Fedora 9 Linux.
+ Спасибо Roxis.
+
+
Изменения в nginx 0.7.0 19.05.2008
*) Изменение: теперь символы 0x00-0x1F, '"' и '\' в access_log
diff --git a/auto/sources b/auto/sources
index ed78c7164..62fb047cd 100644
--- a/auto/sources
+++ b/auto/sources
@@ -44,6 +44,7 @@ CORE_SRCS="src/core/nginx.c \
src/core/ngx_list.c \
src/core/ngx_hash.c \
src/core/ngx_buf.c \
+ src/core/ngx_queue.c \
src/core/ngx_output_chain.c \
src/core/ngx_string.c \
src/core/ngx_parse.c \
diff --git a/src/core/nginx.c b/src/core/nginx.c
index ee636825b..48e085ba3 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -1078,7 +1078,7 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid character \"%c\" in \"worker_cpu_affinity\"",
ch);
- return NGX_CONF_ERROR ;
+ return NGX_CONF_ERROR;
}
}
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 82cce7111..ad5e57cfa 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.7.0"
+#define NGINX_VERSION "0.7.1"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index d22a08ed2..b49a696f2 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -229,7 +229,7 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
/* TODO: configurable try number */
- for (tries = 5 ; tries; tries--) {
+ for (tries = 5; tries; tries--) {
failed = 0;
/* for each listening socket */
diff --git a/src/core/ngx_queue.c b/src/core/ngx_queue.c
new file mode 100644
index 000000000..a49b5c663
--- /dev/null
+++ b/src/core/ngx_queue.c
@@ -0,0 +1,79 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+/*
+ * find the middle queue element if the queue has odd number of elements
+ * or the first element of the queue's second part otherwise
+ */
+
+ngx_queue_t *
+ngx_queue_middle(ngx_queue_t *queue)
+{
+ ngx_queue_t *middle, *next;
+
+ middle = ngx_queue_head(queue);
+
+ if (middle == ngx_queue_last(queue)) {
+ return middle;
+ }
+
+ next = ngx_queue_head(queue);
+
+ for ( ;; ) {
+ middle = ngx_queue_next(middle);
+
+ next = ngx_queue_next(next);
+
+ if (next == ngx_queue_last(queue)) {
+ return middle;
+ }
+
+ next = ngx_queue_next(next);
+
+ if (next == ngx_queue_last(queue)) {
+ return middle;
+ }
+ }
+}
+
+
+/* the stable insertion sort */
+
+void
+ngx_queue_sort(ngx_queue_t *queue,
+ ngx_int_t (*cmp)(const ngx_queue_t *, const ngx_queue_t *))
+{
+ ngx_queue_t *q, *prev, *next;
+
+ q = ngx_queue_head(queue);
+
+ if (q == ngx_queue_last(queue)) {
+ return;
+ }
+
+ for (q = ngx_queue_next(q); q != ngx_queue_sentinel(queue); q = next) {
+
+ prev = ngx_queue_prev(q);
+ next = ngx_queue_next(q);
+
+ ngx_queue_remove(q);
+
+ do {
+ if (cmp(prev, q) <= 0) {
+ break;
+ }
+
+ prev = ngx_queue_prev(prev);
+
+ } while (prev != ngx_queue_sentinel(queue));
+
+ ngx_queue_insert_after(prev, q);
+ }
+}
diff --git a/src/core/ngx_queue.h b/src/core/ngx_queue.h
index 1407d85a6..9a1763d7b 100644
--- a/src/core/ngx_queue.h
+++ b/src/core/ngx_queue.h
@@ -36,6 +36,16 @@ struct ngx_queue_s {
(h)->next = x
+#define ngx_queue_insert_after ngx_queue_insert_head
+
+
+#define ngx_queue_insert_tail(h, x) \
+ (x)->prev = (h)->prev; \
+ (x)->prev->next = x; \
+ (x)->next = h; \
+ (h)->prev = x
+
+
#define ngx_queue_head(h) \
(h)->next
@@ -44,6 +54,18 @@ struct ngx_queue_s {
(h)->prev
+#define ngx_queue_sentinel(h) \
+ (h)
+
+
+#define ngx_queue_next(q) \
+ (q)->next
+
+
+#define ngx_queue_prev(q) \
+ (q)->prev
+
+
#if (NGX_DEBUG)
#define ngx_queue_remove(x) \
@@ -61,8 +83,29 @@ struct ngx_queue_s {
#endif
+#define ngx_queue_split(h, q, n) \
+ (n)->prev = (h)->prev; \
+ (n)->prev->next = n; \
+ (n)->next = q; \
+ (h)->prev = (q)->prev; \
+ (h)->prev->next = h; \
+ (q)->prev = n;
+
+
+#define ngx_queue_add(h, n) \
+ (h)->prev->next = (n)->next; \
+ (n)->next->prev = (h)->prev; \
+ (h)->prev = (n)->prev; \
+ (h)->prev->next = h;
+
+
#define ngx_queue_data(q, type, link) \
(type *) ((u_char *) q - offsetof(type, link))
+ngx_queue_t *ngx_queue_middle(ngx_queue_t *queue);
+void ngx_queue_sort(ngx_queue_t *queue,
+ ngx_int_t (*cmp)(const ngx_queue_t *, const ngx_queue_t *));
+
+
#endif /* _NGX_QUEUE_H_INCLUDED_ */
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 1b1f9712f..1ad2d8d5a 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -446,7 +446,7 @@ ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags)
|| __FreeBSD_version >= 500018
|NOTE_REVOKE
#endif
- ;
+ ;
kev->data = 0;
} else {
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index d34710742..1ec0119cc 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -942,7 +942,7 @@ ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_str_t *value;
if (ecf->connections != NGX_CONF_UNSET_UINT) {
- return "is duplicate" ;
+ return "is duplicate";
}
if (ngx_strcmp(cmd->name.data, "connections") == 0) {
@@ -977,7 +977,7 @@ ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_event_module_t *module;
if (ecf->use != NGX_CONF_UNSET_UINT) {
- return "is duplicate" ;
+ return "is duplicate";
}
value = cf->args->elts;
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 559c00772..7b44815d7 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -1267,6 +1267,29 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
return NGX_OK;
}
+ if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {
+
+ /*
+ * If the server explicitly says that it does not support
+ * session reuse (see SSL_SESS_CACHE_OFF above), then
+ * Outlook Express fails to upload a sent email to
+ * the Sent Items folder on the IMAP server via a separate IMAP
+ * connection in the background. Therefore we have a special
+ * mode (SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE)
+ * where the server pretends that it supports session reuse,
+ * but it does not actually store any session.
+ */
+
+ SSL_CTX_set_session_cache_mode(ssl->ctx,
+ SSL_SESS_CACHE_SERVER
+ |SSL_SESS_CACHE_NO_AUTO_CLEAR
+ |SSL_SESS_CACHE_NO_INTERNAL_STORE);
+
+ SSL_CTX_sess_set_cache_size(ssl->ctx, 1);
+
+ return NGX_OK;
+ }
+
cache_mode = SSL_SESS_CACHE_SERVER;
if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) {
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index b9771c121..4c3dd4830 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -51,9 +51,10 @@ typedef struct {
} ngx_ssl_connection_t;
-#define NGX_SSL_DFLT_BUILTIN_SCACHE -2
-#define NGX_SSL_NO_BUILTIN_SCACHE -3
-#define NGX_SSL_NO_SCACHE -4
+#define NGX_SSL_NO_SCACHE -2
+#define NGX_SSL_NONE_SCACHE -3
+#define NGX_SSL_NO_BUILTIN_SCACHE -4
+#define NGX_SSL_DFLT_BUILTIN_SCACHE -5
#define NGX_SSL_MAX_SESSION_SIZE 4096
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index 0b7eb513c..a9cb21ecb 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -880,7 +880,7 @@ ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free, ngx_buf_t *buf)
ll = free;
- for (cl = *free ; cl; cl = cl->next) {
+ for (cl = *free; cl; cl = cl->next) {
if (cl->buf == s) {
*ll = cl->next;
break;
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 17e8a3dbf..5569745d6 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -138,14 +138,6 @@ static char *ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
static ngx_conf_post_t ngx_http_fastcgi_lowat_post =
{ ngx_http_fastcgi_lowat_check };
-static ngx_conf_deprecated_t ngx_conf_deprecated_fastcgi_header_buffer_size = {
- ngx_conf_deprecated, "fastcgi_header_buffer_size", "fastcgi_buffer_size"
-};
-
-static ngx_conf_deprecated_t ngx_conf_deprecated_fastcgi_redirect_errors = {
- ngx_conf_deprecated, "fastcgi_redirect_errors", "fastcgi_intercept_errors"
-};
-
static ngx_conf_bitmask_t ngx_http_fastcgi_next_upstream_masks[] = {
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
@@ -224,13 +216,6 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.buffer_size),
NULL },
- { ngx_string("fastcgi_header_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.buffer_size),
- &ngx_conf_deprecated_fastcgi_header_buffer_size },
-
{ ngx_string("fastcgi_pass_request_headers"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -252,13 +237,6 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.intercept_errors),
NULL },
- { ngx_string("fastcgi_redirect_errors"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.intercept_errors),
- &ngx_conf_deprecated_fastcgi_redirect_errors },
-
{ ngx_string("fastcgi_read_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index c559d3165..619390b96 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -142,14 +142,6 @@ static ngx_int_t ngx_http_proxy_set_vars(ngx_pool_t *pool, ngx_url_t *u,
static ngx_conf_post_t ngx_http_proxy_lowat_post =
{ ngx_http_proxy_lowat_check };
-static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_header_buffer_size = {
- ngx_conf_deprecated, "proxy_header_buffer_size", "proxy_buffer_size"
-};
-
-static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_redirect_errors = {
- ngx_conf_deprecated, "proxy_redirect_errors", "proxy_intercept_errors"
-};
-
static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = {
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
@@ -235,13 +227,6 @@ static ngx_command_t ngx_http_proxy_commands[] = {
offsetof(ngx_http_proxy_loc_conf_t, upstream.intercept_errors),
NULL },
- { ngx_string("proxy_redirect_errors"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.intercept_errors),
- &ngx_conf_deprecated_proxy_redirect_errors },
-
{ ngx_string("proxy_set_header"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
ngx_conf_set_keyval_slot,
@@ -298,13 +283,6 @@ static ngx_command_t ngx_http_proxy_commands[] = {
offsetof(ngx_http_proxy_loc_conf_t, upstream.buffer_size),
NULL },
- { ngx_string("proxy_header_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.buffer_size),
- &ngx_conf_deprecated_proxy_header_buffer_size },
-
{ ngx_string("proxy_read_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
@@ -1224,7 +1202,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
- for ( ;; ) {
+ for ( ;; ) {
rc = ngx_http_parse_header_line(r, &r->upstream->buffer);
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 341e05424..9c3d3fb28 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -524,7 +524,7 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_conf_t save;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *pctx;
- ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp;
+ ngx_http_core_loc_conf_t *clcf, *pclcf;
ngx_http_script_if_code_t *if_code;
ngx_http_rewrite_loc_conf_t *nlcf;
@@ -567,21 +567,10 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
clcf->name = pclcf->name;
clcf->noname = 1;
- if (pclcf->locations == NULL) {
- pclcf->locations = ngx_array_create(cf->pool, 2, sizeof(void *));
- if (pclcf->locations == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- clcfp = ngx_array_push(pclcf->locations);
- if (clcfp == NULL) {
+ if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
return NGX_CONF_ERROR;
}
- *clcfp = clcf;
-
-
if (ngx_http_rewrite_if_condition(cf, lcf) != NGX_CONF_OK) {
return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 1d7730d56..ddd15f4f5 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -1637,7 +1637,7 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
quoted = 0;
- for (i = 0 ; i < text->len; i++) {
+ for (i = 0; i < text->len; i++) {
ch = text->data[i];
if (!quoted) {
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index 3359900fd..ea9ff8f7e 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -415,7 +415,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
}
ngx_conf_merge_value(conf->builtin_session_cache,
- prev->builtin_session_cache, NGX_SSL_NO_SCACHE);
+ prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
if (conf->shm_zone == NULL) {
conf->shm_zone = prev->shm_zone;
@@ -452,6 +452,11 @@ ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
+ if (ngx_strcmp(value[i].data, "none") == 0) {
+ sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
+ continue;
+ }
+
if (ngx_strcmp(value[i].data, "builtin") == 0) {
sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
continue;
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 03e2834ce..80eec7d57 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.7.0';
+our $VERSION = '0.7.1';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 3ef1dcbc8..a1c4c9892 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -11,22 +11,48 @@
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static ngx_int_t ngx_http_init_phases(ngx_conf_t *cf,
+ ngx_http_core_main_conf_t *cmcf);
+static ngx_int_t ngx_http_init_headers_in_hash(ngx_conf_t *cf,
+ ngx_http_core_main_conf_t *cmcf);
+static ngx_int_t ngx_http_init_phase_handlers(ngx_conf_t *cf,
+ ngx_http_core_main_conf_t *cmcf);
+
+static ngx_int_t ngx_http_init_server_lists(ngx_conf_t *cf,
+ ngx_array_t *servers, ngx_array_t *in_ports);
static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
- ngx_http_conf_in_port_t *in_port, ngx_http_listen_t *lscf,
- ngx_http_core_srv_conf_t *cscf);
+ ngx_http_core_srv_conf_t *cscf, ngx_http_conf_in_port_t *in_port,
+ ngx_http_listen_t *listen);
static ngx_int_t ngx_http_add_names(ngx_conf_t *cf,
- ngx_http_conf_in_addr_t *in_addr, ngx_http_core_srv_conf_t *cscf);
+ ngx_http_core_srv_conf_t *cscf, ngx_http_conf_in_addr_t *in_addr);
+
static char *ngx_http_merge_locations(ngx_conf_t *cf,
- ngx_array_t *locations, void **loc_conf, ngx_http_module_t *module,
+ ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module,
ngx_uint_t ctx_index);
+static ngx_int_t ngx_http_init_locations(ngx_conf_t *cf,
+ ngx_http_core_srv_conf_t *cscf, ngx_http_core_loc_conf_t *pclcf);
+static ngx_int_t ngx_http_init_static_location_trees(ngx_conf_t *cf,
+ ngx_http_core_loc_conf_t *pclcf);
+static ngx_int_t ngx_http_cmp_locations(const ngx_queue_t *one,
+ const ngx_queue_t *two);
+static ngx_int_t ngx_http_join_exact_locations(ngx_conf_t *cf,
+ ngx_queue_t *locations);
+static void ngx_http_create_locations_list(ngx_queue_t *locations,
+ ngx_queue_t *q);
+static ngx_http_location_tree_node_t *
+ ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
+ size_t prefix);
+
+static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf,
+ ngx_http_core_main_conf_t *cmcf, ngx_array_t *in_ports);
static ngx_int_t ngx_http_cmp_conf_in_addrs(const void *one, const void *two);
static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one,
const void *two);
-ngx_uint_t ngx_http_max_module;
+static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf,
+ ngx_http_conf_in_port_t *in_port);
-ngx_uint_t ngx_http_total_requests;
-uint64_t ngx_http_total_sent;
+ngx_uint_t ngx_http_max_module;
ngx_int_t (*ngx_http_top_header_filter) (ngx_http_request_t *r);
@@ -73,34 +99,14 @@ static char *
ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *rv;
- ngx_int_t rc, j;
- ngx_uint_t mi, m, s, l, p, a, i, n;
- ngx_uint_t find_config_index, use_rewrite, use_access;
- ngx_uint_t last, bind_all, done;
+ ngx_uint_t mi, m, s;
ngx_conf_t pcf;
- ngx_array_t headers_in, in_ports;
- ngx_hash_key_t *hk;
- ngx_hash_init_t hash;
- ngx_listening_t *ls;
- ngx_http_listen_t *lscf;
+ ngx_array_t in_ports;
ngx_http_module_t *module;
- ngx_http_header_t *header;
- ngx_http_in_port_t *hip;
- ngx_http_handler_pt *h;
ngx_http_conf_ctx_t *ctx;
- ngx_http_conf_in_port_t *in_port;
- ngx_http_conf_in_addr_t *in_addr;
- ngx_hash_keys_arrays_t ha;
- ngx_http_server_name_t *name;
- ngx_http_phase_handler_t *ph;
- ngx_http_virtual_names_t *vn;
- ngx_http_core_srv_conf_t **cscfp, *cscf;
ngx_http_core_loc_conf_t *clcf;
- ngx_http_phase_handler_pt checker;
+ ngx_http_core_srv_conf_t **cscfp;
ngx_http_core_main_conf_t *cmcf;
-#if (NGX_PCRE)
- ngx_uint_t regex;
-#endif
/* the main http context */
@@ -199,7 +205,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
module = ngx_modules[m]->ctx;
- mi = ngx_modules[m]->ctx_index;
if (module->preconfiguration) {
if (module->preconfiguration(cf) != NGX_OK) {
@@ -215,8 +220,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
rv = ngx_conf_parse(cf, NULL);
if (rv != NGX_CONF_OK) {
- *cf = pcf;
- return rv;
+ goto failed;
}
/*
@@ -240,8 +244,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (module->init_main_conf) {
rv = module->init_main_conf(cf, ctx->main_conf[mi]);
if (rv != NGX_CONF_OK) {
- *cf = pcf;
- return rv;
+ goto failed;
}
}
@@ -250,12 +253,10 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
/* merge the server{}s' srv_conf's */
if (module->merge_srv_conf) {
- rv = module->merge_srv_conf(cf,
- ctx->srv_conf[mi],
+ rv = module->merge_srv_conf(cf, ctx->srv_conf[mi],
cscfp[s]->ctx->srv_conf[mi]);
if (rv != NGX_CONF_OK) {
- *cf = pcf;
- return rv;
+ goto failed;
}
}
@@ -263,96 +264,187 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
/* merge the server{}'s loc_conf */
- rv = module->merge_loc_conf(cf,
- ctx->loc_conf[mi],
+ rv = module->merge_loc_conf(cf, ctx->loc_conf[mi],
cscfp[s]->ctx->loc_conf[mi]);
if (rv != NGX_CONF_OK) {
- *cf = pcf;
- return rv;
+ goto failed;
}
/* merge the locations{}' loc_conf's */
- rv = ngx_http_merge_locations(cf, &cscfp[s]->locations,
+ clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
+
+ rv = ngx_http_merge_locations(cf, clcf->locations,
cscfp[s]->ctx->loc_conf,
module, mi);
if (rv != NGX_CONF_OK) {
- *cf = pcf;
- return rv;
+ goto failed;
}
}
}
}
- /* init lists of the handlers */
+ /* create location trees */
+
+ for (s = 0; s < cmcf->servers.nelts; s++) {
+
+ clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
+
+ if (ngx_http_init_locations(cf, cscfp[s], clcf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+
+ if (ngx_http_init_phases(cf, cmcf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (ngx_http_init_headers_in_hash(cf, cmcf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+
+ for (m = 0; ngx_modules[m]; m++) {
+ if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
+ continue;
+ }
+
+ module = ngx_modules[m]->ctx;
+
+ if (module->postconfiguration) {
+ if (module->postconfiguration(cf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
+ }
+
+ if (ngx_http_variables_init_vars(cf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ /*
+ * http{}'s cf->ctx was needed while the configuration merging
+ * and in postconfiguration process
+ */
+ *cf = pcf;
+
+
+ if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+
+ /*
+ * create the lists of ports, addresses and server names
+ * to find quickly the server core module configuration at run-time
+ */
+
+ /* AF_INET only */
+
+ if (ngx_http_init_server_lists(cf, &cmcf->servers, &in_ports) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+
+ /* optimize the lists of ports, addresses and server names */
+
+ /* AF_INET only */
+
+ if (ngx_http_optimize_servers(cf, cmcf, &in_ports) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+
+failed:
+
+ *cf = pcf;
+
+ return rv;
+}
+
+
+static ngx_int_t
+ngx_http_init_phases(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
+{
if (ngx_array_init(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers,
cf->pool, 1, sizeof(ngx_http_handler_pt))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
-
if (ngx_array_init(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers,
cf->pool, 1, sizeof(ngx_http_handler_pt))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
-
if (ngx_array_init(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers,
cf->pool, 1, sizeof(ngx_http_handler_pt))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
-
if (ngx_array_init(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers,
cf->pool, 1, sizeof(ngx_http_handler_pt))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
-
if (ngx_array_init(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers,
cf->pool, 2, sizeof(ngx_http_handler_pt))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
-
if (ngx_array_init(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers,
cf->pool, 4, sizeof(ngx_http_handler_pt))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
-
if (ngx_array_init(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers,
cf->pool, 1, sizeof(ngx_http_handler_pt))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_init_headers_in_hash(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
+{
+ ngx_array_t headers_in;
+ ngx_hash_key_t *hk;
+ ngx_hash_init_t hash;
+ ngx_http_header_t *header;
if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
for (header = ngx_http_headers_in; header->name.len; header++) {
hk = ngx_array_push(&headers_in);
if (hk == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
hk->key = header->name;
@@ -369,36 +461,22 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
hash.temp_pool = NULL;
if (ngx_hash_init(&hash, headers_in.elts, headers_in.nelts) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
- mi = ngx_modules[m]->ctx_index;
-
- if (module->postconfiguration) {
- if (module->postconfiguration(cf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
- }
-
- if (ngx_http_variables_init_vars(cf) != NGX_OK) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
- /*
- * http{}'s cf->ctx was needed while the configuration merging
- * and in postconfiguration process
- */
+ return NGX_OK;
+}
- *cf = pcf;
+static ngx_int_t
+ngx_http_init_phase_handlers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
+{
+ ngx_int_t j;
+ ngx_uint_t i, n;
+ ngx_uint_t find_config_index, use_rewrite, use_access;
+ ngx_http_handler_pt *h;
+ ngx_http_phase_handler_t *ph;
+ ngx_http_phase_handler_pt checker;
cmcf->phase_engine.server_rewrite_index = (ngx_uint_t) -1;
cmcf->phase_engine.location_rewrite_index = (ngx_uint_t) -1;
@@ -415,7 +493,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ph = ngx_pcalloc(cf->pool,
n * sizeof(ngx_http_phase_handler_t) + sizeof(void *));
if (ph == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
cmcf->phase_engine.handlers = ph;
@@ -493,35 +571,548 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
+ return NGX_OK;
+}
- /*
- * create the lists of ports, addresses and server names
- * to quickly find the server core module configuration at run-time
- */
- if (ngx_array_init(&in_ports, cf->temp_pool, 2,
+static char *
+ngx_http_merge_locations(ngx_conf_t *cf, ngx_queue_t *locations,
+ void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index)
+{
+ char *rv;
+ ngx_queue_t *q;
+ ngx_http_core_loc_conf_t *clcf;
+ ngx_http_location_queue_t *lq;
+
+ if (locations == NULL) {
+ return NGX_CONF_OK;
+ }
+
+ for (q = ngx_queue_head(locations);
+ q != ngx_queue_sentinel(locations);
+ q = ngx_queue_next(q))
+ {
+ lq = (ngx_http_location_queue_t *) q;
+
+ clcf = lq->exact ? lq->exact : lq->inclusive;
+
+ rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
+ clcf->loc_conf[ctx_index]);
+ if (rv != NGX_CONF_OK) {
+ return rv;
+ }
+
+ rv = ngx_http_merge_locations(cf, clcf->locations, clcf->loc_conf,
+ module, ctx_index);
+ if (rv != NGX_CONF_OK) {
+ return rv;
+ }
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_http_init_locations(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+ ngx_http_core_loc_conf_t *pclcf)
+{
+ ngx_uint_t n;
+ ngx_queue_t *q, *locations, *named, tail;
+ ngx_http_core_loc_conf_t *clcf;
+ ngx_http_location_queue_t *lq;
+ ngx_http_core_loc_conf_t **clcfp;
+#if (NGX_PCRE)
+ ngx_uint_t r;
+ ngx_queue_t *regex;
+#endif
+
+ locations = pclcf->locations;
+
+ if (locations == NULL) {
+ return NGX_OK;
+ }
+
+ ngx_queue_sort(locations, ngx_http_cmp_locations);
+
+ named = NULL;
+ n = 0;
+#if (NGX_PCRE)
+ regex = NULL;
+ r = 0;
+#endif
+
+ for (q = ngx_queue_head(locations);
+ q != ngx_queue_sentinel(locations);
+ q = ngx_queue_next(q))
+ {
+ lq = (ngx_http_location_queue_t *) q;
+
+ clcf = lq->exact ? lq->exact : lq->inclusive;
+
+ if (ngx_http_init_locations(cf, NULL, clcf) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+#if (NGX_PCRE)
+
+ if (clcf->regex) {
+ r++;
+
+ if (regex == NULL) {
+ regex = q;
+ }
+
+ continue;
+ }
+
+#endif
+
+ if (clcf->named) {
+ n++;
+
+ if (named == NULL) {
+ named = q;
+ }
+
+ continue;
+ }
+
+ if (clcf->noname) {
+ break;
+ }
+ }
+
+ if (q != ngx_queue_sentinel(locations)) {
+ ngx_queue_split(locations, q, &tail);
+ }
+
+ if (named) {
+ clcfp = ngx_palloc(cf->pool,
+ (n + 1) * sizeof(ngx_http_core_loc_conf_t **));
+ if (clcfp == NULL) {
+ return NGX_ERROR;
+ }
+
+ cscf->named_locations = clcfp;
+
+ for (q = named;
+ q != ngx_queue_sentinel(locations);
+ q = ngx_queue_next(q))
+ {
+ lq = (ngx_http_location_queue_t *) q;
+
+ *(clcfp++) = lq->exact;
+ }
+
+ *clcfp = NULL;
+
+ ngx_queue_split(locations, named, &tail);
+ }
+
+#if (NGX_PCRE)
+
+ if (regex) {
+
+ clcfp = ngx_palloc(cf->pool,
+ (r + 1) * sizeof(ngx_http_core_loc_conf_t **));
+ if (clcfp == NULL) {
+ return NGX_ERROR;
+ }
+
+ pclcf->regex_locations = clcfp;
+
+ for (q = regex;
+ q != ngx_queue_sentinel(locations);
+ q = ngx_queue_next(q))
+ {
+ lq = (ngx_http_location_queue_t *) q;
+
+ *(clcfp++) = lq->exact;
+ }
+
+ *clcfp = NULL;
+
+ ngx_queue_split(locations, regex, &tail);
+ }
+
+#endif
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_init_static_location_trees(ngx_conf_t *cf,
+ ngx_http_core_loc_conf_t *pclcf)
+{
+ ngx_queue_t *q, *locations;
+ ngx_http_core_loc_conf_t *clcf;
+ ngx_http_location_queue_t *lq;
+
+ locations = pclcf->locations;
+
+ if (locations == NULL) {
+ return NGX_OK;
+ }
+
+ if (ngx_queue_empty(locations)) {
+ return NGX_OK;
+ }
+
+ for (q = ngx_queue_head(locations);
+ q != ngx_queue_sentinel(locations);
+ q = ngx_queue_next(q))
+ {
+ lq = (ngx_http_location_queue_t *) q;
+
+ clcf = lq->exact ? lq->exact : lq->inclusive;
+
+ if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
+ return NGX_ERROR;
+ }
+ }
+
+ if (ngx_http_join_exact_locations(cf, locations) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ngx_http_create_locations_list(locations, ngx_queue_head(locations));
+
+ pclcf->static_locations = ngx_http_create_locations_tree(cf, locations, 0);
+ if (pclcf->static_locations == NULL) {
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
+ ngx_http_core_loc_conf_t *clcf)
+{
+ ngx_http_location_queue_t *lq;
+
+ if (*locations == NULL) {
+ *locations = ngx_palloc(cf->temp_pool,
+ sizeof(ngx_http_location_queue_t));
+ if (*locations == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_queue_init(*locations);
+ }
+
+ lq = ngx_palloc(cf->temp_pool, sizeof(ngx_http_location_queue_t));
+ if (lq == NULL) {
+ return NGX_ERROR;
+ }
+
+ if (clcf->exact_match
+#if (NGX_PCRE)
+ || clcf->regex
+#endif
+ || clcf->named || clcf->noname)
+ {
+ lq->exact = clcf;
+ lq->inclusive = NULL;
+
+ } else {
+ lq->exact = NULL;
+ lq->inclusive = clcf;
+ }
+
+ lq->name = &clcf->name;
+ lq->file_name = cf->conf_file->file.name.data;
+ lq->line = cf->conf_file->line;
+
+ ngx_queue_init(&lq->list);
+
+ ngx_queue_insert_tail(*locations, &lq->queue);
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_cmp_locations(const ngx_queue_t *one, const ngx_queue_t *two)
+{
+ ngx_int_t rc;
+ ngx_http_core_loc_conf_t *first, *second;
+ ngx_http_location_queue_t *lq1, *lq2;
+
+ lq1 = (ngx_http_location_queue_t *) one;
+ lq2 = (ngx_http_location_queue_t *) two;
+
+ first = lq1->exact ? lq1->exact : lq1->inclusive;
+ second = lq2->exact ? lq2->exact : lq2->inclusive;
+
+ if (first->noname && !second->noname) {
+ /* shift no named locations to the end */
+ return 1;
+ }
+
+ if (!first->noname && second->noname) {
+ /* shift no named locations to the end */
+ return -1;
+ }
+
+ if (first->noname || second->noname) {
+ /* do not sort no named locations */
+ return 0;
+ }
+
+ if (first->named && !second->named) {
+ /* shift named locations to the end */
+ return 1;
+ }
+
+ if (!first->named && second->named) {
+ /* shift named locations to the end */
+ return -1;
+ }
+
+ if (first->named && second->named) {
+ return ngx_strcmp(first->name.data, second->name.data);
+ }
+
+#if (NGX_PCRE)
+
+ if (first->regex && !second->regex) {
+ /* shift the regex matches to the end */
+ return 1;
+ }
+
+ if (!first->regex && second->regex) {
+ /* shift the regex matches to the end */
+ return -1;
+ }
+
+ if (first->regex || second->regex) {
+ /* do not sort the regex matches */
+ return 0;
+ }
+
+#endif
+
+ rc = ngx_strcmp(first->name.data, second->name.data);
+
+ if (rc == 0 && !first->exact_match && second->exact_match) {
+ /* an exact match must be before the same inclusive one */
+ return 1;
+ }
+
+ return rc;
+}
+
+
+static ngx_int_t
+ngx_http_join_exact_locations(ngx_conf_t *cf, ngx_queue_t *locations)
+{
+ ngx_queue_t *q, *x;
+ ngx_http_location_queue_t *lq, *lx;
+
+ q = ngx_queue_head(locations);
+
+ while (q != ngx_queue_last(locations)) {
+
+ x = ngx_queue_next(q);
+
+ lq = (ngx_http_location_queue_t *) q;
+ lx = (ngx_http_location_queue_t *) x;
+
+ if (ngx_strcmp(lq->name->data, lx->name->data) == 0) {
+
+ if ((lq->exact && lx->exact) || (lq->inclusive && lx->inclusive)) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "duplicate location \"%V\" in %s:%ui",
+ lx->name, lx->file_name, lx->line);
+
+ return NGX_ERROR;
+ }
+
+ lq->inclusive = lx->inclusive;
+
+ ngx_queue_remove(x);
+
+ continue;
+ }
+
+ q = ngx_queue_next(q);
+ }
+
+ return NGX_OK;
+}
+
+
+static void
+ngx_http_create_locations_list(ngx_queue_t *locations, ngx_queue_t *q)
+{
+ u_char *name;
+ size_t len;
+ ngx_queue_t *x, tail;
+ ngx_http_location_queue_t *lq, *lx;
+
+ if (q == ngx_queue_last(locations)) {
+ return;
+ }
+
+ lq = (ngx_http_location_queue_t *) q;
+
+ if (lq->inclusive == NULL) {
+ ngx_http_create_locations_list(locations, ngx_queue_next(q));
+ return;
+ }
+
+ len = lq->name->len;
+ name = lq->name->data;
+
+ for (x = ngx_queue_next(q);
+ x != ngx_queue_sentinel(locations);
+ x = ngx_queue_next(x))
+ {
+ lx = (ngx_http_location_queue_t *) x;
+
+ if (len > lx->name->len
+ || (ngx_strncmp(name, lx->name->data, len) != 0))
+ {
+ break;
+ }
+ }
+
+ q = ngx_queue_next(q);
+
+ if (q == x) {
+ ngx_http_create_locations_list(locations, x);
+ return;
+ }
+
+ ngx_queue_split(locations, q, &tail);
+ ngx_queue_add(&lq->list, &tail);
+
+ if (x == ngx_queue_sentinel(locations)) {
+ ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
+ return;
+ }
+
+ ngx_queue_split(&lq->list, x, &tail);
+ ngx_queue_add(locations, &tail);
+
+ ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
+
+ ngx_http_create_locations_list(locations, x);
+}
+
+
+/*
+ * to keep cache locality for left leaf nodes, allocate nodes in following
+ * order: node, left subtree, right subtree, inclusive subtree
+ */
+
+static ngx_http_location_tree_node_t *
+ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
+ size_t prefix)
+{
+ size_t len;
+ ngx_queue_t *q, tail;
+ ngx_http_location_queue_t *lq;
+ ngx_http_location_tree_node_t *node;
+
+ q = ngx_queue_middle(locations);
+
+ lq = (ngx_http_location_queue_t *) q;
+ len = lq->name->len - prefix;
+
+ node = ngx_pcalloc(cf->pool,
+ offsetof(ngx_http_location_tree_node_t, name) + len);
+ if (node == NULL) {
+ return NULL;
+ }
+
+ node->exact = lq->exact;
+ node->inclusive = lq->inclusive;
+
+ node->auto_redirect = (u_char) ((lq->exact && lq->exact->auto_redirect)
+ || (lq->inclusive && lq->inclusive->auto_redirect));
+
+ node->len = (u_char) len;
+ ngx_memcpy(node->name, &lq->name->data[prefix], len);
+
+ ngx_queue_split(locations, q, &tail);
+
+ if (ngx_queue_empty(locations)) {
+ /*
+ * ngx_queue_split() insures that if left part is empty,
+ * then right one is empty too
+ */
+ goto inclusive;
+ }
+
+ node->left = ngx_http_create_locations_tree(cf, locations, prefix);
+ if (node->left == NULL) {
+ return NULL;
+ }
+
+ ngx_queue_remove(q);
+
+ if (ngx_queue_empty(&tail)) {
+ goto inclusive;
+ }
+
+ node->right = ngx_http_create_locations_tree(cf, &tail, prefix);
+ if (node->right == NULL) {
+ return NULL;
+ }
+
+inclusive:
+
+ if (ngx_queue_empty(&lq->list)) {
+ return node;
+ }
+
+ node->tree = ngx_http_create_locations_tree(cf, &lq->list, prefix + len);
+ if (node->tree == NULL) {
+ return NULL;
+ }
+
+ return node;
+}
+
+
+static ngx_int_t
+ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers,
+ ngx_array_t *in_ports)
+{
+ ngx_uint_t s, l, p, a;
+ ngx_http_listen_t *listen;
+ ngx_http_conf_in_port_t *in_port;
+ ngx_http_conf_in_addr_t *in_addr;
+ ngx_http_core_srv_conf_t **cscfp;
+
+ if (ngx_array_init(in_ports, cf->temp_pool, 2,
sizeof(ngx_http_conf_in_port_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
/* "server" directives */
- cscfp = cmcf->servers.elts;
- for (s = 0; s < cmcf->servers.nelts; s++) {
+ cscfp = servers->elts;
+ for (s = 0; s < servers->nelts; s++) {
/* "listen" directives */
- lscf = cscfp[s]->listen.elts;
+ listen = cscfp[s]->listen.elts;
for (l = 0; l < cscfp[s]->listen.nelts; l++) {
/* AF_INET only */
- in_port = in_ports.elts;
- for (p = 0; p < in_ports.nelts; p++) {
+ in_port = in_ports->elts;
+ for (p = 0; p < in_ports->nelts; p++) {
- if (lscf[l].port != in_port[p].port) {
+ if (listen[l].port != in_port[p].port) {
continue;
}
@@ -530,15 +1121,15 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
in_addr = in_port[p].addrs.elts;
for (a = 0; a < in_port[p].addrs.nelts; a++) {
- if (lscf[l].addr != in_addr[a].addr) {
+ if (listen[l].addr != in_addr[a].addr) {
continue;
}
/* the address is already in the address list */
- if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) != NGX_OK)
+ if (ngx_http_add_names(cf, cscfp[s], &in_addr[a]) != NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
/*
@@ -546,14 +1137,14 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
* for this address:port
*/
- if (lscf[l].conf.default_server) {
+ if (listen[l].conf.default_server) {
if (in_addr[a].default_server) {
ngx_log_error(NGX_LOG_ERR, cf->log, 0,
"the duplicate default server in %s:%ui",
- lscf[l].file_name, lscf[l].line);
+ listen[l].file_name, listen[l].line);
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
in_addr[a].core_srv_conf = cscfp[s];
@@ -568,10 +1159,10 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
* bound to this port
*/
- if (ngx_http_add_address(cf, &in_port[p], &lscf[l], cscfp[s])
+ if (ngx_http_add_address(cf, cscfp[s], &in_port[p], &listen[l])
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
goto found;
@@ -579,17 +1170,18 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
/* add the port to the in_port list */
- in_port = ngx_array_push(&in_ports);
+ in_port = ngx_array_push(in_ports);
if (in_port == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
- in_port->port = lscf[l].port;
+ in_port->port = listen[l].port;
in_port->addrs.elts = NULL;
- if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s]) != NGX_OK)
+ if (ngx_http_add_address(cf, cscfp[s], in_port, &listen[l])
+ != NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
found:
@@ -598,21 +1190,132 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
+ return NGX_OK;
+}
- /* optimize the lists of ports, addresses and server names */
- /* AF_INET only */
+/*
+ * add the server address, the server names and the server core module
+ * configurations to the port (in_port)
+ */
+
+static ngx_int_t
+ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+ ngx_http_conf_in_port_t *in_port, ngx_http_listen_t *listen)
+{
+ ngx_http_conf_in_addr_t *in_addr;
+
+ if (in_port->addrs.elts == NULL) {
+ if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4,
+ sizeof(ngx_http_conf_in_addr_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+ }
+
+ in_addr = ngx_array_push(&in_port->addrs);
+ if (in_addr == NULL) {
+ return NGX_ERROR;
+ }
+
+ in_addr->addr = listen->addr;
+ in_addr->hash.buckets = NULL;
+ in_addr->hash.size = 0;
+ in_addr->wc_head = NULL;
+ in_addr->wc_tail = NULL;
+ in_addr->names.elts = NULL;
+#if (NGX_PCRE)
+ in_addr->nregex = 0;
+ in_addr->regex = NULL;
+#endif
+ in_addr->core_srv_conf = cscf;
+ in_addr->default_server = listen->conf.default_server;
+ in_addr->bind = listen->conf.bind;
+ in_addr->listen_conf = &listen->conf;
+
+#if (NGX_DEBUG)
+ {
+ u_char text[20];
+ ngx_inet_ntop(AF_INET, &in_addr->addr, text, 20);
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "address: %s:%d",
+ text, in_port->port);
+ }
+#endif
+
+ return ngx_http_add_names(cf, cscf, in_addr);
+}
- in_port = in_ports.elts;
- for (p = 0; p < in_ports.nelts; p++) {
+
+/*
+ * add the server names and the server core module
+ * configurations to the address:port (in_addr)
+ */
+
+static ngx_int_t
+ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+ ngx_http_conf_in_addr_t *in_addr)
+{
+ ngx_uint_t i, n;
+ ngx_http_server_name_t *server_names, *name;
+
+ if (in_addr->names.elts == NULL) {
+ if (ngx_array_init(&in_addr->names, cf->temp_pool, 4,
+ sizeof(ngx_http_server_name_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+ }
+
+ server_names = cscf->server_names.elts;
+
+ for (i = 0; i < cscf->server_names.nelts; i++) {
+
+ for (n = 0; n < server_names[i].name.len; n++) {
+ server_names[i].name.data[n] =
+ ngx_tolower(server_names[i].name.data[n]);
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
+ "name: %V", &server_names[i].name);
+
+ name = ngx_array_push(&in_addr->names);
+ if (name == NULL) {
+ return NGX_ERROR;
+ }
+
+ *name = server_names[i];
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
+ ngx_array_t *in_ports)
+{
+ ngx_int_t rc;
+ ngx_uint_t s, p, a, i;
+ ngx_hash_init_t hash;
+ ngx_http_server_name_t *name;
+ ngx_hash_keys_arrays_t ha;
+ ngx_http_conf_in_port_t *in_port;
+ ngx_http_conf_in_addr_t *in_addr;
+#if (NGX_PCRE)
+ ngx_uint_t regex;
+#endif
+
+ in_port = in_ports->elts;
+ for (p = 0; p < in_ports->nelts; p++) {
ngx_sort(in_port[p].addrs.elts, (size_t) in_port[p].addrs.nelts,
sizeof(ngx_http_conf_in_addr_t), ngx_http_cmp_conf_in_addrs);
/*
- * check whether all name-based servers have the same configuraiton
- * as the default server,
- * or some servers disable optimizing the server names
+ * check whether all name-based servers have
+ * the same configuraiton as the default server
*/
in_addr = in_port[p].addrs.elts;
@@ -621,18 +1324,15 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
name = in_addr[a].names.elts;
for (s = 0; s < in_addr[a].names.nelts; s++) {
- if (in_addr[a].core_srv_conf != name[s].core_srv_conf
- || name[s].core_srv_conf->optimize_server_names == 0)
- {
+ if (in_addr[a].core_srv_conf != name[s].core_srv_conf) {
goto virtual_names;
}
}
/*
* if all name-based servers have the same configuration
- * as the default server,
- * and no servers disable optimizing the server names
- * then we do not need to check them at run-time at all
+ * as the default server, then we do not need to check
+ * them at run-time at all
*/
in_addr[a].names.nelts = 0;
@@ -645,14 +1345,13 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ha.temp_pool = ngx_create_pool(16384, cf->log);
if (ha.temp_pool == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
ha.pool = cf->pool;
if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
- ngx_destroy_pool(ha.temp_pool);
- return NGX_CONF_ERROR;
+ goto failed;
}
#if (NGX_PCRE)
@@ -674,14 +1373,14 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
NGX_HASH_WILDCARD_KEY);
if (rc == NGX_ERROR) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
if (rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"invalid server name or wildcard \"%V\" on %s",
&name[s].name, in_addr[a].listen_conf->addr);
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
if (rc == NGX_BUSY) {
@@ -703,8 +1402,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK)
{
- ngx_destroy_pool(ha.temp_pool);
- return NGX_CONF_ERROR;
+ goto failed;
}
}
@@ -722,8 +1420,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ha.dns_wc_head.nelts)
!= NGX_OK)
{
- ngx_destroy_pool(ha.temp_pool);
- return NGX_CONF_ERROR;
+ goto failed;
}
in_addr[a].wc_head = (ngx_hash_wildcard_t *) hash.hash;
@@ -743,8 +1440,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ha.dns_wc_tail.nelts)
!= NGX_OK)
{
- ngx_destroy_pool(ha.temp_pool);
- return NGX_CONF_ERROR;
+ goto failed;
}
in_addr[a].wc_tail = (ngx_hash_wildcard_t *) hash.hash;
@@ -763,7 +1459,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
regex * sizeof(ngx_http_server_name_t));
if (in_addr[a].regex == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
for (i = 0, s = 0; s < in_addr[a].names.nelts; s++) {
@@ -774,357 +1470,219 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#endif
}
- in_addr = in_port[p].addrs.elts;
- last = in_port[p].addrs.nelts;
-
- /*
- * if there is the binding to the "*:port" then we need to bind()
- * to the "*:port" only and ignore the other bindings
- */
-
- if (in_addr[last - 1].addr == INADDR_ANY) {
- in_addr[last - 1].bind = 1;
- bind_all = 0;
-
- } else {
- bind_all = 1;
+ if (ngx_http_init_listening(cf, &in_port[p]) != NGX_OK) {
+ return NGX_ERROR;
}
+ }
- for (a = 0; a < last; /* void */ ) {
-
- if (!bind_all && !in_addr[a].bind) {
- a++;
- continue;
- }
-
- ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr,
- in_port[p].port);
- if (ls == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ls->addr_ntop = 1;
-
- ls->handler = ngx_http_init_connection;
-
- cscf = in_addr[a].core_srv_conf;
- ls->pool_size = cscf->connection_pool_size;
- ls->post_accept_timeout = cscf->client_header_timeout;
-
- clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
+ return NGX_OK;
- ls->log = *clcf->err_log;
- ls->log.data = &ls->addr_text;
- ls->log.handler = ngx_accept_log_error;
+failed:
-#if (NGX_WIN32)
- {
- ngx_iocp_conf_t *iocpcf;
+ ngx_destroy_pool(ha.temp_pool);
- iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
- if (iocpcf->acceptex_read) {
- ls->post_accept_buffer_size = cscf->client_header_buffer_size;
- }
- }
-#endif
+ return NGX_ERROR;
+}
- ls->backlog = in_addr[a].listen_conf->backlog;
- ls->rcvbuf = in_addr[a].listen_conf->rcvbuf;
- ls->sndbuf = in_addr[a].listen_conf->sndbuf;
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- ls->accept_filter = in_addr[a].listen_conf->accept_filter;
-#endif
+static ngx_int_t
+ngx_http_cmp_conf_in_addrs(const void *one, const void *two)
+{
+ ngx_http_conf_in_addr_t *first, *second;
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- ls->deferred_accept = in_addr[a].listen_conf->deferred_accept;
-#endif
+ first = (ngx_http_conf_in_addr_t *) one;
+ second = (ngx_http_conf_in_addr_t *) two;
- hip = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t));
- if (hip == NULL) {
- return NGX_CONF_ERROR;
- }
+ if (first->addr == INADDR_ANY) {
+ /* the INADDR_ANY must be the last resort, shift it to the end */
+ return 1;
+ }
- hip->port = in_port[p].port;
+ if (first->bind && !second->bind) {
+ /* shift explicit bind()ed addresses to the start */
+ return -1;
+ }
- hip->port_text.data = ngx_palloc(cf->pool, 7);
- if (hip->port_text.data == NULL) {
- return NGX_CONF_ERROR;
- }
+ if (!first->bind && second->bind) {
+ /* shift explicit bind()ed addresses to the start */
+ return 1;
+ }
- ls->servers = hip;
+ /* do not sort by default */
- hip->port_text.len = ngx_sprintf(hip->port_text.data, ":%d",
- hip->port)
- - hip->port_text.data;
+ return 0;
+}
- in_addr = in_port[p].addrs.elts;
- if (in_addr[a].bind && in_addr[a].addr != INADDR_ANY) {
- hip->naddrs = 1;
- done = 0;
+static int ngx_libc_cdecl
+ngx_http_cmp_dns_wildcards(const void *one, const void *two)
+{
+ ngx_hash_key_t *first, *second;
- } else if (in_port[p].addrs.nelts > 1
- && in_addr[last - 1].addr == INADDR_ANY)
- {
- hip->naddrs = last;
- done = 1;
+ first = (ngx_hash_key_t *) one;
+ second = (ngx_hash_key_t *) two;
- } else {
- hip->naddrs = 1;
- done = 0;
- }
+ return ngx_strcmp(first->key.data, second->key.data);
+}
-#if 0
- ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
- "%ui: %V %d %ui %ui",
- a, &ls->addr_text, in_addr[a].bind,
- hip->naddrs, last);
-#endif
- hip->addrs = ngx_pcalloc(cf->pool,
- hip->naddrs * sizeof(ngx_http_in_addr_t));
- if (hip->addrs == NULL) {
- return NGX_CONF_ERROR;
- }
+static ngx_int_t
+ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port)
+{
+ ngx_uint_t i, a, last, bind_all, done;
+ ngx_listening_t *ls;
+ ngx_http_in_port_t *hip;
+ ngx_http_conf_in_addr_t *in_addr;
+ ngx_http_virtual_names_t *vn;
+ ngx_http_core_loc_conf_t *clcf;
+ ngx_http_core_srv_conf_t *cscf;
- for (i = 0; i < hip->naddrs; i++) {
- hip->addrs[i].addr = in_addr[i].addr;
- hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf;
+ in_addr = in_port->addrs.elts;
+ last = in_port->addrs.nelts;
- if (in_addr[i].hash.buckets == NULL
- && (in_addr[i].wc_head == NULL
- || in_addr[i].wc_head->hash.buckets == NULL)
- && (in_addr[i].wc_head == NULL
- || in_addr[i].wc_head->hash.buckets == NULL))
- {
- continue;
- }
+ /*
+ * if there is a binding to a "*:port" then we need to bind()
+ * to the "*:port" only and ignore other bindings
+ */
- vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
- if (vn == NULL) {
- return NGX_CONF_ERROR;
- }
- hip->addrs[i].virtual_names = vn;
+ if (in_addr[last - 1].addr == INADDR_ANY) {
+ in_addr[last - 1].bind = 1;
+ bind_all = 0;
- vn->names.hash = in_addr[i].hash;
- vn->names.wc_head = in_addr[i].wc_head;
- vn->names.wc_tail = in_addr[i].wc_tail;
-#if (NGX_PCRE)
- vn->nregex = in_addr[i].nregex;
- vn->regex = in_addr[i].regex;
-#endif
- }
+ } else {
+ bind_all = 1;
+ }
- if (done) {
- break;
- }
+ a = 0;
- in_addr++;
- in_port[p].addrs.elts = in_addr;
- last--;
+ while (a < last) {
- a = 0;
+ if (!bind_all && !in_addr[a].bind) {
+ a++;
+ continue;
}
- }
-#if 0
- {
- u_char address[20];
- ngx_uint_t p, a;
-
- in_port = in_ports.elts;
- for (p = 0; p < in_ports.nelts; p++) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "port: %d %p", in_port[p].port, &in_port[p]);
- in_addr = in_port[p].addrs.elts;
- for (a = 0; a < in_port[p].addrs.nelts; a++) {
- ngx_inet_ntop(AF_INET, &in_addr[a].addr, address, 20);
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "%s:%d %p",
- address, in_port[p].port, in_addr[a].core_srv_conf);
- name = in_addr[a].names.elts;
- for (n = 0; n < in_addr[a].names.nelts; n++) {
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "%s:%d %V %p",
- address, in_port[p].port, &name[n].name,
- name[n].core_srv_conf);
- }
+ ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr,
+ in_port->port);
+ if (ls == NULL) {
+ return NGX_ERROR;
}
- }
- }
-#endif
- return NGX_CONF_OK;
-}
+ ls->addr_ntop = 1;
+ ls->handler = ngx_http_init_connection;
-/*
- * add the server address, the server names and the server core module
- * configurations to the port (in_port)
- */
+ cscf = in_addr[a].core_srv_conf;
+ ls->pool_size = cscf->connection_pool_size;
+ ls->post_accept_timeout = cscf->client_header_timeout;
-static ngx_int_t
-ngx_http_add_address(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port,
- ngx_http_listen_t *lscf, ngx_http_core_srv_conf_t *cscf)
-{
- ngx_http_conf_in_addr_t *in_addr;
+ clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
- if (in_port->addrs.elts == NULL) {
- if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4,
- sizeof(ngx_http_conf_in_addr_t))
- != NGX_OK)
+ ls->log = *clcf->err_log;
+ ls->log.data = &ls->addr_text;
+ ls->log.handler = ngx_accept_log_error;
+
+#if (NGX_WIN32)
{
- return NGX_ERROR;
+ ngx_iocp_conf_t *iocpcf;
+
+ iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
+ if (iocpcf->acceptex_read) {
+ ls->post_accept_buffer_size = cscf->client_header_buffer_size;
}
- }
+ }
+#endif
- in_addr = ngx_array_push(&in_port->addrs);
- if (in_addr == NULL) {
- return NGX_ERROR;
- }
+ ls->backlog = in_addr[a].listen_conf->backlog;
+ ls->rcvbuf = in_addr[a].listen_conf->rcvbuf;
+ ls->sndbuf = in_addr[a].listen_conf->sndbuf;
- in_addr->addr = lscf->addr;
- in_addr->hash.buckets = NULL;
- in_addr->hash.size = 0;
- in_addr->wc_head = NULL;
- in_addr->wc_tail = NULL;
- in_addr->names.elts = NULL;
-#if (NGX_PCRE)
- in_addr->nregex = 0;
- in_addr->regex = NULL;
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
+ ls->accept_filter = in_addr[a].listen_conf->accept_filter;
#endif
- in_addr->core_srv_conf = cscf;
- in_addr->default_server = lscf->conf.default_server;
- in_addr->bind = lscf->conf.bind;
- in_addr->listen_conf = &lscf->conf;
-#if (NGX_DEBUG)
- {
- u_char text[20];
- ngx_inet_ntop(AF_INET, &in_addr->addr, text, 20);
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "address: %s:%d",
- text, in_port->port);
- }
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+ ls->deferred_accept = in_addr[a].listen_conf->deferred_accept;
#endif
- return ngx_http_add_names(cf, in_addr, cscf);
-}
-
-
-/*
- * add the server names and the server core module
- * configurations to the address:port (in_addr)
- */
-
-static ngx_int_t
-ngx_http_add_names(ngx_conf_t *cf, ngx_http_conf_in_addr_t *in_addr,
- ngx_http_core_srv_conf_t *cscf)
-{
- ngx_uint_t i, n;
- ngx_http_server_name_t *server_names, *name;
-
- if (in_addr->names.elts == NULL) {
- if (ngx_array_init(&in_addr->names, cf->temp_pool, 4,
- sizeof(ngx_http_server_name_t))
- != NGX_OK)
- {
+ hip = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t));
+ if (hip == NULL) {
return NGX_ERROR;
}
- }
- server_names = cscf->server_names.elts;
-
- for (i = 0; i < cscf->server_names.nelts; i++) {
+ hip->port = in_port->port;
- for (n = 0; n < server_names[i].name.len; n++) {
- server_names[i].name.data[n] =
- ngx_tolower(server_names[i].name.data[n]);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "name: %V", &server_names[i].name);
-
- name = ngx_array_push(&in_addr->names);
- if (name == NULL) {
+ hip->port_text.data = ngx_palloc(cf->pool, 7);
+ if (hip->port_text.data == NULL) {
return NGX_ERROR;
}
- *name = server_names[i];
- }
+ ls->servers = hip;
- return NGX_OK;
-}
+ hip->port_text.len = ngx_sprintf(hip->port_text.data, ":%d", hip->port)
+ - hip->port_text.data;
+ in_addr = in_port->addrs.elts;
-static char *
-ngx_http_merge_locations(ngx_conf_t *cf, ngx_array_t *locations,
- void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index)
-{
- char *rv;
- ngx_uint_t i;
- ngx_http_core_loc_conf_t **clcfp;
+ if (in_addr[a].bind && in_addr[a].addr != INADDR_ANY) {
+ hip->naddrs = 1;
+ done = 0;
- clcfp = locations->elts;
-
- for (i = 0; i < locations->nelts; i++) {
- rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
- clcfp[i]->loc_conf[ctx_index]);
- if (rv != NGX_CONF_OK) {
- return rv;
- }
+ } else if (in_port->addrs.nelts > 1
+ && in_addr[last - 1].addr == INADDR_ANY)
+ {
+ hip->naddrs = last;
+ done = 1;
- if (clcfp[i]->locations == NULL) {
- continue;
+ } else {
+ hip->naddrs = 1;
+ done = 0;
}
- rv = ngx_http_merge_locations(cf, clcfp[i]->locations,
- clcfp[i]->loc_conf, module, ctx_index);
- if (rv != NGX_CONF_OK) {
- return rv;
+ hip->addrs = ngx_pcalloc(cf->pool,
+ hip->naddrs * sizeof(ngx_http_in_addr_t));
+ if (hip->addrs == NULL) {
+ return NGX_ERROR;
}
- }
- return NGX_CONF_OK;
-}
+ for (i = 0; i < hip->naddrs; i++) {
+ hip->addrs[i].addr = in_addr[i].addr;
+ hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf;
+ if (in_addr[i].hash.buckets == NULL
+ && (in_addr[i].wc_head == NULL
+ || in_addr[i].wc_head->hash.buckets == NULL)
+ && (in_addr[i].wc_head == NULL
+ || in_addr[i].wc_head->hash.buckets == NULL))
+ {
+ continue;
+ }
-static ngx_int_t
-ngx_http_cmp_conf_in_addrs(const void *one, const void *two)
-{
- ngx_http_conf_in_addr_t *first, *second;
+ vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
+ if (vn == NULL) {
+ return NGX_ERROR;
+ }
+ hip->addrs[i].virtual_names = vn;
- first = (ngx_http_conf_in_addr_t *) one;
- second = (ngx_http_conf_in_addr_t *) two;
+ vn->names.hash = in_addr[i].hash;
+ vn->names.wc_head = in_addr[i].wc_head;
+ vn->names.wc_tail = in_addr[i].wc_tail;
+#if (NGX_PCRE)
+ vn->nregex = in_addr[i].nregex;
+ vn->regex = in_addr[i].regex;
+#endif
+ }
- if (first->addr == INADDR_ANY) {
- /* the INADDR_ANY must be the last resort, shift it to the end */
- return 1;
- }
+ if (done) {
+ return NGX_OK;
+ }
- if (first->bind && !second->bind) {
- /* shift explicit bind()ed addresses to the start */
- return -1;
- }
+ in_addr++;
+ in_port->addrs.elts = in_addr;
+ last--;
- if (!first->bind && second->bind) {
- /* shift explicit bind()ed addresses to the start */
- return 1;
+ a = 0;
}
- /* do not sort by default */
-
- return 0;
-}
-
-
-static int ngx_libc_cdecl
-ngx_http_cmp_dns_wildcards(const void *one, const void *two)
-{
- ngx_hash_key_t *first, *second;
-
- first = (ngx_hash_key_t *) one;
- second = (ngx_hash_key_t *) two;
-
- return ngx_strcmp(first->key.data, second->key.data);
+ return NGX_OK;
}
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 41b6c06b5..fe2b7cc6c 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -57,6 +57,10 @@ struct ngx_http_log_ctx_s {
#define ngx_http_set_ctx(r, c, module) r->ctx[module.ctx_index] = c;
+ngx_int_t ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
+ ngx_http_core_loc_conf_t *clcf);
+
+
void ngx_http_init_connection(ngx_connection_t *c);
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
@@ -106,10 +110,6 @@ void ngx_http_block_reading(ngx_http_request_t *r);
extern ngx_module_t ngx_http_module;
-extern ngx_uint_t ngx_http_total_requests;
-extern uint64_t ngx_http_total_sent;
-
-
extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;
extern ngx_http_output_body_filter_pt ngx_http_top_body_filter;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index f9b11b930..76d40ea0f 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -17,19 +17,14 @@ typedef struct {
} ngx_http_method_name_t;
-#define NGX_HTTP_LOCATION_EXACT 1
-#define NGX_HTTP_LOCATION_AUTO_REDIRECT 2
-#define NGX_HTTP_LOCATION_NOREGEX 3
-#define NGX_HTTP_LOCATION_REGEX 4
-
-
#define NGX_HTTP_REQUEST_BODY_FILE_OFF 0
#define NGX_HTTP_REQUEST_BODY_FILE_ON 1
#define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2
-static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
- ngx_array_t *locations, ngx_uint_t regex_start, size_t len);
+static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r);
+static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
+ ngx_http_location_tree_node_t *node);
static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
@@ -45,8 +40,6 @@ static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
void *dummy);
static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
void *dummy);
-static ngx_int_t ngx_http_core_cmp_locations(const void *first,
- const void *second);
static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -86,8 +79,8 @@ static ngx_conf_post_t ngx_http_core_lowat_post =
static ngx_conf_post_handler_pt ngx_http_core_pool_size_p =
ngx_http_core_pool_size;
-static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_host_names = {
- ngx_conf_deprecated, "optimize_host_names", "optimize_server_names"
+static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_server_names = {
+ ngx_conf_deprecated, "optimize_server_names", "server_name_in_redirect"
};
static ngx_conf_deprecated_t ngx_conf_deprecated_open_file_cache_retest = {
@@ -219,16 +212,9 @@ static ngx_command_t ngx_http_core_commands[] = {
{ ngx_string("optimize_server_names"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_core_srv_conf_t, optimize_server_names),
- NULL },
-
- { ngx_string("optimize_host_names"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_core_srv_conf_t, optimize_server_names),
- &ngx_conf_deprecated_optimize_host_names },
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
+ &ngx_conf_deprecated_optimize_server_names },
{ ngx_string("ignore_invalid_headers"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
@@ -787,14 +773,11 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
size_t len;
ngx_int_t rc;
ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_srv_conf_t *cscf;
r->content_handler = NULL;
r->uri_changed = 0;
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- rc = ngx_http_core_find_location(r, &cscf->locations, cscf->regex_start, 0);
+ rc = ngx_http_core_find_location(r);
if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -832,8 +815,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
return NGX_OK;
}
-
- if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) {
+ if (rc == NGX_DONE) {
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.location == NULL) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -1112,143 +1094,148 @@ ngx_http_update_location_config(ngx_http_request_t *r)
static ngx_int_t
-ngx_http_core_find_location(ngx_http_request_t *r,
- ngx_array_t *locations, ngx_uint_t regex_start, size_t len)
+ngx_http_core_find_location(ngx_http_request_t *r)
{
- ngx_int_t n, rc;
- ngx_uint_t i, found;
- ngx_http_core_loc_conf_t *clcf, **clcfp;
-#if (NGX_PCRE)
- ngx_uint_t noregex;
-#endif
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "find location for \"%V\"", &r->uri);
+ ngx_int_t rc;
+ ngx_http_core_loc_conf_t *pclcf;
- found = 0;
-#if (NGX_PCRE)
- noregex = 0;
-#endif
+ pclcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- clcfp = locations->elts;
- for (i = 0; i < locations->nelts; i++) {
+ rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
- if (clcfp[i]->noname
-#if (NGX_PCRE)
- || clcfp[i]->regex
-#endif
- || clcfp[i]->named)
- {
- break;
- }
+ if (rc == NGX_AGAIN) {
+ /* look up nested locations */
+ rc = ngx_http_core_find_location(r);
+ }
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "find location: %s\"%V\"",
- clcfp[i]->exact_match ? "= " : "", &clcfp[i]->name);
-
- if (clcfp[i]->auto_redirect
- && r->uri.len == clcfp[i]->name.len - 1
- && ngx_strncmp(r->uri.data, clcfp[i]->name.data,
- clcfp[i]->name.len - 1)
- == 0)
- {
- /* the locations are lexicographically sorted */
+ if (rc == NGX_OK || rc == NGX_DONE) {
+ return rc;
+ }
- r->loc_conf = clcfp[i]->loc_conf;
+ /* rc == NGX_DECLINED or rc == NGX_AGAIN in nested location */
- return NGX_HTTP_LOCATION_AUTO_REDIRECT;
- }
+#if (NGX_PCRE)
+ {
+ ngx_int_t n;
+ ngx_http_core_loc_conf_t *clcf, **clcfp;
- if (r->uri.len < clcfp[i]->name.len) {
- continue;
- }
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- n = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len);
+ if (clcf->noregex == 0 && pclcf->regex_locations) {
- if (n < 0) {
- /* the locations are lexicographically sorted */
- break;
- }
+ for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {
- if (n == 0) {
- if (clcfp[i]->exact_match) {
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "test location: ~ \"%V\"", &(*clcfp)->name);
- if (r->uri.len == clcfp[i]->name.len) {
- r->loc_conf = clcfp[i]->loc_conf;
- return NGX_HTTP_LOCATION_EXACT;
- }
+ n = ngx_regex_exec((*clcfp)->regex, &r->uri, NULL, 0);
+ if (n == NGX_REGEX_NO_MATCHED) {
continue;
}
- if (len > clcfp[i]->name.len) {
- /* the previous match is longer */
- break;
+ if (n < 0) {
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ ngx_regex_exec_n
+ " failed: %d on \"%V\" using \"%V\"",
+ n, &r->uri, &(*clcfp)->name);
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- found = 1;
+ /* match */
- r->loc_conf = clcfp[i]->loc_conf;
-#if (NGX_PCRE)
- noregex = clcfp[i]->noregex;
-#endif
+ r->loc_conf = (*clcfp)->loc_conf;
+
+ /* look up nested locations */
+
+ return ngx_http_core_find_location(r);
}
}
+ }
+#endif
- if (found) {
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+ return rc;
+}
- if (clcf->locations) {
- rc = ngx_http_core_find_location(r, clcf->locations,
- clcf->regex_start, len);
- if (rc != NGX_OK) {
- return rc;
- }
- }
- }
+/*
+ * NGX_OK - exact match
+ * NGX_DONE - auto redirect
+ * NGX_AGAIN - inclusive match
+ * NGX_DECLINED - no match
+ */
-#if (NGX_PCRE)
+static ngx_int_t
+ngx_http_core_find_static_location(ngx_http_request_t *r,
+ ngx_http_location_tree_node_t *node)
+{
+ u_char *uri;
+ size_t len, n;
+ ngx_int_t rc, rv;
- if (noregex) {
- return NGX_HTTP_LOCATION_NOREGEX;
- }
+ len = r->uri.len;
+ uri = r->uri.data;
- /* regex matches */
+ rv = NGX_DECLINED;
- for (i = regex_start; i < locations->nelts; i++) {
+ for ( ;; ) {
- if (!clcfp[i]->regex) {
- break;
+ if (node == NULL) {
+ return rv;
}
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "find location: ~ \"%V\"", &clcfp[i]->name);
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "test location: \"%*s\"", node->len, node->name);
+
+ n = (len <= (size_t) node->len) ? len : node->len;
- n = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
+ rc = ngx_memcmp(uri, node->name, n);
+
+ if (rc != 0) {
+ node = (rc < 0) ? node->left : node->right;
- if (n == NGX_REGEX_NO_MATCHED) {
continue;
}
- if (n < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n
- " failed: %d on \"%V\" using \"%V\"",
- n, &r->uri, &clcfp[i]->name);
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ if (len > (size_t) node->len) {
+
+ if (node->inclusive) {
+
+ r->loc_conf = node->inclusive->loc_conf;
+ rv = NGX_AGAIN;
+
+ node = node->tree;
+ uri += n;
+ len -= n;
+
+ continue;
+ }
+
+ /* exact only */
+
+ node = node->right;
+
+ continue;
}
- /* match */
+ if (len == (size_t) node->len) {
- r->loc_conf = clcfp[i]->loc_conf;
+ r->loc_conf = (node->exact) ? node->exact->loc_conf:
+ node->inclusive->loc_conf;
+ return NGX_OK;
+ }
- return NGX_HTTP_LOCATION_REGEX;
- }
+ /* len < node->len */
-#endif /* NGX_PCRE */
+ if (len + 1 == (size_t) node->len && node->auto_redirect) {
- return NGX_OK;
+ r->loc_conf = (node->exact) ? node->exact->loc_conf:
+ node->inclusive->loc_conf;
+ rv = NGX_DONE;
+ }
+
+ node = node->left;
+ }
}
@@ -1896,29 +1883,29 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
ngx_int_t
ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
{
- ngx_uint_t i;
ngx_http_core_srv_conf_t *cscf;
ngx_http_core_loc_conf_t **clcfp;
ngx_http_core_main_conf_t *cmcf;
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
- clcfp = cscf->locations.elts;
+ for (clcfp = cscf->named_locations; *clcfp; clcfp++) {
- for (i = cscf->named_start; i < cscf->locations.nelts; i++) {
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "test location: \"%V\"", &(*clcfp)->name);
- if (name->len != clcfp[i]->name.len
- || ngx_strncmp(name->data, clcfp[i]->name.data, name->len) != 0)
+ if (name->len != (*clcfp)->name.len
+ || ngx_strncmp(name->data, (*clcfp)->name.data, name->len) != 0)
{
continue;
}
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "named location: %V \"%V?%V\"", name, &r->uri, &r->args);
+ "using location: %V \"%V?%V\"", name, &r->uri, &r->args);
r->internal = 1;
r->content_handler = NULL;
- r->loc_conf = clcfp[i]->loc_conf;
+ r->loc_conf = (*clcfp)->loc_conf;
ngx_http_update_location_config(r);
@@ -1935,6 +1922,7 @@ ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
"could not find named location \"%V\"", name);
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+
return NGX_DONE;
}
@@ -1983,7 +1971,6 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *http_ctx;
ngx_http_core_srv_conf_t *cscf, **cscfp;
- ngx_http_core_loc_conf_t **clcfp;
ngx_http_core_main_conf_t *cmcf;
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
@@ -2061,37 +2048,6 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
*cf = pcf;
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
- ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts,
- sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
-
- clcfp = cscf->locations.elts;
-
-#if (NGX_PCRE)
-
- cscf->regex_start = cscf->locations.nelts;
-
- for (i = 0; i < cscf->locations.nelts; i++) {
- if (clcfp[i]->regex) {
- cscf->regex_start = i;
- break;
- }
- }
-
-#endif
-
- cscf->named_start = cscf->locations.nelts;
-
- for (i = 0; i < cscf->locations.nelts; i++) {
- if (clcfp[i]->named) {
- cscf->named_start = i;
- break;
- }
- }
-
return rv;
}
@@ -2105,8 +2061,7 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
ngx_conf_t save;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *pctx;
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp;
+ ngx_http_core_loc_conf_t *clcf, *pclcf;
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
if (ctx == NULL) {
@@ -2201,15 +2156,10 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
- if (pclcf->name.len == 0) {
- cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
+ if (pclcf->name.len) {
- clcfp = ngx_array_push(&cscf->locations);
- if (clcfp == NULL) {
- return NGX_CONF_ERROR;
- }
+ /* nested location */
- } else {
#if 0
clcf->prev_location = pclcf;
#endif
@@ -2230,6 +2180,14 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
return NGX_CONF_ERROR;
}
+ if (clcf->named) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "named location \"%V\" must be "
+ "on server level only",
+ &clcf->name);
+ return NGX_CONF_ERROR;
+ }
+
#if (NGX_PCRE)
if (clcf->regex == NULL
&& ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
@@ -2244,22 +2202,11 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
&clcf->name, &pclcf->name);
return NGX_CONF_ERROR;
}
-
- if (pclcf->locations == NULL) {
- pclcf->locations = ngx_array_create(cf->pool, 2, sizeof(void *));
-
- if (pclcf->locations == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- clcfp = ngx_array_push(pclcf->locations);
- if (clcfp == NULL) {
- return NGX_CONF_ERROR;
- }
}
- *clcfp = clcf;
+ if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
save = *cf;
cf->ctx = ctx;
@@ -2269,103 +2216,10 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
*cf = save;
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
- if (clcf->locations == NULL) {
- return rv;
- }
-
- ngx_sort(clcf->locations->elts, (size_t) clcf->locations->nelts,
- sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
-
-#if (NGX_PCRE)
-
- clcf->regex_start = clcf->locations->nelts;
- clcfp = clcf->locations->elts;
-
- for (i = 0; i < clcf->locations->nelts; i++) {
- if (clcfp[i]->regex) {
- clcf->regex_start = i;
- break;
- }
- }
-
-#endif
-
return rv;
}
-static ngx_int_t
-ngx_http_core_cmp_locations(const void *one, const void *two)
-{
- ngx_int_t rc;
- ngx_http_core_loc_conf_t *first, *second;
-
- first = *(ngx_http_core_loc_conf_t **) one;
- second = *(ngx_http_core_loc_conf_t **) two;
-
- if (first->named && !second->named) {
- /* shift named locations to the end */
- return 1;
- }
-
- if (!first->named && second->named) {
- /* shift named locations to the end */
- return -1;
- }
-
- if (first->named && second->named) {
- return ngx_strcmp(first->name.data, second->name.data);
- }
-
- if (first->noname && !second->noname) {
- /* shift no named locations to the end */
- return 1;
- }
-
- if (!first->noname && second->noname) {
- /* shift no named locations to the end */
- return -1;
- }
-
- if (first->noname || second->noname) {
- /* do not sort no named locations */
- return 0;
- }
-
-#if (NGX_PCRE)
-
- if (first->regex && !second->regex) {
- /* shift the regex matches to the end */
- return 1;
- }
-
- if (!first->regex && second->regex) {
- /* shift the regex matches to the end */
- return -1;
- }
-
- if (first->regex || second->regex) {
- /* do not sort the regex matches */
- return 0;
- }
-
-#endif
-
- rc = ngx_strcmp(first->name.data, second->name.data);
-
- if (rc == 0 && second->exact_match) {
- /* an exact match must be before the same inclusive one */
- return 1;
- }
-
- return rc;
-}
-
-
static char *
ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
@@ -2541,12 +2395,6 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
* conf->client_large_buffers.num = 0;
*/
- if (ngx_array_init(&cscf->locations, cf->pool, 4, sizeof(void *))
- == NGX_ERROR)
- {
- return NGX_CONF_ERROR;
- }
-
if (ngx_array_init(&cscf->listen, cf->pool, 4, sizeof(ngx_http_listen_t))
== NGX_ERROR)
{
@@ -2564,7 +2412,6 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
- cscf->optimize_server_names = NGX_CONF_UNSET;
cscf->ignore_invalid_headers = NGX_CONF_UNSET;
cscf->merge_slashes = NGX_CONF_UNSET;
@@ -2640,9 +2487,6 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
- ngx_conf_merge_value(conf->optimize_server_names,
- prev->optimize_server_names, 1);
-
ngx_conf_merge_value(conf->ignore_invalid_headers,
prev->ignore_invalid_headers, 1);
@@ -3345,7 +3189,7 @@ static ngx_http_method_name_t ngx_methods_names[] = {
static char *
ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_core_loc_conf_t *clcf = conf;
+ ngx_http_core_loc_conf_t *pclcf = conf;
char *rv;
void *mconf;
@@ -3355,13 +3199,13 @@ ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *pctx;
ngx_http_method_name_t *name;
- ngx_http_core_loc_conf_t *lcf, **clcfp;
+ ngx_http_core_loc_conf_t *clcf;
- if (clcf->limit_except) {
+ if (pclcf->limit_except) {
return "duplicate";
}
- clcf->limit_except = 0xffffffff;
+ pclcf->limit_except = 0xffffffff;
value = cf->args->elts;
@@ -3369,7 +3213,7 @@ ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
for (name = ngx_methods_names; name->name; name++) {
if (ngx_strcasecmp(value[i].data, name->name) == 0) {
- clcf->limit_except &= name->method;
+ pclcf->limit_except &= name->method;
goto next;
}
}
@@ -3382,8 +3226,8 @@ ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
- if (!(clcf->limit_except & NGX_HTTP_GET)) {
- clcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
+ if (!(pclcf->limit_except & NGX_HTTP_GET)) {
+ pclcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
}
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
@@ -3419,27 +3263,16 @@ ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
- lcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
- clcf->limit_except_loc_conf = ctx->loc_conf;
- lcf->loc_conf = ctx->loc_conf;
- lcf->name = clcf->name;
- lcf->noname = 1;
-
- if (clcf->locations == NULL) {
- clcf->locations = ngx_array_create(cf->pool, 2, sizeof(void *));
- if (clcf->locations == NULL) {
- return NGX_CONF_ERROR;
- }
- }
+ clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
+ pclcf->limit_except_loc_conf = ctx->loc_conf;
+ clcf->loc_conf = ctx->loc_conf;
+ clcf->name = pclcf->name;
+ clcf->noname = 1;
- clcfp = ngx_array_push(clcf->locations);
- if (clcfp == NULL) {
+ if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
return NGX_CONF_ERROR;
}
- *clcfp = lcf;
-
-
save = *cf;
cf->ctx = ctx;
cf->cmd_type = NGX_HTTP_LMT_CONF;
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 9a9f97bdd..85d96b079 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -28,6 +28,10 @@
#define NGX_HTTP_SATISFY_ANY 1
+typedef struct ngx_http_location_tree_node_s ngx_http_location_tree_node_t;
+typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t;
+
+
typedef struct {
unsigned default_server:1;
unsigned bind:1;
@@ -127,37 +131,29 @@ typedef struct {
typedef struct {
- /*
- * array of the ngx_http_core_loc_conf_t *,
- * used in the ngx_http_core_find_location() and in the merge phase
- */
- ngx_array_t locations;
-
- unsigned regex_start:15;
- unsigned named_start:15;
-
/* array of the ngx_http_listen_t, "listen" directive */
- ngx_array_t listen;
+ ngx_array_t listen;
/* array of the ngx_http_server_name_t, "server_name" directive */
- ngx_array_t server_names;
+ ngx_array_t server_names;
/* server ctx */
- ngx_http_conf_ctx_t *ctx;
+ ngx_http_conf_ctx_t *ctx;
+
+ ngx_str_t server_name;
- ngx_str_t server_name;
+ size_t connection_pool_size;
+ size_t request_pool_size;
+ size_t client_header_buffer_size;
- size_t connection_pool_size;
- size_t request_pool_size;
- size_t client_header_buffer_size;
+ ngx_bufs_t large_client_header_buffers;
- ngx_bufs_t large_client_header_buffers;
+ ngx_msec_t client_header_timeout;
- ngx_msec_t client_header_timeout;
+ ngx_flag_t ignore_invalid_headers;
+ ngx_flag_t merge_slashes;
- ngx_flag_t optimize_server_names;
- ngx_flag_t ignore_invalid_headers;
- ngx_flag_t merge_slashes;
+ ngx_http_core_loc_conf_t **named_locations;
} ngx_http_core_srv_conf_t;
@@ -231,8 +227,6 @@ typedef struct {
} ngx_http_err_page_t;
-typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t;
-
struct ngx_http_core_loc_conf_s {
ngx_str_t name; /* location name */
@@ -240,8 +234,6 @@ struct ngx_http_core_loc_conf_s {
ngx_regex_t *regex;
#endif
- unsigned regex_start:15;
-
unsigned noname:1; /* "if () {}" block or limit_except */
unsigned named:1;
@@ -251,14 +243,14 @@ struct ngx_http_core_loc_conf_s {
unsigned auto_redirect:1;
unsigned alias:1;
- /* array of inclusive ngx_http_core_loc_conf_t */
- ngx_array_t *locations;
+ ngx_http_location_tree_node_t *static_locations;
+ ngx_http_core_loc_conf_t **regex_locations;
/* pointer to the modules' loc_conf */
- void **loc_conf ;
+ void **loc_conf;
uint32_t limit_except;
- void **limit_except_loc_conf ;
+ void **limit_except_loc_conf;
ngx_http_handler_pt handler;
@@ -333,12 +325,39 @@ struct ngx_http_core_loc_conf_s {
ngx_uint_t types_hash_max_size;
ngx_uint_t types_hash_bucket_size;
+ ngx_queue_t *locations;
+
#if 0
ngx_http_core_loc_conf_t *prev_location;
#endif
};
+typedef struct {
+ ngx_queue_t queue;
+ ngx_http_core_loc_conf_t *exact;
+ ngx_http_core_loc_conf_t *inclusive;
+ ngx_str_t *name;
+ u_char *file_name;
+ ngx_uint_t line;
+ ngx_queue_t list;
+} ngx_http_location_queue_t;
+
+
+struct ngx_http_location_tree_node_s {
+ ngx_http_location_tree_node_t *left;
+ ngx_http_location_tree_node_t *right;
+ ngx_http_location_tree_node_t *tree;
+
+ ngx_http_core_loc_conf_t *exact;
+ ngx_http_core_loc_conf_t *inclusive;
+
+ u_char auto_redirect;
+ u_char len;
+ u_char name[1];
+};
+
+
void ngx_http_core_run_phases(ngx_http_request_t *r);
ngx_int_t ngx_http_core_generic_phase(ngx_http_request_t *r,
ngx_http_phase_handler_t *ph);
@@ -401,7 +420,7 @@ extern ngx_uint_t ngx_http_max_module;
\
r->allow_ranges = 0; \
if (r->headers_out.accept_ranges) { \
- r->headers_out.accept_ranges->hash = 0 ; \
+ r->headers_out.accept_ranges->hash = 0; \
r->headers_out.accept_ranges = NULL; \
}
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index 2dd5b952b..b7f26f654 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -536,7 +536,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
}
b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len);
- *b->last++ = ':' ; *b->last++ = ' ' ;
+ *b->last++ = ':'; *b->last++ = ' ';
b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len);
*b->last++ = CR; *b->last++ = LF;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 5258ad91f..9ea987fb8 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1836,7 +1836,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
if (!ngx_terminate
&& !ngx_exiting
- && r->keepalive != 0
+ && r->keepalive
&& clcf->keepalive_timeout > 0)
{
ngx_http_set_keepalive(r);
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 306944b61..e1d0eaf4d 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -343,7 +343,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
r->err_status = error;
- if (r->keepalive != 0) {
+ if (r->keepalive) {
switch (error) {
case NGX_HTTP_BAD_REQUEST:
case NGX_HTTP_REQUEST_ENTITY_TOO_LARGE:
@@ -619,7 +619,7 @@ ngx_http_send_special_response(ngx_http_request_t *r,
b->last = tail + len;
out[1].buf = b;
- out[1].next = NULL;;
+ out[1].next = NULL;
if (msie_padding) {
b = ngx_calloc_buf(r->pool);
@@ -633,7 +633,7 @@ ngx_http_send_special_response(ngx_http_request_t *r,
out[1].next = &out[2];
out[2].buf = b;
- out[2].next = NULL;;
+ out[2].next = NULL;
}
if (r == r->main) {
diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c
index 7360539ca..a387e59d1 100644
--- a/src/mail/ngx_mail_ssl_module.c
+++ b/src/mail/ngx_mail_ssl_module.c
@@ -261,7 +261,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
}
ngx_conf_merge_value(conf->builtin_session_cache,
- prev->builtin_session_cache, NGX_SSL_NO_SCACHE);
+ prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
if (conf->shm_zone == NULL) {
conf->shm_zone = prev->shm_zone;
@@ -298,6 +298,11 @@ ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
+ if (ngx_strcmp(value[i].data, "none") == 0) {
+ scf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
+ continue;
+ }
+
if (ngx_strcmp(value[i].data, "builtin") == 0) {
scf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
continue;
diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h
index cd9350992..bf2eae892 100644
--- a/src/os/unix/ngx_linux_config.h
+++ b/src/os/unix/ngx_linux_config.h
@@ -47,6 +47,7 @@
#include <time.h> /* tzset() */
#include <malloc.h> /* memalign() */
+#include <limits.h> /* IOV_MAX */
#include <sys/ioctl.h>
#include <sys/sysctl.h>
#include <crypt.h>
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 73b9d690a..bacba5945 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -1054,70 +1054,74 @@ ngx_channel_handler(ngx_event_t *ev)
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler");
- n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log);
+ for ( ;; ) {
+
+ n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log);
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %i", n);
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %i", n);
- if (n == NGX_ERROR) {
+ if (n == NGX_ERROR) {
- if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
- ngx_del_conn(c, 0);
+ if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
+ ngx_del_conn(c, 0);
+ }
+
+ ngx_close_connection(c);
+ return;
}
- ngx_close_connection(c);
- return;
- }
+ if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
+ if (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) {
+ return;
+ }
+ }
- if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
- if (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) {
+ if (n == NGX_AGAIN) {
return;
}
- }
- if (n == NGX_AGAIN) {
- return;
- }
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
+ "channel command: %d", ch.command);
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
- "channel command: %d", ch.command);
+ switch (ch.command) {
- switch (ch.command) {
+ case NGX_CMD_QUIT:
+ ngx_quit = 1;
+ break;
- case NGX_CMD_QUIT:
- ngx_quit = 1;
- break;
+ case NGX_CMD_TERMINATE:
+ ngx_terminate = 1;
+ break;
- case NGX_CMD_TERMINATE:
- ngx_terminate = 1;
- break;
+ case NGX_CMD_REOPEN:
+ ngx_reopen = 1;
+ break;
- case NGX_CMD_REOPEN:
- ngx_reopen = 1;
- break;
+ case NGX_CMD_OPEN_CHANNEL:
- case NGX_CMD_OPEN_CHANNEL:
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0,
+ "get channel s:%i pid:%P fd:%d",
+ ch.slot, ch.pid, ch.fd);
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0,
- "get channel s:%i pid:%P fd:%d", ch.slot, ch.pid, ch.fd);
+ ngx_processes[ch.slot].pid = ch.pid;
+ ngx_processes[ch.slot].channel[0] = ch.fd;
+ break;
- ngx_processes[ch.slot].pid = ch.pid;
- ngx_processes[ch.slot].channel[0] = ch.fd;
- break;
+ case NGX_CMD_CLOSE_CHANNEL:
- case NGX_CMD_CLOSE_CHANNEL:
+ ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0,
+ "close channel s:%i pid:%P our:%P fd:%d",
+ ch.slot, ch.pid, ngx_processes[ch.slot].pid,
+ ngx_processes[ch.slot].channel[0]);
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0,
- "close channel s:%i pid:%P our:%P fd:%d",
- ch.slot, ch.pid, ngx_processes[ch.slot].pid,
- ngx_processes[ch.slot].channel[0]);
+ if (close(ngx_processes[ch.slot].channel[0]) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
+ "close() channel failed");
+ }
- if (close(ngx_processes[ch.slot].channel[0]) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "close() channel failed");
+ ngx_processes[ch.slot].channel[0] = -1;
+ break;
}
-
- ngx_processes[ch.slot].channel[0] = -1;
- break;
}
}