summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-10-22 11:17:22 +0000
committerJonathan Kolb <jon@b0g.us>2007-10-22 11:17:22 +0000
commit388fd29a9824babe892771b2ca42db491b90bfde (patch)
tree48da2a3018050fa6ac4ba84fc8438aac387201f1
parent7a5fafa72cef419ba594e9357cfbcb47e9663311 (diff)
downloadnginx-388fd29a9824babe892771b2ca42db491b90bfde.tar.gz
Changes with nginx 0.6.15 22 Oct 2007v0.6.15
*) Feature: cygwin compatibility. Thanks to Vladimir Kutakov. *) Feature: the "merge_slashes" directive. *) Feature: the "gzip_vary" directive. *) Feature: the "server_tokens" directive. *) Bugfix: nginx did not unescape URI in the "include" SSI command. *) Bugfix: the segmentation fault was occurred on start or while reconfiguration if variable was used in the "charset" or "source_charset" directives. *) Bugfix: nginx returned the 400 response on requests like "GET http://www.domain.com HTTP/1.0". Thanks to James Oakley. *) Bugfix: if request with request body was redirected using the "error_page" directive, then nginx tried to read the request body again; bug appeared in 0.6.7. *) Bugfix: a segmentation fault occurred in worker process if no server_name was explicitly defined for server processing request; bug appeared in 0.6.7.
-rw-r--r--CHANGES30
-rw-r--r--CHANGES.ru30
-rw-r--r--auto/headers2
-rw-r--r--auto/sources2
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_md5.h40
-rw-r--r--src/core/ngx_sha1.h30
-rw-r--r--src/core/ngx_string.c18
-rw-r--r--src/core/ngx_string.h17
-rw-r--r--src/http/modules/ngx_http_charset_filter_module.c15
-rw-r--r--src/http/modules/ngx_http_gzip_filter_module.c40
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c20
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http.h3
-rw-r--r--src/http/ngx_http_core_module.c28
-rw-r--r--src/http/ngx_http_core_module.h3
-rw-r--r--src/http/ngx_http_header_filter_module.c22
-rw-r--r--src/http/ngx_http_parse.c30
-rw-r--r--src/http/ngx_http_request.c13
-rw-r--r--src/http/ngx_http_request_body.c2
-rw-r--r--src/http/ngx_http_script.c3
-rw-r--r--src/http/ngx_http_special_response.c22
-rw-r--r--src/os/unix/ngx_posix_config.h15
-rw-r--r--src/os/unix/ngx_process_cycle.c21
24 files changed, 344 insertions, 66 deletions
diff --git a/CHANGES b/CHANGES
index 2ae2144e8..64f76a4e4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,34 @@
+Changes with nginx 0.6.15 22 Oct 2007
+
+ *) Feature: cygwin compatibility.
+ Thanks to Vladimir Kutakov.
+
+ *) Feature: the "merge_slashes" directive.
+
+ *) Feature: the "gzip_vary" directive.
+
+ *) Feature: the "server_tokens" directive.
+
+ *) Bugfix: nginx did not unescape URI in the "include" SSI command.
+
+ *) Bugfix: the segmentation fault was occurred on start or while
+ reconfiguration if variable was used in the "charset" or
+ "source_charset" directives.
+
+ *) Bugfix: nginx returned the 400 response on requests like
+ "GET http://www.domain.com HTTP/1.0".
+ Thanks to James Oakley.
+
+ *) Bugfix: if request with request body was redirected using the
+ "error_page" directive, then nginx tried to read the request body
+ again; bug appeared in 0.6.7.
+
+ *) Bugfix: a segmentation fault occurred in worker process if no
+ server_name was explicitly defined for server processing request;
+ bug appeared in 0.6.7.
+
+
Changes with nginx 0.6.14 15 Oct 2007
*) Change: now by default the "echo" SSI command uses entity encoding.
diff --git a/CHANGES.ru b/CHANGES.ru
index 52c755892..132840dd0 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,34 @@
+Изменения в nginx 0.6.15 22.10.2007
+
+ *) Добавление: совместимость с cygwin.
+ Спасибо Владимиру Кутакову.
+
+ *) Добавление: директива merge_slashes.
+
+ *) Добавление: директива gzip_vary.
+
+ *) Добавление: директива server_tokens.
+
+ *) Исправление: nginx не раскодировал URI в команде SSI include.
+
+ *) Исправление: при использовании переменной в директивах charset или
+ source_charset на старте или во время переконфигурации происходил
+ segmentation fault,
+
+ *) Исправление: nginx возвращал ошибку 400 на запросы вида
+ "GET http://www.domain.com HTTP/1.0".
+ Спасибо James Oakley.
+
+ *) Исправление: после перенаправления запроса с телом запроса с помощью
+ директивы error_page nginx пытался снова прочитать тело запроса;
+ ошибка появилась в 0.6.7.
+
+ *) Исправление: в рабочем процессе происходил segmentation fault, если
+ у сервера, обрабатывающему запрос, не был явно определён
+ server_name; ошибка появилась в 0.6.7.
+
+
Изменения в nginx 0.6.14 15.10.2007
*) Изменение: теперь по умолчанию команда SSI echo использует
diff --git a/auto/headers b/auto/headers
index 29eec60ab..d41d95a75 100644
--- a/auto/headers
+++ b/auto/headers
@@ -6,3 +6,5 @@ ngx_include="unistd.h"; . auto/include
ngx_include="inttypes.h"; . auto/include
ngx_include="limits.h"; . auto/include
ngx_include="sys/filio.h"; . auto/include
+ngx_include="crypt.h"; . auto/include
+ngx_include="malloc.h"; . auto/include
diff --git a/auto/sources b/auto/sources
index c5a430322..e28d83d2c 100644
--- a/auto/sources
+++ b/auto/sources
@@ -21,6 +21,8 @@ CORE_DEPS="src/core/nginx.h \
src/core/ngx_file.h \
src/core/ngx_crc.h \
src/core/ngx_crc32.h \
+ src/core/ngx_md5.h \
+ src/core/ngx_sha1.h \
src/core/ngx_rbtree.h \
src/core/ngx_radix_tree.h \
src/core/ngx_slab.h \
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 9eae363ea..7fe55d2dc 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.6.14"
+#define NGINX_VERSION "0.6.15"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_md5.h b/src/core/ngx_md5.h
new file mode 100644
index 000000000..eeba97e86
--- /dev/null
+++ b/src/core/ngx_md5.h
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#ifndef _NGX_MD5_H_INCLUDED_
+#define _NGX_MD5_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#if (NGX_HAVE_OPENSSL_MD5_H)
+#include <openssl/md5.h>
+#else
+#include <md5.h>
+#endif
+
+
+typedef MD5_CTX ngx_md5_t;
+
+
+#if (NGX_OPENSSL_MD5)
+
+#define ngx_md5_init MD5_Init
+#define ngx_md5_update MD5_Update
+#define ngx_md5_final MD5_Final
+
+#else
+
+#define ngx_md5_init MD5Init
+#define ngx_md5_update MD5Update
+#define ngx_md5_final MD5Final
+
+#endif
+
+
+#endif /* _NGX_MD5_H_INCLUDED_ */
diff --git a/src/core/ngx_sha1.h b/src/core/ngx_sha1.h
new file mode 100644
index 000000000..78f52c5ce
--- /dev/null
+++ b/src/core/ngx_sha1.h
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#ifndef _NGX_SHA1_H_INCLUDED_
+#define _NGX_SHA1_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#if (NGX_HAVE_OPENSSL_SHA1_H)
+#include <openssl/sha.h>
+#else
+#include <sha.h>
+#endif
+
+
+typedef SHA_CTX ngx_sha1_t;
+
+
+#define ngx_sha1_init SHA1_Init
+#define ngx_sha1_update SHA1_Update
+#define ngx_sha1_final SHA1_Final
+
+
+#endif /* _NGX_SHA1_H_INCLUDED_ */
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 93b713d81..69f032e2e 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1243,7 +1243,9 @@ ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
switch (state) {
case sw_usual:
- if (ch == '?' && type == NGX_UNESCAPE_URI) {
+ if (ch == '?'
+ && (type & (NGX_UNESCAPE_URI|NGX_UNESCAPE_REDIRECT)))
+ {
*d++ = ch;
goto done;
}
@@ -1286,7 +1288,7 @@ ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
if (ch >= '0' && ch <= '9') {
ch = (u_char) ((decoded << 4) + ch - '0');
- if (type == NGX_UNESCAPE_URI) {
+ if (type & NGX_UNESCAPE_REDIRECT) {
if (ch > '%' && ch < 0x7f) {
*d++ = ch;
break;
@@ -1306,7 +1308,17 @@ ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
if (c >= 'a' && c <= 'f') {
ch = (u_char) ((decoded << 4) + c - 'a' + 10);
- if (type == NGX_UNESCAPE_URI) {
+ if (type & NGX_UNESCAPE_URI) {
+ if (ch == '?') {
+ *d++ = ch;
+ goto done;
+ }
+
+ *d++ = ch;
+ break;
+ }
+
+ if (type & NGX_UNESCAPE_REDIRECT) {
if (ch == '?') {
*d++ = ch;
goto done;
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index f96795134..275c8db5e 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -155,14 +155,15 @@ size_t ngx_utf_length(u_char *p, size_t n);
u_char *ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n);
-#define NGX_ESCAPE_URI 0
-#define NGX_ESCAPE_ARGS 1
-#define NGX_ESCAPE_HTML 2
-#define NGX_ESCAPE_REFRESH 3
-#define NGX_ESCAPE_MEMCACHED 4
-#define NGX_ESCAPE_MAIL_AUTH 5
-
-#define NGX_UNESCAPE_URI 1
+#define NGX_ESCAPE_URI 0
+#define NGX_ESCAPE_ARGS 1
+#define NGX_ESCAPE_HTML 2
+#define NGX_ESCAPE_REFRESH 3
+#define NGX_ESCAPE_MEMCACHED 4
+#define NGX_ESCAPE_MAIL_AUTH 5
+
+#define NGX_UNESCAPE_URI 1
+#define NGX_UNESCAPE_REDIRECT 2
uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size,
ngx_uint_t type);
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index 98919ae2f..f7d9906a8 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -366,8 +366,8 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
no_charset_map:
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "no \"charset_map\" between the charsets "
- "\"%V\" and \"%V\"", from, to);
+ "no \"charset_map\" between the charsets \"%V\" and \"%V\"",
+ from, to);
return ngx_http_next_header_filter(r);
}
@@ -1462,6 +1462,12 @@ ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_OK;
}
+ if (conf->source_charset >= NGX_HTTP_CHARSET_VAR
+ || conf->charset >= NGX_HTTP_CHARSET_VAR)
+ {
+ return NGX_CONF_OK;
+ }
+
mcf = ngx_http_conf_get_module_main_conf(cf,
ngx_http_charset_filter_module);
recode = mcf->recodes.elts;
@@ -1519,9 +1525,8 @@ ngx_http_charset_postconfiguration(ngx_conf_t *cf)
}
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- " no \"charset_map\" between the charsets "
- "\"%V\" and \"%V\"",
- &charset[c].name, &charset[recode[i].dst].name);
+ "no \"charset_map\" between the charsets \"%V\" and \"%V\"",
+ &charset[c].name, &charset[recode[i].dst].name);
return NGX_ERROR;
next:
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index 603daf475..cb5397ad2 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -14,6 +14,7 @@
typedef struct {
ngx_flag_t enable;
ngx_flag_t no_buffer;
+ ngx_flag_t vary;
ngx_array_t *types; /* array of ngx_str_t */
@@ -192,6 +193,13 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = {
offsetof(ngx_http_gzip_conf_t, min_length),
NULL },
+ { ngx_string("gzip_vary"),
+ 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_gzip_conf_t, vary),
+ NULL },
+
ngx_null_command
};
@@ -261,6 +269,7 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
{
ngx_str_t *type;
ngx_uint_t i;
+ ngx_table_elt_t *header;
ngx_http_gzip_ctx_t *ctx;
ngx_http_gzip_conf_t *conf;
@@ -336,16 +345,31 @@ found:
ctx->request = r;
- r->headers_out.content_encoding = ngx_list_push(&r->headers_out.headers);
- if (r->headers_out.content_encoding == NULL) {
+ header = ngx_list_push(&r->headers_out.headers);
+ if (header == NULL) {
return NGX_ERROR;
}
- r->headers_out.content_encoding->hash = 1;
- r->headers_out.content_encoding->key.len = sizeof("Content-Encoding") - 1;
- r->headers_out.content_encoding->key.data = (u_char *) "Content-Encoding";
- r->headers_out.content_encoding->value.len = sizeof("gzip") - 1;
- r->headers_out.content_encoding->value.data = (u_char *) "gzip";
+ header->hash = 1;
+ header->key.len = sizeof("Content-Encoding") - 1;
+ header->key.data = (u_char *) "Content-Encoding";
+ header->value.len = sizeof("gzip") - 1;
+ header->value.data = (u_char *) "gzip";
+
+ r->headers_out.content_encoding = header;
+
+ if (conf->vary) {
+ header = ngx_list_push(&r->headers_out.headers);
+ if (header == NULL) {
+ return NGX_ERROR;
+ }
+
+ header->hash = 1;
+ header->key.len = sizeof("Vary") - 1;
+ header->key.data = (u_char *) "Vary";
+ header->value.len = sizeof("Accept-Encoding") - 1;
+ header->value.data = (u_char *) "Accept-Encoding";
+ }
ctx->length = r->headers_out.content_length_n;
@@ -996,6 +1020,7 @@ ngx_http_gzip_create_conf(ngx_conf_t *cf)
conf->enable = NGX_CONF_UNSET;
conf->no_buffer = NGX_CONF_UNSET;
+ conf->vary = NGX_CONF_UNSET;
conf->http_version = NGX_CONF_UNSET_UINT;
@@ -1031,6 +1056,7 @@ ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child)
MAX_MEM_LEVEL - 1);
ngx_conf_merge_value(conf->min_length, prev->min_length, 20);
ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
+ ngx_conf_merge_value(conf->vary, prev->vary, 0);
if (conf->types == NULL) {
if (prev->types == NULL) {
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 60aed18f8..ae72ee379 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -1858,6 +1858,8 @@ static ngx_int_t
ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
ngx_str_t **params)
{
+ u_char *dst, *src;
+ size_t len;
ngx_int_t rc, key;
ngx_str_t *uri, *file, *wait, *set, *stub, args;
ngx_buf_t *b;
@@ -1927,13 +1929,25 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
return rc;
}
- args.len = 0;
- args.data = NULL;
- flags = 0;
+ dst = uri->data;
+ src = uri->data;
+
+ ngx_unescape_uri(&dst, &src, uri->len, NGX_UNESCAPE_URI);
+
+ len = (uri->data + uri->len) - src;
+ if (len) {
+ dst = ngx_copy(dst, src, len);
+ }
+
+ uri->len = dst - uri->data;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ssi include: \"%V\"", uri);
+ args.len = 0;
+ args.data = NULL;
+ flags = 0;
+
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
return NGX_HTTP_SSI_ERROR;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index a051de19c..04dbb1804 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.6.14';
+our $VERSION = '0.6.15';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 8b04b7a35..93c140f07 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -64,7 +64,8 @@ int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg);
#endif
ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b);
-ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r);
+ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r,
+ ngx_uint_t merge_slashes);
ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
ngx_str_t *args, ngx_uint_t *flags);
ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 462393b63..5ac187344 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -185,6 +185,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
NULL },
+ { ngx_string("merge_slashes"),
+ 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, merge_slashes),
+ NULL },
+
{ ngx_string("location"),
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
ngx_http_core_location,
@@ -427,6 +434,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, recursive_error_pages),
NULL },
+ { ngx_string("server_tokens"),
+ 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_core_loc_conf_t, server_tokens),
+ NULL },
+
{ ngx_string("error_page"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_2MORE,
@@ -681,7 +695,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
&& clcf->client_max_body_size < r->headers_in.content_length_n)
{
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client intented to send too large body: %O bytes",
+ "client intended to send too large body: %O bytes",
r->headers_in.content_length_n);
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
@@ -1598,7 +1612,7 @@ ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "could not find name location \"%V\"", name);
+ "could not find named location \"%V\"", name);
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_DONE;
@@ -2233,6 +2247,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
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;
return cscf;
}
@@ -2292,9 +2307,12 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
+#if (NGX_PCRE)
+ sn->regex = NULL;
+#endif
+ sn->core_srv_conf = conf;
sn->name.len = conf->server_name.len;
sn->name.data = conf->server_name.data;
- sn->core_srv_conf = conf;
}
ngx_conf_merge_size_value(conf->connection_pool_size,
@@ -2322,6 +2340,8 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->ignore_invalid_headers,
prev->ignore_invalid_headers, 1);
+ ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
+
return NGX_CONF_OK;
}
@@ -2377,6 +2397,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf->msie_refresh = NGX_CONF_UNSET;
lcf->log_not_found = NGX_CONF_UNSET;
lcf->recursive_error_pages = NGX_CONF_UNSET;
+ lcf->server_tokens = NGX_CONF_UNSET;
lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
lcf->open_file_cache = NGX_CONF_UNSET_PTR;
@@ -2565,6 +2586,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
ngx_conf_merge_value(conf->recursive_error_pages,
prev->recursive_error_pages, 0);
+ ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
ngx_conf_merge_ptr_value(conf->open_file_cache,
prev->open_file_cache, NULL);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index c56e09bc2..a2f29e267 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -143,6 +143,7 @@ typedef struct {
ngx_flag_t optimize_server_names;
ngx_flag_t ignore_invalid_headers;
+ ngx_flag_t merge_slashes;
} ngx_http_core_srv_conf_t;
@@ -185,7 +186,6 @@ typedef struct {
#if (NGX_PCRE)
ngx_uint_t nregex;
ngx_http_server_name_t *regex;
-
#endif
/* the default server configuration for this address:port */
@@ -285,6 +285,7 @@ struct ngx_http_core_loc_conf_s {
ngx_flag_t msie_refresh; /* msie_refresh */
ngx_flag_t log_not_found; /* log_not_found */
ngx_flag_t recursive_error_pages; /* recursive_error_pages */
+ ngx_flag_t server_tokens; /* server_tokens */
ngx_array_t *error_pages; /* error_page */
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index fedb33c3b..63ecfa135 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -45,7 +45,8 @@ ngx_module_t ngx_http_header_filter_module = {
};
-static char ngx_http_server_string[] = "Server: " NGINX_VER CRLF;
+static char ngx_http_server_string[] = "Server: nginx" CRLF;
+static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
static ngx_str_t ngx_http_status_lines[] = {
@@ -237,8 +238,11 @@ ngx_http_header_filter(ngx_http_request_t *r)
len += ngx_http_status_lines[status].len;
}
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
if (r->headers_out.server == NULL) {
- len += sizeof(ngx_http_server_string) - 1;
+ len += clcf->server_tokens ? sizeof(ngx_http_server_full_string) - 1:
+ sizeof(ngx_http_server_string) - 1;
}
if (r->headers_out.date == NULL) {
@@ -268,8 +272,6 @@ ngx_http_header_filter(ngx_http_request_t *r)
len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1;
}
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
if (r->headers_out.location
&& r->headers_out.location->value.len
&& r->headers_out.location->value.data[0] == '/')
@@ -365,8 +367,16 @@ ngx_http_header_filter(ngx_http_request_t *r)
*b->last++ = CR; *b->last++ = LF;
if (r->headers_out.server == NULL) {
- b->last = ngx_cpymem(b->last, ngx_http_server_string,
- sizeof(ngx_http_server_string) - 1);
+ if (clcf->server_tokens) {
+ p = (u_char *) ngx_http_server_full_string;
+ len = sizeof(ngx_http_server_full_string) - 1;
+
+ } else {
+ p = (u_char *) ngx_http_server_string;
+ len = sizeof(ngx_http_server_string) - 1;
+ }
+
+ b->last = ngx_cpymem(b->last, p, len);
}
if (r->headers_out.date == NULL) {
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 559a5cbd5..256bd9be9 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -335,18 +335,26 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break;
}
+ r->host_end = p;
+
switch (ch) {
case ':':
- r->host_end = p;
state = sw_port;
break;
case '/':
- r->host_end = p;
r->uri_start = p;
state = sw_after_slash_in_uri;
break;
+ case ' ':
+ /*
+ * use single "/" from request line to preserve pointers,
+ * if request line will be copied to large client buffer
+ */
+ r->uri_start = r->schema_end + 1;
+ r->uri_end = r->schema_end + 2;
+ state = sw_http_09;
+ break;
default:
- r->host_end = p;
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
@@ -362,6 +370,16 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->uri_start = p;
state = sw_after_slash_in_uri;
break;
+ case ' ':
+ r->port_end = p;
+ /*
+ * use single "/" from request line to preserve pointers,
+ * if request line will be copied to large client buffer
+ */
+ r->uri_start = r->schema_end + 1;
+ r->uri_end = r->schema_end + 2;
+ state = sw_http_09;
+ break;
default:
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
@@ -890,7 +908,7 @@ header_done:
ngx_int_t
-ngx_http_parse_complex_uri(ngx_http_request_t *r)
+ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
{
u_char c, ch, decoded, *p, *u;
enum {
@@ -998,8 +1016,12 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
switch(ch) {
#if (NGX_WIN32)
case '\\':
+ break;
#endif
case '/':
+ if (merge_slashes) {
+ *u++ = ch;
+ }
break;
case '.':
state = sw_dot;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index c041383b4..4b0190689 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -602,10 +602,11 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
static void
ngx_http_process_request_line(ngx_event_t *rev)
{
- ssize_t n;
- ngx_int_t rc, rv;
- ngx_connection_t *c;
- ngx_http_request_t *r;
+ ssize_t n;
+ ngx_int_t rc, rv;
+ ngx_connection_t *c;
+ ngx_http_request_t *r;
+ ngx_http_core_srv_conf_t *cscf;
c = rev->data;
r = c->data;
@@ -657,7 +658,9 @@ ngx_http_process_request_line(ngx_event_t *rev)
return;
}
- rc = ngx_http_parse_complex_uri(r);
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+ rc = ngx_http_parse_complex_uri(r, cscf->merge_slashes);
if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index dfe5e0fe1..a9583c706 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -442,7 +442,7 @@ ngx_http_discard_request_body(ngx_http_request_t *r)
ngx_del_timer(rev);
}
- if (r->headers_in.content_length_n <= 0) {
+ if (r->headers_in.content_length_n <= 0 || r->request_body) {
return NGX_OK;
}
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 0fa08bc87..96f618abe 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -750,7 +750,8 @@ ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
dst = e->buf.data;
src = e->buf.data;
- ngx_unescape_uri(&dst, &src, e->pos - e->buf.data, NGX_UNESCAPE_URI);
+ ngx_unescape_uri(&dst, &src, e->pos - e->buf.data,
+ NGX_UNESCAPE_REDIRECT);
if (src < e->pos) {
dst = ngx_copy(dst, src, e->pos - src);
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 944bf335e..825703ae9 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -10,13 +10,20 @@
#include <nginx.h>
-static u_char error_tail[] =
+static u_char error_full_tail[] =
"<hr><center>" NGINX_VER "</center>" CRLF
"</body>" CRLF
"</html>" CRLF
;
+static u_char error_tail[] =
+"<hr><center>nginx</center>" CRLF
+"</body>" CRLF
+"</html>" CRLF
+;
+
+
static u_char ngx_http_msie_stub[] =
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
@@ -471,7 +478,8 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
if (!r->zero_body) {
if (error_pages[err].len) {
r->headers_out.content_length_n = error_pages[err].len
- + sizeof(error_tail) - 1;
+ + (clcf->server_tokens ? sizeof(error_full_tail) - 1:
+ sizeof(error_tail) - 1);
if (clcf->msie_padding
&& r->headers_in.msie
@@ -568,8 +576,14 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
}
b->memory = 1;
- b->pos = error_tail;
- b->last = error_tail + sizeof(error_tail) - 1;
+
+ if (clcf->server_tokens) {
+ b->pos = error_full_tail;
+ b->last = error_full_tail + sizeof(error_full_tail) - 1;
+ } else {
+ b->pos = error_tail;
+ b->last = error_tail + sizeof(error_tail) - 1;
+ }
cl->next = ngx_alloc_chain_link(r->pool);
if (cl->next == NULL) {
diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_posix_config.h
index f79657654..49c3c4d6c 100644
--- a/src/os/unix/ngx_posix_config.h
+++ b/src/os/unix/ngx_posix_config.h
@@ -19,6 +19,12 @@
#endif
+#ifdef __CYGWIN__
+#define timezonevar /* timezone is variable */
+#define NGX_BROKEN_SCM_RIGHTS 1
+#endif
+
+
#include <sys/types.h>
#include <sys/time.h>
#if (NGX_HAVE_UNISTD_H)
@@ -64,6 +70,15 @@
#include <limits.h> /* IOV_MAX */
#endif
+#if (NGX_HAVE_MALLOC_H)
+#include <malloc.h> /* memalign() */
+#endif
+
+#if (NGX_HAVE_CRYPT_H)
+#include <crypt.h>
+#endif
+
+
#ifndef IOV_MAX
#define IOV_MAX 16
#endif
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 3d198be8a..631597ef4 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -409,6 +409,12 @@ ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo)
ngx_err_t err;
ngx_channel_t ch;
+#if (NGX_BROKEN_SCM_RIGHTS)
+
+ ch.command = 0;
+
+#else
+
switch (signo) {
case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
@@ -427,6 +433,8 @@ ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo)
ch.command = 0;
}
+#endif
+
ch.fd = -1;
@@ -1035,7 +1043,6 @@ static void
ngx_channel_handler(ngx_event_t *ev)
{
ngx_int_t n;
- ngx_socket_t fd;
ngx_channel_t ch;
ngx_connection_t *c;
@@ -1053,17 +1060,7 @@ ngx_channel_handler(ngx_event_t *ev)
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %i", n);
if (n == NGX_ERROR) {
-
- ngx_free_connection(c);
-
- fd = c->fd;
- c->fd = (ngx_socket_t) -1;
-
- if (close(fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "close() channel failed");
- }
-
+ ngx_close_connection(c);
return;
}