summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2010-02-01 16:09:21 +0000
committerJonathan Kolb <jon@b0g.us>2010-02-01 16:09:21 +0000
commit433704bd188c90b81b2a212ac8c5298583002b32 (patch)
treec5b1e07f4083f2402b2cca38ff6d5fc1688e9672
parente69ffdaddf10c64c8bf1083d437c54e8fde98795 (diff)
downloadnginx-433704bd188c90b81b2a212ac8c5298583002b32.tar.gz
Changes with nginx 0.7.65 01 Feb 2010v0.7.65
*) Security: now nginx/Windows ignores trailing spaces in URI. Thanks to Dan Crowley, Core Security Technologies. *) Security: now nginx/Windows ignores short files names. Thanks to Dan Crowley, Core Security Technologies. *) Change: now the "009" status code is written to an access log for proxied HTTP/0.9 responses. *) Change: now the default buffer size of the "large_client_header_buffers" directive is 8K. Thanks to Andrew Cholakian. *) Change: now default SSL ciphers are "HIGH:!ADH:!MD5". *) Change: now SSLv2 protocol is disabled by default. *) Change: now $host variable value is always low case. *) Feature: the conf/fastcgi.conf for simple FastCGI configurations. *) Feature: now URI part is not required a "proxy_pass" directive if variables are used. *) Feature: the $ssl_session_id variable. *) Bugfix: if a proxied or FastCGI request was internally redirected to another proxied or FastCGI location, then $upstream_response_time variable may have abnormally large value; the bug had appeared in 0.7.63. *) Bugfix: if the "expires modified" set date in the past, then a negative number was set in the "Cache-Control" response header line. Thanks to Alex Kapranoff. *) Bugfix: nginx closed a connection if a cached response had an empty body. Thanks to Piotr Sikora. *) Bugfix: nginx cached a 304 response if there was the "If-None-Match" header line in a proxied request. Thanks to Tim Dettrick and David Kostal. *) Bugfix: nginx did not treat a comma as separator in the "Cache-Control" backend response header line. *) Bugfix: cached HTTP/0.9 responses were handled incorrectly. *) Bugfix: nginx sent gzipped responses to clients those do not support gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared in 0.8.16. *) Bugfix: nginx always added "Content-Encoding: gzip" response header line in 304 responses sent by ngx_http_gzip_static_module. *) Bugfix: the "!-x" operator did not work. Thanks to Maxim Dounin. *) Bugfix: a segmentation fault might occur in a worker process, if limit_rate was used in HTTPS server. Thanks to Maxim Dounin. *) Bugfix: a segmentation fault might occur in a worker process while $limit_rate logging. Thanks to Maxim Dounin. *) Bugfix: nginx did not support dates in 2038 year on 32-bit platforms; *) Bugfix: nginx/Windows tried to delete a temporary file twice if the file should replace an already existent file. *) Bugfix: nginx/Windows tried to rename a temporary file twice if the file should replace an already existent file. *) Bugfix: nginx/Windows might not create temporary file, a cache file, or "proxy/fastcgi_store"d file if a worker had no enough access rights for top level directories. *) Bugfix: in UTF-8 encoding support by "try_files" directive in nginx/Windows. *) Bugfix: UTF-8 encoding usage in the ngx_http_autoindex_module. Thanks to Maxim Dounin. *) Bugfix: the ngx_http_autoindex_module did not show the trailing slash in links to a directory; the bug had appeared in 0.7.15. *) Bugfix: nginx did not close a log file set by the --error-log-path configuration option; the bug had appeared in 0.7.53. *) Bugfix: "addition_types" directive was incorrectly named "addtion_types". *) Bugfix: invalid request line in $request variable was written in access_log only if error_log was set to "info" or "debug" level.
-rw-r--r--CHANGES100
-rw-r--r--CHANGES.ru108
-rw-r--r--LICENSE2
-rw-r--r--auto/install4
-rw-r--r--auto/lib/openssl/conf8
-rw-r--r--auto/lib/openssl/make6
-rw-r--r--conf/fastcgi.conf24
-rw-r--r--src/core/nginx.c7
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_connection.c6
-rw-r--r--src/core/ngx_file.c33
-rw-r--r--src/core/ngx_open_file_cache.c2
-rw-r--r--src/core/ngx_output_chain.c8
-rw-r--r--src/core/ngx_string.c4
-rw-r--r--src/event/ngx_event_openssl.c46
-rw-r--r--src/event/ngx_event_openssl.h2
-rw-r--r--src/http/modules/ngx_http_addition_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c41
-rw-r--r--src/http/modules/ngx_http_gzip_filter_module.c14
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c3
-rw-r--r--src/http/modules/ngx_http_headers_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_index_module.c5
-rw-r--r--src/http/modules/ngx_http_log_module.c29
-rw-r--r--src/http/modules/ngx_http_not_modified_filter_module.c5
-rw-r--r--src/http/modules/ngx_http_proxy_module.c41
-rw-r--r--src/http/modules/ngx_http_random_index_module.c2
-rw-r--r--src/http/modules/ngx_http_ssl_module.c8
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c31
-rw-r--r--src/http/ngx_http_core_module.c25
-rw-r--r--src/http/ngx_http_file_cache.c6
-rw-r--r--src/http/ngx_http_header_filter_module.c11
-rw-r--r--src/http/ngx_http_parse_time.c28
-rw-r--r--src/http/ngx_http_request.c122
-rw-r--r--src/http/ngx_http_request.h7
-rw-r--r--src/http/ngx_http_request_body.c12
-rw-r--r--src/http/ngx_http_script.c5
-rw-r--r--src/http/ngx_http_upstream.c9
-rw-r--r--src/http/ngx_http_variables.c67
-rw-r--r--src/mail/ngx_mail_ssl_module.c5
-rw-r--r--src/os/unix/ngx_files.c83
-rw-r--r--src/os/unix/ngx_files.h29
-rw-r--r--src/os/unix/ngx_process_cycle.c14
-rw-r--r--src/os/unix/ngx_setproctitle.h2
44 files changed, 729 insertions, 245 deletions
diff --git a/CHANGES b/CHANGES
index 6b67e324c..d292d381f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,104 @@
+Changes with nginx 0.7.65 01 Feb 2010
+
+ *) Security: now nginx/Windows ignores trailing spaces in URI.
+ Thanks to Dan Crowley, Core Security Technologies.
+
+ *) Security: now nginx/Windows ignores short files names.
+ Thanks to Dan Crowley, Core Security Technologies.
+
+ *) Change: now the "009" status code is written to an access log for
+ proxied HTTP/0.9 responses.
+
+ *) Change: now the default buffer size of the
+ "large_client_header_buffers" directive is 8K.
+ Thanks to Andrew Cholakian.
+
+ *) Change: now default SSL ciphers are "HIGH:!ADH:!MD5".
+
+ *) Change: now SSLv2 protocol is disabled by default.
+
+ *) Change: now $host variable value is always low case.
+
+ *) Feature: the conf/fastcgi.conf for simple FastCGI configurations.
+
+ *) Feature: now URI part is not required a "proxy_pass" directive if
+ variables are used.
+
+ *) Feature: the $ssl_session_id variable.
+
+ *) Bugfix: if a proxied or FastCGI request was internally redirected to
+ another proxied or FastCGI location, then $upstream_response_time
+ variable may have abnormally large value; the bug had appeared in
+ 0.7.63.
+
+ *) Bugfix: if the "expires modified" set date in the past, then a
+ negative number was set in the "Cache-Control" response header
+ line.
+ Thanks to Alex Kapranoff.
+
+ *) Bugfix: nginx closed a connection if a cached response had an empty
+ body.
+ Thanks to Piotr Sikora.
+
+ *) Bugfix: nginx cached a 304 response if there was the "If-None-Match"
+ header line in a proxied request.
+ Thanks to Tim Dettrick and David Kostal.
+
+ *) Bugfix: nginx did not treat a comma as separator in the
+ "Cache-Control" backend response header line.
+
+ *) Bugfix: cached HTTP/0.9 responses were handled incorrectly.
+
+ *) Bugfix: nginx sent gzipped responses to clients those do not support
+ gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared
+ in 0.8.16.
+
+ *) Bugfix: nginx always added "Content-Encoding: gzip" response header
+ line in 304 responses sent by ngx_http_gzip_static_module.
+
+ *) Bugfix: the "!-x" operator did not work.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: a segmentation fault might occur in a worker process, if
+ limit_rate was used in HTTPS server.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: a segmentation fault might occur in a worker process while
+ $limit_rate logging.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: nginx did not support dates in 2038 year on 32-bit platforms;
+
+ *) Bugfix: nginx/Windows tried to delete a temporary file twice if the
+ file should replace an already existent file.
+
+ *) Bugfix: nginx/Windows tried to rename a temporary file twice if the
+ file should replace an already existent file.
+
+ *) Bugfix: nginx/Windows might not create temporary file, a cache file,
+ or "proxy/fastcgi_store"d file if a worker had no enough access
+ rights for top level directories.
+
+ *) Bugfix: in UTF-8 encoding support by "try_files" directive in
+ nginx/Windows.
+
+ *) Bugfix: UTF-8 encoding usage in the ngx_http_autoindex_module.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: the ngx_http_autoindex_module did not show the trailing
+ slash in links to a directory; the bug had appeared in 0.7.15.
+
+ *) Bugfix: nginx did not close a log file set by the --error-log-path
+ configuration option; the bug had appeared in 0.7.53.
+
+ *) Bugfix: "addition_types" directive was incorrectly named
+ "addtion_types".
+
+ *) Bugfix: invalid request line in $request variable was written in
+ access_log only if error_log was set to "info" or "debug" level.
+
+
Changes with nginx 0.7.64 16 Nov 2009
*) Security: now SSL/TLS renegotiation is disabled.
diff --git a/CHANGES.ru b/CHANGES.ru
index 3339b8c85..50dff9985 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,110 @@
+Изменения в nginx 0.7.65 01.02.2010
+
+ *) Безопасность: теперь nginx/Windows игнорирует пробелы в конце URI.
+ Спасибо Dan Crowley, Core Security Technologies.
+
+ *) Безопасность: теперь nginx/Windows игнорирует короткие имена файлов.
+ Спасибо Dan Crowley, Core Security Technologies.
+
+ *) Изменение: теперь для проксируемых ответов HTTP/0.9 в лог пишется
+ код ответа "009".
+
+ *) Изменение: теперь по умолчанию размер буфера директивы
+ large_client_header_buffers равен 8K.
+ Спасибо Andrew Cholakian.
+
+ *) Изменение: теперь по умолчанию используются следующие шифры SSL:
+ "HIGH:!ADH:!MD5".
+
+ *) Изменение: теперь протокол SSLv2 по умолчанию запрещён.
+
+ *) Изменение: теперь значение переменной $host всегда в нижнем регистре.
+
+ *) Добавление: файл conf/fastcgi.conf для простых конфигураций FastCGI.
+
+ *) Добавление: теперь при использовании переменных в директиве
+ proxy_pass не требуется задавать URI.
+
+ *) Добавление: переменная $ssl_session_id.
+
+ *) Исправление: если проксированный или FastCGI запрос внутренне
+ перенаправлялся в другой проксированный или FastCGI location, то
+ переменная $upstream_response_time могла иметь ненормально большое
+ значение; ошибка появилась в 0.7.63.
+
+ *) Исправление: если директива "expires modified" выставляла дату в
+ прошлом, то в строке заголовка ответа "Cache-Control" выдавалось
+ отрицательное число.
+ Спасибо Алексею Капранову.
+
+ *) Исправление: nginx закрывал соединение при запросе закэшированного
+ ответа с пустым телом.
+ Спасибо Piotr Sikora.
+
+ *) Исправление: nginx кэшировал 304 ответ, если в заголовке
+ проксируемого запроса была строка "If-None-Match".
+ Спасибо Tim Dettrick и David Kostal.
+
+ *) Исправление: nginx не считал запятую разделителем в строке
+ "Cache-Control" в строке заголовка бэкенда.
+
+ *) Исправление: закэшированные ответы ответов HTTP/0.9 неправильно
+ обрабатывались.
+
+ *) Исправление: nginx передавал сжатые ответы клиентам, не
+ поддерживающим сжатие, при настройках gzip_static on и gzip_vary
+ off; ошибка появилась в 0.8.16.
+
+ *) Исправление: nginx всегда добавлял строку "Content-Encoding: gzip" в
+ заголовок 304-ых ответов модуля ngx_http_gzip_static_module.
+
+ *) Исправление: оператор "!-x" не работал.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: в рабочем процессе мог произойти segmentation fault при
+ использовании limit_rate в HTTPS сервере.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: при записи в лог переменной $limit_rate в рабочем
+ процессе происходил segmentation fault.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: nginx не поддерживал даты в 2038 году на 32-битных
+ платформах;
+
+ *) Исправление: nginx/Windows пытался дважды удалить временный файл при
+ перезаписи уже существующего файла.
+
+ *) Исправление: nginx/Windows пытался дважды переименовать временный
+ файл при перезаписи уже существующего файла.
+
+ *) Исправление: nginx/Windows мог не создать временный файл, файл в
+ кэше или файл с помощью директив proxy/fastcgi_store, если рабочий
+ процесс не имел достаточно прав для работы с каталогами верхнего
+ уровня.
+
+ *) Исправление: в поддержке кодировки UTF-8 директивой try_files в
+ nginx/Windows.
+
+ *) Исправление: ошибки при использовании кодировки UTF-8 в
+ ngx_http_autoindex_module.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: модуль ngx_http_autoindex_module не показывал последний
+ слэш для линков на каталоги; ошибка появилась в 0.7.15.
+
+ *) Исправление: nginx не закрывал лог, заданный параметром конфигурации
+ --error-log-path; ошибка появилась в 0.7.53.
+
+ *) Исправление: директива "addition_types" была неверно названа
+ "addtion_types".
+
+ *) Исправление: неверная строка запроса в переменной $request
+ записывалась в access_log только при использовании error_log на
+ уровне info или debug.
+
+
Изменения в nginx 0.7.64 16.11.2009
*) Безопасность: теперь SSL/TLS renegotiation запрещён.
@@ -88,7 +194,7 @@
Спасибо Максиму Дунину.
*) Исправление: в обработке строк "Last-Modified" и "Accept-Ranges" в
- заголовке ответа бэкенда; ошибка появилась в 0.7.44
+ заголовке ответа бэкенда; ошибка появилась в 0.7.44.
Спасибо Максиму Дунину.
*) Добавление: директива image_filter_transparency.
diff --git a/LICENSE b/LICENSE
index d941ed9fb..77a6c11bb 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2009 Igor Sysoev
+ * Copyright (C) 2002-2010 Igor Sysoev
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/auto/install b/auto/install
index f876891f8..815fcb335 100644
--- a/auto/install
+++ b/auto/install
@@ -101,6 +101,10 @@ install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \
cp conf/fastcgi_params \
'\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params.default'
+ test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf' \
+ || cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX'
+ cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf.default'
+
test -f '\$(DESTDIR)$NGX_CONF_PATH' \
|| cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PATH'
cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PREFIX/nginx.conf.default'
diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf
index 731db80d7..64f2ce02f 100644
--- a/auto/lib/openssl/conf
+++ b/auto/lib/openssl/conf
@@ -25,10 +25,10 @@ if [ $OPENSSL != NONE ]; then
have=NGX_OPENSSL . auto/have
have=NGX_SSL . auto/have
- CORE_INCS="$CORE_INCS $OPENSSL/openssl/include"
- CORE_DEPS="$CORE_DEPS $OPENSSL/openssl/include/openssl/ssl.h"
- CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libssl.a"
- CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libcrypto.a"
+ CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
+ CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
+ CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
+ CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
;;
esac
diff --git a/auto/lib/openssl/make b/auto/lib/openssl/make
index 3c21f436b..d497d88e1 100644
--- a/auto/lib/openssl/make
+++ b/auto/lib/openssl/make
@@ -46,13 +46,13 @@ END
esac
case $OPENSSL in
- /*) ngx_prefix="$OPENSSL/openssl" ;;
- *) ngx_prefix="$PWD/$OPENSSL/openssl" ;;
+ /*) ngx_prefix="$OPENSSL/.openssl" ;;
+ *) ngx_prefix="$PWD/$OPENSSL/.openssl" ;;
esac
cat << END >> $NGX_MAKEFILE
-$OPENSSL/openssl/include/openssl/ssl.h: $NGX_MAKEFILE
+$OPENSSL/.openssl/include/openssl/ssl.h: $NGX_MAKEFILE
cd $OPENSSL \\
&& \$(MAKE) clean \\
&& ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
diff --git a/conf/fastcgi.conf b/conf/fastcgi.conf
new file mode 100644
index 000000000..fab09eb24
--- /dev/null
+++ b/conf/fastcgi.conf
@@ -0,0 +1,24 @@
+
+fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+fastcgi_param QUERY_STRING $query_string;
+fastcgi_param REQUEST_METHOD $request_method;
+fastcgi_param CONTENT_TYPE $content_type;
+fastcgi_param CONTENT_LENGTH $content_length;
+
+fastcgi_param SCRIPT_NAME $fastcgi_script_name;
+fastcgi_param REQUEST_URI $request_uri;
+fastcgi_param DOCUMENT_URI $document_uri;
+fastcgi_param DOCUMENT_ROOT $document_root;
+fastcgi_param SERVER_PROTOCOL $server_protocol;
+
+fastcgi_param GATEWAY_INTERFACE CGI/1.1;
+fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
+
+fastcgi_param REMOTE_ADDR $remote_addr;
+fastcgi_param REMOTE_PORT $remote_port;
+fastcgi_param SERVER_ADDR $server_addr;
+fastcgi_param SERVER_PORT $server_port;
+fastcgi_param SERVER_NAME $server_name;
+
+# PHP only, required if PHP was built with --enable-force-cgi-redirect
+fastcgi_param REDIRECT_STATUS 200;
diff --git a/src/core/nginx.c b/src/core/nginx.c
index a9951d3a2..5df96a438 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -380,6 +380,13 @@ main(int argc, char *const *argv)
}
}
+ if (log->file->fd != ngx_stderr) {
+ if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ ngx_close_file_n " built-in log failed");
+ }
+ }
+
ngx_use_stderr = 0;
if (ngx_process == NGX_PROCESS_SINGLE) {
diff --git a/src/core/nginx.h b/src/core/nginx.h
index bfcf1ee8b..c444f473d 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 7064
-#define NGINX_VERSION "0.7.64"
+#define nginx_version 7065
+#define NGINX_VERSION "0.7.65"
#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 0a7fe847d..01c205877 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -917,12 +917,8 @@ ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
level = NGX_LOG_INFO;
break;
- case NGX_ERROR_ERR:
- level = NGX_LOG_ERR;
- break;
-
default:
- level = NGX_LOG_ALERT;
+ level = NGX_LOG_ERR;
}
} else {
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index 45bb4ca4f..6844849ad 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -183,7 +183,15 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access)
u_char *p, ch;
ngx_err_t err;
- for (p = dir + 1; *p; p++) {
+ err = 0;
+
+#if (NGX_WIN32)
+ p = dir + 3;
+#else
+ p = dir + 1;
+#endif
+
+ for ( /* void */ ; *p; p++) {
ch = *p;
if (ch != '/') {
@@ -194,7 +202,14 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access)
if (ngx_create_dir(dir, access) == NGX_FILE_ERROR) {
err = ngx_errno;
- if (err != NGX_EEXIST) {
+
+ switch (err) {
+ case NGX_EEXIST:
+ err = 0;
+ case NGX_EACCES:
+ break;
+
+ default:
return err;
}
}
@@ -202,7 +217,7 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access)
*p = '/';
}
- return 0;
+ return err;
}
@@ -576,16 +591,10 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
#if (NGX_WIN32)
if (err == NGX_EEXIST) {
- if (ngx_win32_rename_file(src, to, ext->log) == NGX_OK) {
+ err = ngx_win32_rename_file(src, to, ext->log);
- if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) {
- return NGX_OK;
- }
-
- err = ngx_errno;
-
- } else {
- err = 0;
+ if (err == 0) {
+ return NGX_OK;
}
}
diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c
index aa87fd22c..5f6e0b263 100644
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -525,7 +525,7 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
of->fd = fd;
if (of->directio <= ngx_file_size(&fi)) {
- if (ngx_directio_on(fd) == -1) {
+ if (ngx_directio_on(fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
ngx_directio_on_n " \"%s\" failed", name);
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index 6d6d241c1..808addd85 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -510,7 +510,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
#if (NGX_HAVE_ALIGNED_DIRECTIO)
if (ctx->unaligned) {
- if (ngx_directio_off(src->file->fd) == -1) {
+ if (ngx_directio_off(src->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
ngx_directio_off_n " \"%s\" failed",
src->file->name.data);
@@ -528,7 +528,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
err = ngx_errno;
- if (ngx_directio_on(src->file->fd) == -1) {
+ if (ngx_directio_on(src->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
ngx_directio_on_n " \"%s\" failed",
src->file->name.data);
@@ -555,9 +555,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
ngx_read_file_n " read only %z of %O from \"%s\"",
n, size, src->file->name.data);
- if (n == 0) {
- return NGX_ERROR;
- }
+ return NGX_ERROR;
}
dst->last += n;
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 3456baa5c..f8b165731 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1238,10 +1238,8 @@ ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len)
break;
}
- len--;
-
while (src < next) {
- *++dst = *++src;
+ *dst++ = *src++;
len--;
}
}
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index a99552c10..d4b5683d6 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -986,7 +986,7 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
for ( ;; ) {
- while (in && buf->last < buf->end) {
+ while (in && buf->last < buf->end && send < limit) {
if (in->buf->last_buf || in->buf->flush) {
flush = 1;
}
@@ -1013,8 +1013,8 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
ngx_memcpy(buf->last, in->buf->pos, size);
buf->last += size;
-
in->buf->pos += size;
+ send += size;
if (in->buf->pos == in->buf->last) {
in = in->next;
@@ -1039,7 +1039,6 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
}
buf->pos += n;
- send += n;
c->sent += n;
if (n < size) {
@@ -1313,6 +1312,7 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|| n == SSL_R_NO_SHARED_CIPHER /* 193 */
|| n == SSL_R_UNEXPECTED_MESSAGE /* 244 */
|| n == SSL_R_UNEXPECTED_RECORD /* 245 */
+ || n == SSL_R_UNKNOWN_PROTOCOL /* 252 */
|| n == SSL_R_WRONG_VERSION_NUMBER /* 267 */
|| n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */
|| n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */
@@ -1628,7 +1628,7 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
hash = ngx_crc32_short(sess->session_id, sess->session_id_length);
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "http ssl new session: %08XD:%d:%d",
+ "ssl new session: %08XD:%d:%d",
hash, sess->session_id_length, len);
sess_id->node.key = hash;
@@ -1691,7 +1691,7 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
*copy = 0;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "http ssl get session: %08XD:%d", hash, len);
+ "ssl get session: %08XD:%d", hash, len);
shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn),
ngx_ssl_session_cache_index);
@@ -1805,7 +1805,7 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
hash = ngx_crc32_short(id, len);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
- "http ssl remove session: %08XD:%uz", hash, len);
+ "ssl remove session: %08XD:%uz", hash, len);
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
@@ -1969,6 +1969,40 @@ ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
ngx_int_t
+ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+ int len;
+ u_char *p, *buf;
+ SSL_SESSION *sess;
+
+ sess = SSL_get0_session(c->ssl->connection);
+
+ len = i2d_SSL_SESSION(sess, NULL);
+
+ buf = ngx_alloc(len, c->log);
+ if (buf == NULL) {
+ return NGX_ERROR;
+ }
+
+ s->len = 2 * len;
+ s->data = ngx_pnalloc(pool, 2 * len);
+ if (s->data == NULL) {
+ ngx_free(buf);
+ return NGX_ERROR;
+ }
+
+ p = buf;
+ i2d_SSL_SESSION(sess, &p);
+
+ ngx_hex_dump(s->data, buf, len);
+
+ ngx_free(buf);
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
size_t len;
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 21e22ebd8..f3b5a2558 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -119,6 +119,8 @@ ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
+ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool,
+ ngx_str_t *s);
ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool,
diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c
index 4076c5374..c78361c66 100644
--- a/src/http/modules/ngx_http_addition_filter_module.c
+++ b/src/http/modules/ngx_http_addition_filter_module.c
@@ -45,7 +45,7 @@ static ngx_command_t ngx_http_addition_commands[] = {
offsetof(ngx_http_addition_conf_t, after_body),
NULL },
- { ngx_string("addtion_types"),
+ { ngx_string("addition_types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_types_slot,
NGX_HTTP_LOC_CONF_OFFSET,
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 3ce608db1..a4a62e4cc 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -523,6 +523,23 @@ static ngx_str_t ngx_http_fastcgi_hide_headers[] = {
};
+#if (NGX_HTTP_CACHE)
+
+static ngx_str_t ngx_http_fastcgi_hide_cache_headers[] = {
+ ngx_string("Status"),
+ ngx_string("X-Accel-Expires"),
+ ngx_string("X-Accel-Redirect"),
+ ngx_string("X-Accel-Limit-Rate"),
+ ngx_string("X-Accel-Buffering"),
+ ngx_string("X-Accel-Charset"),
+ ngx_string("Set-Cookie"),
+ ngx_string("P3P"),
+ ngx_null_string
+};
+
+#endif
+
+
static ngx_path_init_t ngx_http_fastcgi_temp_path = {
ngx_string(NGX_HTTP_FASTCGI_TEMP_PATH), { 1, 2, 0 }
};
@@ -1899,6 +1916,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
u_char *p;
size_t size;
uintptr_t *code;
+ ngx_str_t *h;
ngx_uint_t i;
ngx_keyval_t *src;
ngx_hash_init_t hash;
@@ -2119,10 +2137,18 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
hash.bucket_size = ngx_align(64, ngx_cacheline_size);
hash.name = "fastcgi_hide_headers_hash";
+#if (NGX_HTTP_CACHE)
+
+ h = conf->upstream.cache ? ngx_http_fastcgi_hide_cache_headers:
+ ngx_http_fastcgi_hide_headers;
+#else
+
+ h = ngx_http_fastcgi_hide_headers;
+
+#endif
+
if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
- &prev->upstream,
- ngx_http_fastcgi_hide_headers,
- &hash)
+ &prev->upstream, h, &hash)
!= NGX_OK)
{
return NGX_CONF_ERROR;
@@ -2433,8 +2459,13 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+
clcf->handler = ngx_http_fastcgi_handler;
+ if (clcf->name.data[clcf->name.len - 1] == '/') {
+ clcf->auto_redirect = 1;
+ }
+
value = cf->args->elts;
url = &value[1];
@@ -2470,10 +2501,6 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index 62b430b71..2c67a36f1 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -246,17 +246,27 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|| (r->headers_out.status != NGX_HTTP_OK
&& r->headers_out.status != NGX_HTTP_FORBIDDEN
&& r->headers_out.status != NGX_HTTP_NOT_FOUND)
- || r->header_only
|| (r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
|| (r->headers_out.content_length_n != -1
&& r->headers_out.content_length_n < conf->min_length)
|| ngx_http_test_content_type(r, &conf->types) == NULL
- || ngx_http_gzip_ok(r) != NGX_OK)
+ || r->header_only)
{
return ngx_http_next_header_filter(r);
}
+ r->gzip_vary = 1;
+
+ if (!r->gzip_tested) {
+ if (ngx_http_gzip_ok(r) != NGX_OK) {
+ return ngx_http_next_header_filter(r);
+ }
+
+ } else if (!r->gzip_ok) {
+ return ngx_http_next_header_filter(r);
+ }
+
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
index 45ab6aaa2..29874a33a 100644
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -144,7 +144,6 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
case NGX_ENOTDIR:
case NGX_ENAMETOOLONG:
- r->gzip = 0;
return NGX_DECLINED;
case NGX_EACCES:
@@ -164,6 +163,8 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
+ r->gzip_vary = 1;
+
if (rc != NGX_OK) {
return NGX_DECLINED;
}
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index 3b5ebd68f..fb6c0050e 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -291,7 +291,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
ngx_http_time(expires->value.data, expires_time);
- if (conf->expires_time < 0) {
+ if (conf->expires_time < 0 || max_age < 0) {
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index d94fc118c..b58aa97c2 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -222,7 +222,10 @@ ngx_http_index_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (of.err == NGX_ENOTDIR || of.err == NGX_EACCES) {
+ if (of.err == NGX_ENOTDIR
+ || of.err == NGX_ENAMETOOLONG
+ || of.err == NGX_EACCES)
+ {
return ngx_http_index_error(r, clcf, path.data, of.err);
}
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index 1ff105821..515203889 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -542,8 +542,25 @@ ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,
static u_char *
ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
{
- return ngx_sprintf(buf, "%ui",
- r->err_status ? r->err_status : r->headers_out.status);
+ ngx_uint_t status;
+
+ if (r->err_status) {
+ status = r->err_status;
+
+ } else if (r->headers_out.status) {
+ status = r->headers_out.status;
+
+ } else if (r->http_version == NGX_HTTP_VERSION_9) {
+ *buf++ = '0';
+ *buf++ = '0';
+ *buf++ = '9';
+ return buf;
+
+ } else {
+ status = 0;
+ }
+
+ return ngx_sprintf(buf, "%ui", status);
}
@@ -837,7 +854,13 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strcmp(value[1].data, "off") == 0) {
llcf->off = 1;
- return NGX_CONF_OK;
+ if (cf->args->nelts == 2) {
+ return NGX_CONF_OK;
+ }
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
}
if (llcf->logs == NULL) {
diff --git a/src/http/modules/ngx_http_not_modified_filter_module.c b/src/http/modules/ngx_http_not_modified_filter_module.c
index 5312b3a22..705815740 100644
--- a/src/http/modules/ngx_http_not_modified_filter_module.c
+++ b/src/http/modules/ngx_http_not_modified_filter_module.c
@@ -88,6 +88,11 @@ ngx_http_not_modified_header_filter(ngx_http_request_t *r)
ngx_http_clear_content_length(r);
ngx_http_clear_accept_ranges(r);
+ if (r->headers_out.content_encoding) {
+ r->headers_out.content_encoding->hash = 0;
+ r->headers_out.content_encoding = NULL;
+ }
+
return ngx_http_next_header_filter(r);
}
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index f4ed8a7a1..19dbd5cfc 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -530,7 +530,7 @@ static ngx_keyval_t ngx_http_proxy_cache_headers[] = {
{ ngx_string("Expect"), ngx_string("") },
{ ngx_string("If-Modified-Since"), ngx_string("") },
{ ngx_string("If-Unmodified-Since"), ngx_string("") },
- { ngx_string("If-Match-None"), ngx_string("") },
+ { ngx_string("If-None-Match"), ngx_string("") },
{ ngx_string("If-Match"), ngx_string("") },
{ ngx_string("Range"), ngx_string("") },
{ ngx_string("If-Range"), ngx_string("") },
@@ -717,17 +717,22 @@ ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
return NGX_ERROR;
}
- if (url.uri.len && url.uri.data[0] == '?') {
- p = ngx_pnalloc(r->pool, url.uri.len + 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
+ if (url.uri.len) {
+ if (url.uri.data[0] == '?') {
+ p = ngx_pnalloc(r->pool, url.uri.len + 1);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ *p++ = '/';
+ ngx_memcpy(p, url.uri.data, url.uri.len);
- *p++ = '/';
- ngx_memcpy(p, url.uri.data, url.uri.len);
+ url.uri.len++;
+ url.uri.data = p - 1;
+ }
- url.uri.len++;
- url.uri.data = p - 1;
+ } else {
+ url.uri = r->unparsed_uri;
}
ctx->vars.key_start = u->schema;
@@ -1218,7 +1223,6 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
if (r->cache) {
r->http_version = NGX_HTTP_VERSION_9;
- u->headers_in.status_n = NGX_HTTP_OK;
return NGX_OK;
}
@@ -1234,7 +1238,6 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
#endif
r->http_version = NGX_HTTP_VERSION_9;
- u->headers_in.status_n = NGX_HTTP_OK;
u->state->status = NGX_HTTP_OK;
return NGX_OK;
@@ -2585,6 +2588,12 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+ clcf->handler = ngx_http_proxy_handler;
+
+ if (clcf->name.data[clcf->name.len - 1] == '/') {
+ clcf->auto_redirect = 1;
+ }
+
value = cf->args->elts;
url = &value[1];
@@ -2613,8 +2622,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
#endif
- clcf->handler = ngx_http_proxy_handler;
-
return NGX_CONF_OK;
}
@@ -2661,8 +2668,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_proxy_set_vars(&u, &plcf->vars);
- clcf->handler = ngx_http_proxy_handler;
-
plcf->location = clcf->name;
if (clcf->named
@@ -2686,10 +2691,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
plcf->url = *url;
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_random_index_module.c b/src/http/modules/ngx_http_random_index_module.c
index bb5544ae6..7b0ec503c 100644
--- a/src/http/modules/ngx_http_random_index_module.c
+++ b/src/http/modules/ngx_http_random_index_module.c
@@ -175,7 +175,7 @@ ngx_http_random_index_handler(ngx_http_request_t *r)
len = ngx_de_namelen(&dir);
- if (!dir.valid_type) {
+ if (dir.type == 0 || ngx_de_is_link(&dir)) {
/* 1 byte for '/' and 1 byte for terminating '\0' */
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index e428c36de..3fe0d4366 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -13,7 +13,7 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
ngx_pool_t *pool, ngx_str_t *s);
-#define NGX_DEFAULT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
+#define NGX_DEFAULT_CIPHERS "HIGH:!ADH:!MD5"
static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
@@ -184,6 +184,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
{ ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
(uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
+ { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
+ (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
{ ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
@@ -344,8 +347,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
prev->prefer_server_ciphers, 0);
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
- (NGX_CONF_BITMASK_SET
- |NGX_SSL_SSLv2|NGX_SSL_SSLv3|NGX_SSL_TLSv1));
+ (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1));
ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 5dab6254e..8108a0fd4 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.64';
+our $VERSION = '0.7.65';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index bdeb31c53..6ba5a4d9e 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -152,12 +152,13 @@ static ngx_http_ssi_command_t ngx_http_perl_ssi_command = {
#endif
-static ngx_str_t ngx_null_name = ngx_null_string;
-
-static HV *nginx_stash;
+static ngx_str_t ngx_null_name = ngx_null_string;
+static HV *nginx_stash;
#if (NGX_HAVE_PERL_MULTIPLICITY)
-static ngx_uint_t ngx_perl_term;
+static ngx_uint_t ngx_perl_term;
+#else
+static PerlInterpreter *perl;
#endif
@@ -456,18 +457,16 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,
static char *
ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
{
- ngx_str_t *m;
- ngx_uint_t i;
+ ngx_str_t *m;
+ ngx_uint_t i;
#if (NGX_HAVE_PERL_MULTIPLICITY)
- ngx_pool_cleanup_t *cln;
+ ngx_pool_cleanup_t *cln;
cln = ngx_pool_cleanup_add(cf->pool, 0);
if (cln == NULL) {
return NGX_CONF_ERROR;
}
-#else
- static PerlInterpreter *perl;
#endif
#ifdef NGX_PERL_MODULES
@@ -1068,19 +1067,21 @@ ngx_http_perl_exit(ngx_cycle_t *cycle)
{
#if (NGX_HAVE_PERL_MULTIPLICITY)
+ /*
+ * the master exit hook is run before global pool cleanup,
+ * therefore just set flag here
+ */
+
ngx_perl_term = 1;
#else
- ngx_http_perl_main_conf_t *pmcf;
-
- pmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_perl_module);
- if (pmcf && nginx_stash) {
+ if (nginx_stash) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "perl term");
- (void) perl_destruct(pmcf->perl);
+ (void) perl_destruct(perl);
- perl_free(pmcf->perl);
+ perl_free(perl);
PERL_SYS_TERM();
}
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 01e4da397..7bb3ad25c 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -773,7 +773,11 @@ ngx_http_handler(ngx_http_request_t *r)
}
r->valid_location = 1;
- r->gzip = 0;
+#if (NGX_HTTP_GZIP)
+ r->gzip_tested = 0;
+ r->gzip_ok = 0;
+ r->gzip_vary = 0;
+#endif
r->write_event_handler = ngx_http_core_run_phases;
ngx_http_core_run_phases(r);
@@ -1199,7 +1203,10 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
{
- if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
+ if (of.err != NGX_ENOENT
+ && of.err != NGX_ENOTDIR
+ && of.err != NGX_ENAMETOOLONG)
+ {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
"%s \"%s\" failed", of.failed, path.data);
}
@@ -1857,15 +1864,7 @@ ngx_http_gzip_ok(ngx_http_request_t *r)
ngx_table_elt_t *e, *d;
ngx_http_core_loc_conf_t *clcf;
- if (r->gzip == 1) {
- return NGX_OK;
- }
-
- if (r->gzip == 2) {
- return NGX_DECLINED;
- }
-
- r->gzip = 2;
+ r->gzip_tested = 1;
if (r != r->main
|| r->headers_in.accept_encoding == NULL
@@ -2000,7 +1999,7 @@ ok:
#endif
- r->gzip = 1;
+ r->gzip_ok = 1;
return NGX_OK;
}
@@ -2862,7 +2861,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
prev->client_header_buffer_size, 1024);
ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
prev->large_client_header_buffers,
- 4, ngx_pagesize);
+ 4, 8192);
if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index a60483d59..c02bc7740 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -311,7 +311,7 @@ ngx_http_file_cache_open(ngx_http_request_t *r)
return n;
}
- if ((size_t) n <= c->header_start) {
+ if ((size_t) n < c->header_start) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
"cache file \"%s\" is too small", c->file.name.data);
return NGX_ERROR;
@@ -718,6 +718,8 @@ ngx_http_cache_send(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ r->header_only = (c->length - c->body_start) == 0;
+
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
@@ -727,7 +729,7 @@ ngx_http_cache_send(ngx_http_request_t *r)
b->file_pos = c->body_start;
b->file_last = c->length;
- b->in_file = (c->length - c->body_start) ? 1: 0;
+ b->in_file = 1;
b->last_buf = (r == r->main) ? 1: 0;
b->last_in_chain = 1;
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index 9044c4040..0f6f1731a 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -399,8 +399,13 @@ ngx_http_header_filter(ngx_http_request_t *r)
}
#if (NGX_HTTP_GZIP)
- if (r->gzip && clcf->gzip_vary) {
- len += sizeof("Vary: Accept-Encoding" CRLF) - 1;
+ if (r->gzip_vary) {
+ if (clcf->gzip_vary) {
+ len += sizeof("Vary: Accept-Encoding" CRLF) - 1;
+
+ } else {
+ r->gzip_vary = 0;
+ }
}
#endif
@@ -559,7 +564,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
}
#if (NGX_HTTP_GZIP)
- if (r->gzip && clcf->gzip_vary) {
+ if (r->gzip_vary) {
b->last = ngx_cpymem(b->last, "Vary: Accept-Encoding" CRLF,
sizeof("Vary: Accept-Encoding" CRLF) - 1);
}
diff --git a/src/http/ngx_http_parse_time.c b/src/http/ngx_http_parse_time.c
index 23fc23854..2e7b40add 100644
--- a/src/http/ngx_http_parse_time.c
+++ b/src/http/ngx_http_parse_time.c
@@ -8,13 +8,15 @@
#include <ngx_core.h>
-static int mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+static ngx_uint_t mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
time_t
ngx_http_parse_time(u_char *value, size_t len)
{
- u_char *p, *end;
- int day, month, year, hour, min, sec;
+ u_char *p, *end;
+ ngx_int_t month;
+ ngx_uint_t day, year, hour, min, sec;
+ uint64_t time;
enum {
no = 0,
rfc822, /* Tue, 10 Nov 2002 23:50:13 */
@@ -229,14 +231,6 @@ ngx_http_parse_time(u_char *value, size_t len)
return NGX_ERROR;
}
-#if (NGX_TIME_T_SIZE <= 4)
-
- if (year >= 2038) {
- return NGX_ERROR;
- }
-
-#endif
-
/*
* shift new year to March 1 and start months from 1 (not 0),
* it is needed for Gauss' formula
@@ -249,7 +243,7 @@ ngx_http_parse_time(u_char *value, size_t len)
/* Gauss' formula for Grigorian days since March 1, 1 BC */
- return (
+ time = (uint64_t) (
/* days in years including leap years since March 1, 1 BC */
365 * year + year / 4 - year / 100 + year / 400
@@ -268,4 +262,14 @@ ngx_http_parse_time(u_char *value, size_t len)
*/
- 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec;
+
+#if (NGX_TIME_T_SIZE <= 4)
+
+ if (time > 0x7fffffff) {
+ return NGX_ERROR;
+ }
+
+#endif
+
+ return (time_t) time;
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 541d305ec..c239b9d34 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -31,7 +31,8 @@ static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
static void ngx_http_process_request(ngx_http_request_t *r);
-static ssize_t ngx_http_validate_host(u_char *host, size_t len);
+static ssize_t ngx_http_validate_host(ngx_http_request_t *r, u_char **host,
+ size_t len, ngx_uint_t alloc);
static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r,
u_char *host, size_t len);
@@ -623,6 +624,7 @@ int
ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
{
size_t len;
+ u_char *host;
const char *servername;
ngx_connection_t *c;
ngx_http_request_t *r;
@@ -647,7 +649,15 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
r = c->data;
- if (ngx_http_find_virtual_server(r, (u_char *) servername, len) != NGX_OK) {
+ host = (u_char *) servername;
+
+ len = ngx_http_validate_host(r, &host, len, 1);
+
+ if (len <= 0) {
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+
+ if (ngx_http_find_virtual_server(r, host, len) != NGX_OK) {
return SSL_TLSEXT_ERR_NOACK;
}
@@ -666,6 +676,7 @@ 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)
{
+ u_char *host;
ssize_t n;
ngx_int_t rc, rv;
ngx_connection_t *c;
@@ -773,9 +784,11 @@ ngx_http_process_request_line(ngx_event_t *rev)
p = r->uri.data + r->uri.len - 1;
- if (*p == '.') {
+ if (*p == '.' || *p == ' ') {
- while (--p > r->uri.data && *p == '.') { /* void */ }
+ while (--p > r->uri.data && (*p == '.' || *p == ' ')) {
+ /* void */
+ }
r->uri.len = p + 1 - r->uri.data;
@@ -797,18 +810,25 @@ ngx_http_process_request_line(ngx_event_t *rev)
"http exten: \"%V\"", &r->exten);
if (r->host_start && r->host_end) {
- n = ngx_http_validate_host(r->host_start,
- r->host_end - r->host_start);
- if (n <= 0) {
+ host = r->host_start;
+ n = ngx_http_validate_host(r, &host,
+ r->host_end - r->host_start, 0);
+
+ if (n == 0) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid host in request line");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return;
}
+ if (n < 0) {
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
r->headers_in.server.len = n;
- r->headers_in.server.data = r->host_start;
+ r->headers_in.server.data = host;
}
if (r->http_version < NGX_HTTP_VERSION_10) {
@@ -932,9 +952,17 @@ ngx_http_process_request_headers(ngx_event_t *rev)
}
if (rv == NGX_DECLINED) {
- len = r->header_in->end - r->header_name_start;
p = r->header_name_start;
+ if (p == NULL) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent too large request");
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+ return;
+ }
+
+ len = r->header_in->end - p;
+
if (len > NGX_MAX_ERROR_STR - 300) {
len = NGX_MAX_ERROR_STR - 300;
p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
@@ -1308,27 +1336,34 @@ static ngx_int_t
ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{
- ssize_t len;
+ u_char *host;
+ ssize_t len;
if (r->headers_in.host == NULL) {
r->headers_in.host = h;
}
- len = ngx_http_validate_host(h->value.data, h->value.len);
+ host = h->value.data;
+ len = ngx_http_validate_host(r, &host, h->value.len, 0);
- if (len <= 0) {
+ if (len == 0) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent invalid host header");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return NGX_ERROR;
}
+ if (len < 0) {
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return NGX_ERROR;
+ }
+
if (r->headers_in.server.len) {
return NGX_OK;
}
r->headers_in.server.len = len;
- r->headers_in.server.data = h->value.data;
+ r->headers_in.server.data = host;
return NGX_OK;
}
@@ -1584,21 +1619,23 @@ ngx_http_process_request(ngx_http_request_t *r)
static ssize_t
-ngx_http_validate_host(u_char *host, size_t len)
+ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
+ ngx_uint_t alloc)
{
- u_char ch;
- size_t i, last;
- ngx_uint_t dot;
+ u_char *h, ch;
+ size_t i, last;
+ ngx_uint_t dot;
last = len;
+ h = *host;
dot = 0;
for (i = 0; i < len; i++) {
- ch = host[i];
+ ch = h[i];
if (ch == '.') {
if (dot) {
- return -1;
+ return 0;
}
dot = 1;
@@ -1613,7 +1650,11 @@ ngx_http_validate_host(u_char *host, size_t len)
}
if (ngx_path_separator(ch) || ch == '\0') {
- return -1;
+ return 0;
+ }
+
+ if (ch >= 'A' || ch < 'Z') {
+ alloc = 1;
}
}
@@ -1621,6 +1662,15 @@ ngx_http_validate_host(u_char *host, size_t len)
last--;
}
+ if (alloc) {
+ *host = ngx_pnalloc(r->pool, last) ;
+ if (*host == NULL) {
+ return -1;
+ }
+
+ ngx_strlow(*host, h, last);
+ }
+
return last;
}
@@ -1628,29 +1678,15 @@ ngx_http_validate_host(u_char *host, size_t len)
static ngx_int_t
ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
{
- u_char *server;
- ngx_uint_t hash;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t *cscf;
- u_char buf[32];
if (r->virtual_names == NULL) {
return NGX_DECLINED;
}
- if (len <= 32) {
- server = buf;
-
- } else {
- server = ngx_pnalloc(r->pool, len);
- if (server == NULL) {
- return NGX_ERROR;
- }
- }
-
- hash = ngx_hash_strlow(server, host, len);
-
- cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, server, len);
+ cscf = ngx_hash_find_combined(&r->virtual_names->names,
+ ngx_hash_key(host, len), host, len);
if (cscf) {
goto found;
@@ -1666,7 +1702,7 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
ngx_http_server_name_t *sn;
name.len = len;
- name.data = server;
+ name.data = host;
ncaptures = 0;
@@ -1682,16 +1718,6 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
if (r->captures == NULL) {
return NGX_ERROR;
}
-
- if (server == buf) {
- server = ngx_pnalloc(r->pool, len);
- if (server == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(server, buf, len);
- name.data = server;
- }
}
n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures);
@@ -1713,7 +1739,7 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
cscf = sn[i].core_srv_conf;
r->ncaptures = ncaptures;
- r->captures_data = server;
+ r->captures_data = host;
goto found;
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 78dabddbd..974020ef8 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -451,7 +451,12 @@ struct ngx_http_request_s {
#if (NGX_HTTP_CACHE)
unsigned cached:1;
#endif
- unsigned gzip:2;
+
+#if (NGX_HTTP_GZIP)
+ unsigned gzip_tested:1;
+ unsigned gzip_ok:1;
+ unsigned gzip_vary:1;
+#endif
unsigned proxy:1;
unsigned bypass_cache:1;
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index 9d47300f5..07f023dd6 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -458,6 +458,7 @@ ngx_http_discard_request_body(ngx_http_request_t *r)
if (size) {
if (r->headers_in.content_length_n > size) {
+ r->header_in->pos += size;
r->headers_in.content_length_n -= size;
} else {
@@ -559,12 +560,16 @@ ngx_http_read_discarded_request_body(ngx_http_request_t *r)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http read discarded body");
- do {
+ for ( ;; ) {
if (r->headers_in.content_length_n == 0) {
r->read_event_handler = ngx_http_block_reading;
return NGX_OK;
}
+ if (!r->connection->read->ready) {
+ return NGX_AGAIN;
+ }
+
size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
NGX_HTTP_DISCARD_BUFFER_SIZE:
(size_t) r->headers_in.content_length_n;
@@ -585,10 +590,7 @@ ngx_http_read_discarded_request_body(ngx_http_request_t *r)
}
r->headers_in.content_length_n -= n;
-
- } while (r->connection->read->ready);
-
- return NGX_AGAIN;
+ }
}
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index ad9d88b40..a92b1995a 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -1417,7 +1417,10 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
{
- if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
+ if (of.err != NGX_ENOENT
+ && of.err != NGX_ENOTDIR
+ && of.err != NGX_ENAMETOOLONG)
+ {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
"%s \"%s\" failed", of.failed, value->data);
}
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index ed86a382c..2deec4819 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -364,6 +364,7 @@ ngx_http_upstream_create(ngx_http_request_t *r)
if (u && u->cleanup) {
ngx_http_upstream_cleanup(r);
*u->cleanup = NULL;
+ u->cleanup = NULL;
}
u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
@@ -711,6 +712,11 @@ ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
r->cached = 1;
c = r->cache;
+ if (c->header_start == c->body_start) {
+ r->http_version = NGX_HTTP_VERSION_9;
+ return ngx_http_cache_send(r);
+ }
+
/* TODO: cache stack */
u->buffer = *c->buf;
@@ -2834,6 +2840,7 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
if (u->cleanup) {
*u->cleanup = NULL;
+ u->cleanup = NULL;
}
if (u->state && u->state->response_sec) {
@@ -3015,7 +3022,7 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
n = 0;
for (p += 8; p < last; p++) {
- if (*p == ';' || *p == ' ') {
+ if (*p == ',' || *p == ';' || *p == ' ') {
break;
}
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index d41b996c6..fc8ca9b02 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -14,6 +14,8 @@ static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static void ngx_http_variable_request_set(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_request_get_size(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
static void ngx_http_variable_request_set_size(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r,
@@ -25,6 +27,8 @@ static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_request_line(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r,
@@ -164,8 +168,7 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
offsetof(ngx_http_request_t, uri),
NGX_HTTP_VAR_NOCACHEABLE, 0 },
- { ngx_string("request"), NULL, ngx_http_variable_request,
- offsetof(ngx_http_request_t, request_line), 0, 0 },
+ { ngx_string("request"), NULL, ngx_http_variable_request_line, 0, 0, 0 },
{ ngx_string("document_root"), NULL,
ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
@@ -237,7 +240,7 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 },
{ ngx_string("limit_rate"), ngx_http_variable_request_set_size,
- ngx_http_variable_request,
+ ngx_http_variable_request_get_size,
offsetof(ngx_http_request_t, limit_rate),
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
@@ -567,6 +570,28 @@ ngx_http_variable_request_set(ngx_http_request_t *r,
}
+static ngx_int_t
+ngx_http_variable_request_get_size(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ size_t *sp;
+
+ sp = (size_t *) ((char *) r + data);
+
+ v->data = ngx_pnalloc(r->pool, NGX_SIZE_T_LEN);
+ if (v->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->len = ngx_sprintf(v->data, "%uz", *sp) - v->data;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ return NGX_OK;
+}
+
+
static void
ngx_http_variable_request_set_size(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
@@ -751,6 +776,42 @@ ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var,
static ngx_int_t
+ngx_http_variable_request_line(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ u_char *p, *s;
+
+ s = r->request_line.data;
+
+ if (s == NULL) {
+ s = r->request_start;
+
+ if (s == NULL) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ for (p = s; p < r->header_in->last; p++) {
+ if (*p == CR || *p == LF) {
+ break;
+ }
+ }
+
+ r->request_line.len = p - s;
+ r->request_line.data = s;
+ }
+
+ v->len = r->request_line.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = s;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
ngx_http_variable_cookie(ngx_http_request_t *r, ngx_http_variable_value_t *v,
uintptr_t data)
{
diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c
index 025df54d7..90f2b1b2b 100644
--- a/src/mail/ngx_mail_ssl_module.c
+++ b/src/mail/ngx_mail_ssl_module.c
@@ -9,7 +9,7 @@
#include <ngx_mail.h>
-#define NGX_DEFAULT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
+#define NGX_DEFAULT_CIPHERS "HIGH:!ADH:!MD5"
static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf);
@@ -198,8 +198,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
prev->prefer_server_ciphers, 0);
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
- (NGX_CONF_BITMASK_SET
- |NGX_SSL_SSLv2|NGX_SSL_SSLv3|NGX_SSL_TLSv1));
+ (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1));
ngx_conf_merge_str_value(conf->certificate, prev->certificate, "");
ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, "");
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index 98ed08229..618d4e214 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -22,7 +22,7 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
if (n == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "pread() failed, file \"%s\"", file->name.data);
+ "pread() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
@@ -30,7 +30,8 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
if (file->sys_offset != offset) {
if (lseek(file->fd, offset, SEEK_SET) == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "lseek() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
@@ -40,7 +41,8 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
n = read(file->fd, buf, size);
if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "read() failed");
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "read() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
@@ -57,57 +59,66 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
ssize_t
ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
{
- ssize_t n;
+ ssize_t n, written;
ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
"write: %d, %p, %uz, %O", file->fd, buf, size, offset);
+ written = 0;
+
#if (NGX_HAVE_PWRITE)
- n = pwrite(file->fd, buf, size, offset);
+ for ( ;; ) {
+ n = pwrite(file->fd, buf, size, offset);
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pwrite() failed");
- return NGX_ERROR;
- }
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "pwrite() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
- if ((size_t) n != size) {
- ngx_log_error(NGX_LOG_CRIT, file->log, 0,
- "pwrite() has written only %z of %uz", n, size);
- return NGX_ERROR;
+ file->offset += n;
+ written += n;
+
+ if ((size_t) n == size) {
+ return written;
+ }
+
+ offset += n;
+ size -= n;
}
#else
if (file->sys_offset != offset) {
if (lseek(file->fd, offset, SEEK_SET) == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "lseek() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
file->sys_offset = offset;
}
- n = write(file->fd, buf, size);
+ for ( ;; ) {
+ n = write(file->fd, buf, size);
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "write() failed");
- return NGX_ERROR;
- }
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "write() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
- if ((size_t) n != size) {
- ngx_log_error(NGX_LOG_CRIT, file->log, 0,
- "write() has written only %z of %uz", n, size);
- return NGX_ERROR;
- }
+ file->offset += n;
+ written += n;
- file->sys_offset += n;
+ if ((size_t) n == size) {
+ return written;
+ }
+ size -= n;
+ }
#endif
-
- file->offset += n;
-
- return n;
}
@@ -191,7 +202,7 @@ ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
if (file->sys_offset != offset) {
if (lseek(file->fd, offset, SEEK_SET) == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "lseek() failed");
+ "lseek() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
@@ -202,13 +213,14 @@ ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
if (n == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "writev() failed");
+ "writev() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
if ((size_t) n != size) {
ngx_log_error(NGX_LOG_CRIT, file->log, 0,
- "writev() has written only %z of %uz", n, size);
+ "writev() \"%s\" has written only %z of %uz",
+ file->name.data, n, size);
return NGX_ERROR;
}
@@ -262,9 +274,8 @@ ngx_read_dir(ngx_dir_t *dir)
if (dir->de) {
#if (NGX_HAVE_D_TYPE)
dir->type = dir->de->d_type;
- dir->valid_type = dir->type ? 1 : 0;
#else
- dir->valid_type = 0;
+ dir->type = 0;
#endif
return NGX_OK;
}
@@ -394,7 +405,7 @@ ngx_directio_on(ngx_fd_t fd)
flags = fcntl(fd, F_GETFL);
if (flags == -1) {
- return -1;
+ return NGX_FILE_ERROR;
}
return fcntl(fd, F_SETFL, flags | O_DIRECT);
@@ -409,7 +420,7 @@ ngx_directio_off(ngx_fd_t fd)
flags = fcntl(fd, F_GETFL);
if (flags == -1) {
- return -1;
+ return NGX_FILE_ERROR;
}
return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 5395acd03..c9144f31b 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -24,7 +24,6 @@ typedef struct {
unsigned type:8;
unsigned valid_info:1;
- unsigned valid_type:1;
} ngx_dir_t;
@@ -142,7 +141,7 @@ ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s);
#define ngx_is_dir(sb) (S_ISDIR((sb)->st_mode))
#define ngx_is_file(sb) (S_ISREG((sb)->st_mode))
#define ngx_is_link(sb) (S_ISLNK((sb)->st_mode))
-#define ngx_is_exec(sb) ((sb)->st_mode & S_IXUSR)
+#define ngx_is_exec(sb) (((sb)->st_mode & S_IXUSR) == S_IXUSR)
#define ngx_file_access(sb) ((sb)->st_mode & 0777)
#define ngx_file_size(sb) (sb)->st_size
#define ngx_file_mtime(sb) (sb)->st_mtime
@@ -200,31 +199,31 @@ ngx_int_t ngx_read_dir(ngx_dir_t *dir);
#else
#define ngx_de_namelen(dir) ngx_strlen((dir)->de->d_name)
#endif
-#define ngx_de_info(name, dir) stat((const char *) name, &(dir)->info)
+
+static ngx_inline ngx_int_t
+ngx_de_info(u_char *name, ngx_dir_t *dir)
+{
+ dir->type = 0;
+ return stat((const char *) name, &dir->info);
+}
+
#define ngx_de_info_n "stat()"
#define ngx_de_link_info(name, dir) lstat((const char *) name, &(dir)->info)
#define ngx_de_link_info_n "lstat()"
#if (NGX_HAVE_D_TYPE)
-#if (NGX_LINUX)
-
-/* XFS on Linux does not set dirent.d_type */
+/*
+ * some file systems (e.g. XFS on Linux and CD9660 on FreeBSD)
+ * do not set dirent.d_type
+ */
#define ngx_de_is_dir(dir) \
(((dir)->type) ? ((dir)->type == DT_DIR) : (S_ISDIR((dir)->info.st_mode)))
#define ngx_de_is_file(dir) \
(((dir)->type) ? ((dir)->type == DT_REG) : (S_ISREG((dir)->info.st_mode)))
#define ngx_de_is_link(dir) \
- (((dir)->type) ? ((dir)->type == DT_LINK) : (S_ISLNK((dir)->info.st_mode)))
-
-#else
-
-#define ngx_de_is_dir(dir) ((dir)->type == DT_DIR)
-#define ngx_de_is_file(dir) ((dir)->type == DT_REG)
-#define ngx_de_is_link(dir) ((dir)->type == DT_LINK)
-
-#endif /* NGX_LINUX */
+ (((dir)->type) ? ((dir)->type == DT_LNK) : (S_ISLNK((dir)->info.st_mode)))
#else
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 69db458f5..e3b054834 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -86,7 +86,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
u_char *p;
size_t size;
ngx_int_t i;
- ngx_uint_t n;
+ ngx_uint_t n, sigio;
sigset_t set;
struct itimerval itv;
ngx_uint_t live;
@@ -139,11 +139,13 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_new_binary = 0;
delay = 0;
+ sigio = 0;
live = 1;
for ( ;; ) {
if (delay) {
if (ngx_sigalrm) {
+ sigio = 0;
delay *= 2;
ngx_sigalrm = 0;
}
@@ -168,7 +170,8 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_time_update(0, 0);
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "wake up");
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+ "wake up, sigio %i", sigio);
if (ngx_reap) {
ngx_reap = 0;
@@ -186,6 +189,13 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
delay = 50;
}
+ if (sigio) {
+ sigio--;
+ continue;
+ }
+
+ sigio = ccf->worker_processes + 2 /* cache processes */;
+
if (delay > 1000) {
ngx_signal_worker_processes(cycle, SIGKILL);
} else {
diff --git a/src/os/unix/ngx_setproctitle.h b/src/os/unix/ngx_setproctitle.h
index 22f7e3ea6..09973e990 100644
--- a/src/os/unix/ngx_setproctitle.h
+++ b/src/os/unix/ngx_setproctitle.h
@@ -13,7 +13,7 @@
/* FreeBSD, NetBSD, OpenBSD */
#define ngx_init_setproctitle(log)
-#define ngx_setproctitle setproctitle
+#define ngx_setproctitle(title) setproctitle("%s", title)
#else /* !NGX_HAVE_SETPROCTITLE */