New upstream version 1.20.2
This commit is contained in:
parent
b283023b77
commit
5c35f1696f
97 changed files with 6154 additions and 1066 deletions
261
CHANGES
261
CHANGES
|
|
@ -1,7 +1,264 @@
|
|||
|
||||
Changes with nginx 1.18.0 21 Apr 2020
|
||||
Changes with nginx 1.20.2 16 Nov 2021
|
||||
|
||||
*) 1.18.x stable branch.
|
||||
*) Feature: OpenSSL 3.0 compatibility.
|
||||
|
||||
*) Bugfix: SSL variables might be empty when used in logs; the bug had
|
||||
appeared in 1.19.5.
|
||||
|
||||
*) Bugfix: keepalive connections with gRPC backends might not be closed
|
||||
after receiving a GOAWAY frame.
|
||||
|
||||
*) Bugfix: backend SSL connections in the stream module might hang after
|
||||
an SSL handshake.
|
||||
|
||||
*) Bugfix: SSL connections with gRPC backends might hang if select,
|
||||
poll, or /dev/poll methods were used.
|
||||
|
||||
*) Bugfix: in the $content_length variable when using chunked transfer
|
||||
encoding.
|
||||
|
||||
*) Bugfix: requests might hang when using HTTP/2 and the "aio_write"
|
||||
directive.
|
||||
|
||||
|
||||
Changes with nginx 1.20.1 25 May 2021
|
||||
|
||||
*) Security: 1-byte memory overwrite might occur during DNS server
|
||||
response processing if the "resolver" directive was used, allowing an
|
||||
attacker who is able to forge UDP packets from the DNS server to
|
||||
cause worker process crash or, potentially, arbitrary code execution
|
||||
(CVE-2021-23017).
|
||||
|
||||
|
||||
Changes with nginx 1.20.0 20 Apr 2021
|
||||
|
||||
*) 1.20.x stable branch.
|
||||
|
||||
|
||||
Changes with nginx 1.19.10 13 Apr 2021
|
||||
|
||||
*) Change: the default value of the "keepalive_requests" directive was
|
||||
changed to 1000.
|
||||
|
||||
*) Feature: the "keepalive_time" directive.
|
||||
|
||||
*) Feature: the $connection_time variable.
|
||||
|
||||
*) Workaround: "gzip filter failed to use preallocated memory" alerts
|
||||
appeared in logs when using zlib-ng.
|
||||
|
||||
|
||||
Changes with nginx 1.19.9 30 Mar 2021
|
||||
|
||||
*) Bugfix: nginx could not be built with the mail proxy module, but
|
||||
without the ngx_mail_ssl_module; the bug had appeared in 1.19.8.
|
||||
|
||||
*) Bugfix: "upstream sent response body larger than indicated content
|
||||
length" errors might occur when working with gRPC backends; the bug
|
||||
had appeared in 1.19.1.
|
||||
|
||||
*) Bugfix: nginx might not close a connection till keepalive timeout
|
||||
expiration if the connection was closed by the client while
|
||||
discarding the request body.
|
||||
|
||||
*) Bugfix: nginx might not detect that a connection was already closed
|
||||
by the client when waiting for auth_delay or limit_req delay, or when
|
||||
working with backends.
|
||||
|
||||
*) Bugfix: in the eventport method.
|
||||
|
||||
|
||||
Changes with nginx 1.19.8 09 Mar 2021
|
||||
|
||||
*) Feature: flags in the "proxy_cookie_flags" directive can now contain
|
||||
variables.
|
||||
|
||||
*) Feature: the "proxy_protocol" parameter of the "listen" directive,
|
||||
the "proxy_protocol" and "set_real_ip_from" directives in mail proxy.
|
||||
|
||||
*) Bugfix: HTTP/2 connections were immediately closed when using
|
||||
"keepalive_timeout 0"; the bug had appeared in 1.19.7.
|
||||
|
||||
*) Bugfix: some errors were logged as unknown if nginx was built with
|
||||
glibc 2.32.
|
||||
|
||||
*) Bugfix: in the eventport method.
|
||||
|
||||
|
||||
Changes with nginx 1.19.7 16 Feb 2021
|
||||
|
||||
*) Change: connections handling in HTTP/2 has been changed to better
|
||||
match HTTP/1.x; the "http2_recv_timeout", "http2_idle_timeout", and
|
||||
"http2_max_requests" directives have been removed, the
|
||||
"keepalive_timeout" and "keepalive_requests" directives should be
|
||||
used instead.
|
||||
|
||||
*) Change: the "http2_max_field_size" and "http2_max_header_size"
|
||||
directives have been removed, the "large_client_header_buffers"
|
||||
directive should be used instead.
|
||||
|
||||
*) Feature: now, if free worker connections are exhausted, nginx starts
|
||||
closing not only keepalive connections, but also connections in
|
||||
lingering close.
|
||||
|
||||
*) Bugfix: "zero size buf in output" alerts might appear in logs if an
|
||||
upstream server returned an incorrect response during unbuffered
|
||||
proxying; the bug had appeared in 1.19.1.
|
||||
|
||||
*) Bugfix: HEAD requests were handled incorrectly if the "return"
|
||||
directive was used with the "image_filter" or "xslt_stylesheet"
|
||||
directives.
|
||||
|
||||
*) Bugfix: in the "add_trailer" directive.
|
||||
|
||||
|
||||
Changes with nginx 1.19.6 15 Dec 2020
|
||||
|
||||
*) Bugfix: "no live upstreams" errors if a "server" inside "upstream"
|
||||
block was marked as "down".
|
||||
|
||||
*) Bugfix: a segmentation fault might occur in a worker process if HTTPS
|
||||
was used; the bug had appeared in 1.19.5.
|
||||
|
||||
*) Bugfix: nginx returned the 400 response on requests like
|
||||
"GET http://example.com?args HTTP/1.0".
|
||||
|
||||
*) Bugfix: in the ngx_http_flv_module and ngx_http_mp4_module.
|
||||
Thanks to Chris Newton.
|
||||
|
||||
|
||||
Changes with nginx 1.19.5 24 Nov 2020
|
||||
|
||||
*) Feature: the -e switch.
|
||||
|
||||
*) Feature: the same source files can now be specified in different
|
||||
modules while building addon modules.
|
||||
|
||||
*) Bugfix: SSL shutdown did not work when lingering close was used.
|
||||
|
||||
*) Bugfix: "upstream sent frame for closed stream" errors might occur
|
||||
when working with gRPC backends.
|
||||
|
||||
*) Bugfix: in request body filters internal API.
|
||||
|
||||
|
||||
Changes with nginx 1.19.4 27 Oct 2020
|
||||
|
||||
*) Feature: the "ssl_conf_command", "proxy_ssl_conf_command",
|
||||
"grpc_ssl_conf_command", and "uwsgi_ssl_conf_command" directives.
|
||||
|
||||
*) Feature: the "ssl_reject_handshake" directive.
|
||||
|
||||
*) Feature: the "proxy_smtp_auth" directive in mail proxy.
|
||||
|
||||
|
||||
Changes with nginx 1.19.3 29 Sep 2020
|
||||
|
||||
*) Feature: the ngx_stream_set_module.
|
||||
|
||||
*) Feature: the "proxy_cookie_flags" directive.
|
||||
|
||||
*) Feature: the "userid_flags" directive.
|
||||
|
||||
*) Bugfix: the "stale-if-error" cache control extension was erroneously
|
||||
applied if backend returned a response with status code 500, 502,
|
||||
503, 504, 403, 404, or 429.
|
||||
|
||||
*) Bugfix: "[crit] cache file ... has too long header" messages might
|
||||
appear in logs if caching was used and the backend returned responses
|
||||
with the "Vary" header line.
|
||||
|
||||
*) Workaround: "[crit] SSL_write() failed" messages might appear in logs
|
||||
when using OpenSSL 1.1.1.
|
||||
|
||||
*) Bugfix: "SSL_shutdown() failed (SSL: ... bad write retry)" messages
|
||||
might appear in logs; the bug had appeared in 1.19.2.
|
||||
|
||||
*) Bugfix: a segmentation fault might occur in a worker process when
|
||||
using HTTP/2 if errors with code 400 were redirected to a proxied
|
||||
location using the "error_page" directive.
|
||||
|
||||
*) Bugfix: socket leak when using HTTP/2 and subrequests in the njs
|
||||
module.
|
||||
|
||||
|
||||
Changes with nginx 1.19.2 11 Aug 2020
|
||||
|
||||
*) Change: now nginx starts closing keepalive connections before all
|
||||
free worker connections are exhausted, and logs a warning about this
|
||||
to the error log.
|
||||
|
||||
*) Change: optimization of client request body reading when using
|
||||
chunked transfer encoding.
|
||||
|
||||
*) Bugfix: memory leak if the "ssl_ocsp" directive was used.
|
||||
|
||||
*) Bugfix: "zero size buf in output" alerts might appear in logs if a
|
||||
FastCGI server returned an incorrect response; the bug had appeared
|
||||
in 1.19.1.
|
||||
|
||||
*) Bugfix: a segmentation fault might occur in a worker process if
|
||||
different large_client_header_buffers sizes were used in different
|
||||
virtual servers.
|
||||
|
||||
*) Bugfix: SSL shutdown might not work.
|
||||
|
||||
*) Bugfix: "SSL_shutdown() failed (SSL: ... bad write retry)" messages
|
||||
might appear in logs.
|
||||
|
||||
*) Bugfix: in the ngx_http_slice_module.
|
||||
|
||||
*) Bugfix: in the ngx_http_xslt_filter_module.
|
||||
|
||||
|
||||
Changes with nginx 1.19.1 07 Jul 2020
|
||||
|
||||
*) Change: the "lingering_close", "lingering_time", and
|
||||
"lingering_timeout" directives now work when using HTTP/2.
|
||||
|
||||
*) Change: now extra data sent by a backend are always discarded.
|
||||
|
||||
*) Change: now after receiving a too short response from a FastCGI
|
||||
server nginx tries to send the available part of the response to the
|
||||
client, and then closes the client connection.
|
||||
|
||||
*) Change: now after receiving a response with incorrect length from a
|
||||
gRPC backend nginx stops response processing with an error.
|
||||
|
||||
*) Feature: the "min_free" parameter of the "proxy_cache_path",
|
||||
"fastcgi_cache_path", "scgi_cache_path", and "uwsgi_cache_path"
|
||||
directives.
|
||||
Thanks to Adam Bambuch.
|
||||
|
||||
*) Bugfix: nginx did not delete unix domain listen sockets during
|
||||
graceful shutdown on the SIGQUIT signal.
|
||||
|
||||
*) Bugfix: zero length UDP datagrams were not proxied.
|
||||
|
||||
*) Bugfix: proxying to uwsgi backends using SSL might not work.
|
||||
Thanks to Guanzhong Chen.
|
||||
|
||||
*) Bugfix: in error handling when using the "ssl_ocsp" directive.
|
||||
|
||||
*) Bugfix: on XFS and NFS file systems disk cache size might be
|
||||
calculated incorrectly.
|
||||
|
||||
*) Bugfix: "negative size buf in writer" alerts might appear in logs if
|
||||
a memcached server returned a malformed response.
|
||||
|
||||
|
||||
Changes with nginx 1.19.0 26 May 2020
|
||||
|
||||
*) Feature: client certificate validation with OCSP.
|
||||
|
||||
*) Bugfix: "upstream sent frame for closed stream" errors might occur
|
||||
when working with gRPC backends.
|
||||
|
||||
*) Bugfix: OCSP stapling might not work if the "resolver" directive was
|
||||
not specified.
|
||||
|
||||
*) Bugfix: connections with incorrect HTTP/2 preface were not logged.
|
||||
|
||||
|
||||
Changes with nginx 1.17.10 14 Apr 2020
|
||||
|
|
|
|||
263
CHANGES.ru
263
CHANGES.ru
|
|
@ -1,7 +1,266 @@
|
|||
|
||||
Изменения в nginx 1.18.0 21.04.2020
|
||||
Изменения в nginx 1.20.2 16.11.2021
|
||||
|
||||
*) Стабильная ветка 1.18.x.
|
||||
*) Добавление: совместимость с OpenSSL 3.0.
|
||||
|
||||
*) Исправление: SSL-переменные могли быть пустыми при записи в лог;
|
||||
ошибка появилась в 1.19.5.
|
||||
|
||||
*) Исправление: keepalive-соединения с gRPC-бэкендами могли не
|
||||
закрываться после получения GOAWAY-фрейма.
|
||||
|
||||
*) Исправление: SSL-соединения к бэкендам в модуле stream могли зависать
|
||||
после SSL handshake.
|
||||
|
||||
*) Исправление: SSL-соединения с gRPC-бэкендами могли зависать, если
|
||||
использовались методы select, poll или /dev/poll.
|
||||
|
||||
*) Исправление: в переменной $content_length при использовании chunked
|
||||
transfer encoding.
|
||||
|
||||
*) Исправление: при использовании HTTP/2 и директивы aio_write запросы
|
||||
могли зависать.
|
||||
|
||||
|
||||
Изменения в nginx 1.20.1 25.05.2021
|
||||
|
||||
*) Безопасность: при использовании директивы resolver во время обработки
|
||||
ответа DNS-сервера могла происходить перезапись одного байта памяти,
|
||||
что позволяло атакующему, имеющему возможность подделывать UDP-пакеты
|
||||
от DNS-сервера, вызвать падение рабочего процесса или, потенциально,
|
||||
выполнение произвольного кода (CVE-2021-23017).
|
||||
|
||||
|
||||
Изменения в nginx 1.20.0 20.04.2021
|
||||
|
||||
*) Стабильная ветка 1.20.x.
|
||||
|
||||
|
||||
Изменения в nginx 1.19.10 13.04.2021
|
||||
|
||||
*) Изменение: в директиве keepalive_requests значение по умолчанию
|
||||
изменено на 1000.
|
||||
|
||||
*) Добавление: директива keepalive_time.
|
||||
|
||||
*) Добавление: переменная $connection_time.
|
||||
|
||||
*) Изменение: при использовании zlib-ng в логах появлялись сообщения
|
||||
"gzip filter failed to use preallocated memory".
|
||||
|
||||
|
||||
Изменения в nginx 1.19.9 30.03.2021
|
||||
|
||||
*) Исправление: nginx не собирался с почтовым прокси-сервером, но без
|
||||
модуля ngx_mail_ssl_module; ошибка появилась в 1.19.8.
|
||||
|
||||
*) Исправление: при работе с gRPC-бэкендами могли возникать ошибки
|
||||
"upstream sent response body larger than indicated content length";
|
||||
ошибка появилась в 1.19.1.
|
||||
|
||||
*) Исправление: если клиент закрывал соединение в момент отбрасывания
|
||||
тела запроса, nginx мог не закрыть соединение до истечения
|
||||
keepalive-таймаута.
|
||||
|
||||
*) Исправление: при ожидании задержки limit_req или auth_delay, а также
|
||||
при работе с бэкендами nginx мог не обнаружить, что соединение уже
|
||||
закрыто клиентом.
|
||||
|
||||
*) Исправление: в методе обработки соединений eventport.
|
||||
|
||||
|
||||
Изменения в nginx 1.19.8 09.03.2021
|
||||
|
||||
*) Добавление: в директиве proxy_cookie_flags теперь флаги можно
|
||||
задавать с помощью переменных.
|
||||
|
||||
*) Добавление: параметр proxy_protocol в директиве listen, директивы
|
||||
proxy_protocol и set_real_ip_from в почтовом прокси-сервере.
|
||||
|
||||
*) Исправление: HTTP/2-соединения сразу закрывались при использовании
|
||||
"keepalive_timeout 0"; ошибка появилась в 1.19.7.
|
||||
|
||||
*) Исправление: некоторые ошибки логгировались как неизвестные, если
|
||||
nginx был собран с glibc 2.32.
|
||||
|
||||
*) Исправление: в методе обработки соединений eventport.
|
||||
|
||||
|
||||
Изменения в nginx 1.19.7 16.02.2021
|
||||
|
||||
*) Изменение: обработка соединений в HTTP/2 была изменена и теперь более
|
||||
соответствует HTTP/1.x; директивы http2_recv_timeout,
|
||||
http2_idle_timeout и http2_max_requests упразднены, вместо них
|
||||
следует использовать директивы keepalive_timeout и
|
||||
keepalive_requests.
|
||||
|
||||
*) Изменение: директивы http2_max_field_size и http2_max_header_size
|
||||
упразднены, вместо них следует использовать директиву
|
||||
large_client_header_buffers.
|
||||
|
||||
*) Добавление: теперь при исчерпании свободных соединений nginx
|
||||
закрывает не только keepalive-соединения, но и соединения в lingering
|
||||
close.
|
||||
|
||||
*) Исправление: в логах могли появляться сообщения "zero size buf in
|
||||
output", если бэкенд возвращал некорректный ответ при
|
||||
небуферизированном проксировании; ошибка появилась в 1.19.1.
|
||||
|
||||
*) Исправление: при использовании директивы return вместе с image_filter
|
||||
или xslt_stylesheet HEAD-запросы обрабатывались некорректно.
|
||||
|
||||
*) Исправление: в директиве add_trailer.
|
||||
|
||||
|
||||
Изменения в nginx 1.19.6 15.12.2020
|
||||
|
||||
*) Исправление: ошибки "no live upstreams", если server в блоке upstream
|
||||
был помечен как down.
|
||||
|
||||
*) Исправление: при использовании HTTPS в рабочем процессе мог произойти
|
||||
segmentation fault; ошибка появилась в 1.19.5.
|
||||
|
||||
*) Исправление: nginx возвращал ошибку 400 на запросы вида
|
||||
"GET http://example.com?args HTTP/1.0".
|
||||
|
||||
*) Исправление: в модулях ngx_http_flv_module и ngx_http_mp4_module.
|
||||
Спасибо Chris Newton.
|
||||
|
||||
|
||||
Изменения в nginx 1.19.5 24.11.2020
|
||||
|
||||
*) Добавление: ключ -e.
|
||||
|
||||
*) Добавление: при сборке дополнительных модулей теперь можно указывать
|
||||
одни и те же исходные файлы в разных модулях.
|
||||
|
||||
*) Исправление: SSL shutdown не работал при закрытии соединений с
|
||||
ожиданием дополнительных данных (lingering close).
|
||||
|
||||
*) Исправление: при работе с gRPC-бэкендами могли возникать ошибки
|
||||
"upstream sent frame for closed stream".
|
||||
|
||||
*) Исправление: во внутреннем API для обработки тела запроса.
|
||||
|
||||
|
||||
Изменения в nginx 1.19.4 27.10.2020
|
||||
|
||||
*) Добавление: директивы ssl_conf_command, proxy_ssl_conf_command,
|
||||
grpc_ssl_conf_command и uwsgi_ssl_conf_command.
|
||||
|
||||
*) Добавление: директива ssl_reject_handshake.
|
||||
|
||||
*) Добавление: директива proxy_smtp_auth в почтовом прокси-сервере.
|
||||
|
||||
|
||||
Изменения в nginx 1.19.3 29.09.2020
|
||||
|
||||
*) Добавление: модуль ngx_stream_set_module.
|
||||
|
||||
*) Добавление: директива proxy_cookie_flags.
|
||||
|
||||
*) Добавление: директива userid_flags.
|
||||
|
||||
*) Исправление: расширение управления кэшированием stale-if-error
|
||||
ошибочно применялось, если бэкенд возвращал ответ с кодом 500, 502,
|
||||
503, 504, 403, 404 или 429.
|
||||
|
||||
*) Исправление: если использовалось кэширование и бэкенд возвращал
|
||||
ответы с строкой заголовка Vary, в логах могли появляться сообщения
|
||||
"[crit] cache file ... has too long header".
|
||||
|
||||
*) Изменение: при использовании OpenSSL 1.1.1 в логах могли появляться
|
||||
сообщения "[crit] SSL_write() failed".
|
||||
|
||||
*) Исправление: в логах могли появляться сообщения "SSL_shutdown()
|
||||
failed (SSL: ... bad write retry)"; ошибка появилась в 1.19.2.
|
||||
|
||||
*) Исправление: при использовании HTTP/2 в рабочем процессе мог
|
||||
произойти segmentation fault, если ошибки с кодом 400 с помощью
|
||||
директивы error_page перенаправлялись в проксируемый location.
|
||||
|
||||
*) Исправление: утечки сокетов при использовании HTTP/2 и подзапросов в
|
||||
модуле njs.
|
||||
|
||||
|
||||
Изменения в nginx 1.19.2 11.08.2020
|
||||
|
||||
*) Изменение: теперь nginx начинает закрывать keepalive-соединения, не
|
||||
дожидаясь исчерпания всех свободных соединений, а также пишет об этом
|
||||
предупреждение в лог ошибок.
|
||||
|
||||
*) Изменение: оптимизация чтения тела запроса при использовании chunked
|
||||
transfer encoding.
|
||||
|
||||
*) Исправление: утечки памяти при использовании директивы ssl_ocsp.
|
||||
|
||||
*) Исправление: в логах могли появляться сообщения "zero size buf in
|
||||
output", если FastCGI-сервер возвращал некорректный ответ; ошибка
|
||||
появилась в 1.19.1.
|
||||
|
||||
*) Исправление: в рабочем процессе мог произойти segmentation fault,
|
||||
если размеры large_client_header_buffers отличались в разных
|
||||
виртуальных серверах.
|
||||
|
||||
*) Исправление: SSL shutdown мог не работать.
|
||||
|
||||
*) Исправление: в логах могли появляться сообщения "SSL_shutdown()
|
||||
failed (SSL: ... bad write retry)".
|
||||
|
||||
*) Исправление: в модуле ngx_http_slice_module.
|
||||
|
||||
*) Исправление: в модуле ngx_http_xslt_filter_module.
|
||||
|
||||
|
||||
Изменения в nginx 1.19.1 07.07.2020
|
||||
|
||||
*) Изменение: директивы lingering_close, lingering_time и
|
||||
lingering_timeout теперь работают при использовании HTTP/2.
|
||||
|
||||
*) Изменение: теперь лишние данные, присланные бэкендом, всегда
|
||||
отбрасываются.
|
||||
|
||||
*) Изменение: теперь при получении слишком короткого ответа от
|
||||
FastCGI-сервера nginx пытается отправить клиенту доступную часть
|
||||
ответа, после чего закрывает соединение с клиентом.
|
||||
|
||||
*) Изменение: теперь при получении ответа некорректной длины от
|
||||
gRPC-бэкенда nginx прекращает обработку ответа с ошибкой.
|
||||
|
||||
*) Добавление: параметр min_free в директивах proxy_cache_path,
|
||||
fastcgi_cache_path, scgi_cache_path и uwsgi_cache_path.
|
||||
Спасибо Adam Bambuch.
|
||||
|
||||
*) Исправление: nginx не удалял unix domain listen-сокеты при плавном
|
||||
завершении по сигналу SIGQUIT.
|
||||
|
||||
*) Исправление: UDP-пакеты нулевого размера не проксировались.
|
||||
|
||||
*) Исправление: проксирование на uwsgi-бэкенды с использованием SSL
|
||||
могло не работать.
|
||||
Спасибо Guanzhong Chen.
|
||||
|
||||
*) Исправление: в обработке ошибок при использовании директивы ssl_ocsp.
|
||||
|
||||
*) Исправление: при использовании файловых систем XFS и NFS размер кэша
|
||||
на диске мог считаться некорректно.
|
||||
|
||||
*) Исправление: если сервер memcached возвращал некорректный ответ, в
|
||||
логах могли появляться сообщения "negative size buf in writer".
|
||||
|
||||
|
||||
Изменения в nginx 1.19.0 26.05.2020
|
||||
|
||||
*) Добавление: проверка клиентских сертификатов с помощью OCSP.
|
||||
|
||||
*) Исправление: при работе с gRPC-бэкендами могли возникать ошибки
|
||||
"upstream sent frame for closed stream".
|
||||
|
||||
*) Исправление: OCSP stapling мог не работать, если не была указана
|
||||
директива resolver.
|
||||
|
||||
*) Исправление: соединения с некорректным HTTP/2 preface не
|
||||
логгировались.
|
||||
|
||||
|
||||
Изменения в nginx 1.17.10 14.04.2020
|
||||
|
|
|
|||
4
LICENSE
4
LICENSE
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2019 Igor Sysoev
|
||||
* Copyright (C) 2011-2019 Nginx, Inc.
|
||||
* Copyright (C) 2002-2021 Igor Sysoev
|
||||
* Copyright (C) 2011-2021 Nginx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -48,4 +48,6 @@ default: build
|
|||
|
||||
clean:
|
||||
rm -rf Makefile $NGX_OBJS
|
||||
|
||||
.PHONY: default clean
|
||||
END
|
||||
|
|
|
|||
|
|
@ -215,4 +215,6 @@ upgrade:
|
|||
test -f $NGX_PID_PATH.oldbin
|
||||
|
||||
kill -QUIT \`cat $NGX_PID_PATH.oldbin\`
|
||||
|
||||
.PHONY: build install modules upgrade
|
||||
END
|
||||
|
|
|
|||
13
auto/make
13
auto/make
|
|
@ -313,7 +313,7 @@ $ngx_obj: \$(CORE_DEPS) \$(HTTP_DEPS)$ngx_cont$ngx_src
|
|||
END
|
||||
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
|
|
@ -343,7 +343,7 @@ $ngx_obj: \$(CORE_DEPS) \$(MAIL_DEPS)$ngx_cont$ngx_src
|
|||
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
|
||||
|
||||
END
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ $ngx_obj: \$(CORE_DEPS) \$(STREAM_DEPS)$ngx_cont$ngx_src
|
|||
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
|
||||
|
||||
END
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
|
|
@ -399,7 +399,7 @@ $ngx_obj: \$(CORE_DEPS) $ngx_cont$ngx_src
|
|||
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
|
||||
|
||||
END
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
|
|
@ -431,7 +431,7 @@ $ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src
|
|||
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
|
||||
|
||||
END
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
|
|
@ -502,6 +502,7 @@ fi
|
|||
for ngx_module in $DYNAMIC_MODULES
|
||||
do
|
||||
eval ngx_module_srcs="\$${ngx_module}_SRCS"
|
||||
eval ngx_module_shrd="\$${ngx_module}_SHRD"
|
||||
eval eval ngx_module_libs="\\\"\$${ngx_module}_LIBS\\\""
|
||||
|
||||
eval ngx_module_modules="\$${ngx_module}_MODULES"
|
||||
|
|
@ -567,7 +568,7 @@ END
|
|||
| sed -e "s/\(.*\.\)c/\1$ngx_objext/"`
|
||||
|
||||
ngx_module_objs=
|
||||
for ngx_src in $ngx_module_srcs
|
||||
for ngx_src in $ngx_module_srcs $ngx_module_shrd
|
||||
do
|
||||
case "$ngx_src" in
|
||||
src/*)
|
||||
|
|
|
|||
44
auto/module
44
auto/module
|
|
@ -17,7 +17,6 @@ if [ "$ngx_module_link" = DYNAMIC ]; then
|
|||
done
|
||||
|
||||
DYNAMIC_MODULES="$DYNAMIC_MODULES $ngx_module"
|
||||
eval ${ngx_module}_SRCS=\"$ngx_module_srcs\"
|
||||
|
||||
eval ${ngx_module}_MODULES=\"$ngx_module_name\"
|
||||
|
||||
|
|
@ -31,6 +30,30 @@ if [ "$ngx_module_link" = DYNAMIC ]; then
|
|||
eval ${ngx_module}_ORDER=\"$ngx_module_order\"
|
||||
fi
|
||||
|
||||
srcs=
|
||||
shrd=
|
||||
for src in $ngx_module_srcs
|
||||
do
|
||||
found=no
|
||||
for old in $DYNAMIC_MODULES_SRCS
|
||||
do
|
||||
if [ $src = $old ]; then
|
||||
found=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $found = no ]; then
|
||||
srcs="$srcs $src"
|
||||
else
|
||||
shrd="$shrd $src"
|
||||
fi
|
||||
done
|
||||
eval ${ngx_module}_SRCS=\"$srcs\"
|
||||
eval ${ngx_module}_SHRD=\"$shrd\"
|
||||
|
||||
DYNAMIC_MODULES_SRCS="$DYNAMIC_MODULES_SRCS $srcs"
|
||||
|
||||
if test -n "$ngx_module_incs"; then
|
||||
CORE_INCS="$CORE_INCS $ngx_module_incs"
|
||||
fi
|
||||
|
|
@ -107,7 +130,24 @@ elif [ "$ngx_module_link" = ADDON ]; then
|
|||
eval ${ngx_module_type}_MODULES=\"\$${ngx_module_type}_MODULES \
|
||||
$ngx_module_name\"
|
||||
|
||||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_module_srcs"
|
||||
srcs=
|
||||
for src in $ngx_module_srcs
|
||||
do
|
||||
found=no
|
||||
for old in $NGX_ADDON_SRCS
|
||||
do
|
||||
if [ $src = $old ]; then
|
||||
found=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $found = no ]; then
|
||||
srcs="$srcs $src"
|
||||
fi
|
||||
done
|
||||
|
||||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $srcs"
|
||||
|
||||
if test -n "$ngx_module_incs"; then
|
||||
eval ${ngx_var}_INCS=\"\$${ngx_var}_INCS $ngx_module_incs\"
|
||||
|
|
|
|||
16
auto/modules
16
auto/modules
|
|
@ -985,6 +985,12 @@ if [ $MAIL != NO ]; then
|
|||
ngx_module_srcs=src/mail/ngx_mail_proxy_module.c
|
||||
|
||||
. auto/module
|
||||
|
||||
ngx_module_name=ngx_mail_realip_module
|
||||
ngx_module_deps=
|
||||
ngx_module_srcs=src/mail/ngx_mail_realip_module.c
|
||||
|
||||
. auto/module
|
||||
fi
|
||||
|
||||
|
||||
|
|
@ -1119,6 +1125,16 @@ if [ $STREAM != NO ]; then
|
|||
. auto/module
|
||||
fi
|
||||
|
||||
if [ $STREAM_SET = YES ]; then
|
||||
ngx_module_name=ngx_stream_set_module
|
||||
ngx_module_deps=
|
||||
ngx_module_srcs=src/stream/ngx_stream_set_module.c
|
||||
ngx_module_libs=
|
||||
ngx_module_link=$STREAM_SET
|
||||
|
||||
. auto/module
|
||||
fi
|
||||
|
||||
if [ $STREAM_UPSTREAM_HASH = YES ]; then
|
||||
ngx_module_name=ngx_stream_upstream_hash_module
|
||||
ngx_module_deps=
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ STREAM_GEOIP=NO
|
|||
STREAM_MAP=YES
|
||||
STREAM_SPLIT_CLIENTS=YES
|
||||
STREAM_RETURN=YES
|
||||
STREAM_SET=YES
|
||||
STREAM_UPSTREAM_HASH=YES
|
||||
STREAM_UPSTREAM_LEAST_CONN=YES
|
||||
STREAM_UPSTREAM_RANDOM=YES
|
||||
|
|
@ -131,8 +132,10 @@ STREAM_UPSTREAM_ZONE=YES
|
|||
STREAM_SSL_PREREAD=NO
|
||||
|
||||
DYNAMIC_MODULES=
|
||||
DYNAMIC_MODULES_SRCS=
|
||||
|
||||
NGX_ADDONS=
|
||||
NGX_ADDON_SRCS=
|
||||
NGX_ADDON_DEPS=
|
||||
DYNAMIC_ADDONS=
|
||||
|
||||
|
|
@ -324,6 +327,7 @@ use the \"--with-mail_ssl_module\" option instead"
|
|||
--without-stream_split_clients_module)
|
||||
STREAM_SPLIT_CLIENTS=NO ;;
|
||||
--without-stream_return_module) STREAM_RETURN=NO ;;
|
||||
--without-stream_set_module) STREAM_SET=NO ;;
|
||||
--without-stream_upstream_hash_module)
|
||||
STREAM_UPSTREAM_HASH=NO ;;
|
||||
--without-stream_upstream_least_conn_module)
|
||||
|
|
@ -538,6 +542,7 @@ cat << END
|
|||
--without-stream_split_clients_module
|
||||
disable ngx_stream_split_clients_module
|
||||
--without-stream_return_module disable ngx_stream_return_module
|
||||
--without-stream_set_module disable ngx_stream_set_module
|
||||
--without-stream_upstream_hash_module
|
||||
disable ngx_stream_upstream_hash_module
|
||||
--without-stream_upstream_least_conn_module
|
||||
|
|
|
|||
|
|
@ -86,6 +86,31 @@ if [ $ngx_found = yes ]; then
|
|||
ee.data.ptr = NULL;
|
||||
epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
|
||||
. auto/feature
|
||||
|
||||
|
||||
# eventfd()
|
||||
|
||||
ngx_feature="eventfd()"
|
||||
ngx_feature_name="NGX_HAVE_EVENTFD"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <sys/eventfd.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="(void) eventfd(0, 0)"
|
||||
. auto/feature
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
have=NGX_HAVE_SYS_EVENTFD_H . auto/have
|
||||
fi
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
ngx_feature="eventfd() (SYS_eventfd)"
|
||||
ngx_feature_incs="#include <sys/syscall.h>"
|
||||
ngx_feature_test="(void) SYS_eventfd"
|
||||
. auto/feature
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
|||
79
auto/unix
79
auto/unix
|
|
@ -582,29 +582,6 @@ Currently file AIO is supported on FreeBSD 4.3+ and Linux 2.6.22+ only
|
|||
END
|
||||
exit 1
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
ngx_feature="eventfd()"
|
||||
ngx_feature_name="NGX_HAVE_EVENTFD"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <sys/eventfd.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="(void) eventfd(0, 0)"
|
||||
. auto/feature
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
have=NGX_HAVE_SYS_EVENTFD_H . auto/have
|
||||
fi
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
ngx_feature="eventfd() (SYS_eventfd)"
|
||||
ngx_feature_incs="#include <sys/syscall.h>"
|
||||
ngx_feature_test="(void) SYS_eventfd"
|
||||
. auto/feature
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
|
@ -727,17 +704,33 @@ ngx_feature_test="char buf[1]; struct iovec vec[1]; ssize_t n;
|
|||
. auto/feature
|
||||
|
||||
|
||||
ngx_feature="sys_nerr"
|
||||
ngx_feature_name="NGX_SYS_NERR"
|
||||
ngx_feature_run=value
|
||||
ngx_feature_incs='#include <errno.h>
|
||||
#include <stdio.h>'
|
||||
# strerrordesc_np(), introduced in glibc 2.32
|
||||
|
||||
ngx_feature="strerrordesc_np()"
|
||||
ngx_feature_name="NGX_HAVE_STRERRORDESC_NP"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs='#include <string.h>'
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test='printf("%d", sys_nerr);'
|
||||
ngx_feature_test="char *p; p = strerrordesc_np(0);
|
||||
if (p == NULL) return 1"
|
||||
. auto/feature
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
ngx_feature="sys_nerr"
|
||||
ngx_feature_name="NGX_SYS_NERR"
|
||||
ngx_feature_run=value
|
||||
ngx_feature_incs='#include <errno.h>
|
||||
#include <stdio.h>'
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test='printf("%d", sys_nerr);'
|
||||
. auto/feature
|
||||
fi
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
# Cygiwn defines _sys_nerr
|
||||
|
|
@ -753,34 +746,6 @@ if [ $ngx_found = no ]; then
|
|||
fi
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
# Solaris has no sys_nerr
|
||||
ngx_feature='maximum errno'
|
||||
ngx_feature_name=NGX_SYS_NERR
|
||||
ngx_feature_run=value
|
||||
ngx_feature_incs='#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>'
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test='int n;
|
||||
char *p;
|
||||
for (n = 1; n < 1000; n++) {
|
||||
errno = 0;
|
||||
p = strerror(n);
|
||||
if (errno == EINVAL
|
||||
|| p == NULL
|
||||
|| strncmp(p, "Unknown error", 13) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("%d", n);'
|
||||
. auto/feature
|
||||
fi
|
||||
|
||||
|
||||
ngx_feature="localtime_r()"
|
||||
ngx_feature_name="NGX_HAVE_LOCALTIME_R"
|
||||
ngx_feature_run=no
|
||||
|
|
|
|||
4
configure
vendored
4
configure
vendored
|
|
@ -87,6 +87,10 @@ have=NGX_PID_PATH value="\"$NGX_PID_PATH\"" . auto/define
|
|||
have=NGX_LOCK_PATH value="\"$NGX_LOCK_PATH\"" . auto/define
|
||||
have=NGX_ERROR_LOG_PATH value="\"$NGX_ERROR_LOG_PATH\"" . auto/define
|
||||
|
||||
if [ ".$NGX_ERROR_LOG_PATH" = "." ]; then
|
||||
have=NGX_ERROR_LOG_STDERR . auto/have
|
||||
fi
|
||||
|
||||
have=NGX_HTTP_LOG_PATH value="\"$NGX_HTTP_LOG_PATH\"" . auto/define
|
||||
have=NGX_HTTP_CLIENT_TEMP_PATH value="\"$NGX_HTTP_CLIENT_TEMP_PATH\""
|
||||
. auto/define
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ syn keyword ngxDirective contained ancient_browser_value
|
|||
syn keyword ngxDirective contained api
|
||||
syn keyword ngxDirective contained auth_basic
|
||||
syn keyword ngxDirective contained auth_basic_user_file
|
||||
syn keyword ngxDirective contained auth_delay
|
||||
syn keyword ngxDirective contained auth_http
|
||||
syn keyword ngxDirective contained auth_http_header
|
||||
syn keyword ngxDirective contained auth_http_pass_client_cert
|
||||
|
|
@ -267,6 +268,7 @@ syn keyword ngxDirective contained grpc_socket_keepalive
|
|||
syn keyword ngxDirective contained grpc_ssl_certificate
|
||||
syn keyword ngxDirective contained grpc_ssl_certificate_key
|
||||
syn keyword ngxDirective contained grpc_ssl_ciphers
|
||||
syn keyword ngxDirective contained grpc_ssl_conf_command
|
||||
syn keyword ngxDirective contained grpc_ssl_crl
|
||||
syn keyword ngxDirective contained grpc_ssl_name
|
||||
syn keyword ngxDirective contained grpc_ssl_password_file
|
||||
|
|
@ -332,6 +334,7 @@ syn keyword ngxDirective contained ip_hash
|
|||
syn keyword ngxDirective contained js_access
|
||||
syn keyword ngxDirective contained js_content
|
||||
syn keyword ngxDirective contained js_filter
|
||||
syn keyword ngxDirective contained js_import
|
||||
syn keyword ngxDirective contained js_include
|
||||
syn keyword ngxDirective contained js_path
|
||||
syn keyword ngxDirective contained js_preread
|
||||
|
|
@ -348,6 +351,7 @@ syn keyword ngxDirective contained large_client_header_buffers
|
|||
syn keyword ngxDirective contained least_conn
|
||||
syn keyword ngxDirective contained least_time
|
||||
syn keyword ngxDirective contained limit_conn
|
||||
syn keyword ngxDirective contained limit_conn_dry_run
|
||||
syn keyword ngxDirective contained limit_conn_log_level
|
||||
syn keyword ngxDirective contained limit_conn_status
|
||||
syn keyword ngxDirective contained limit_conn_zone
|
||||
|
|
@ -444,6 +448,7 @@ syn keyword ngxDirective contained proxy_cache_use_stale
|
|||
syn keyword ngxDirective contained proxy_cache_valid
|
||||
syn keyword ngxDirective contained proxy_connect_timeout
|
||||
syn keyword ngxDirective contained proxy_cookie_domain
|
||||
syn keyword ngxDirective contained proxy_cookie_flags
|
||||
syn keyword ngxDirective contained proxy_cookie_path
|
||||
syn keyword ngxDirective contained proxy_download_rate
|
||||
syn keyword ngxDirective contained proxy_force_ranges
|
||||
|
|
@ -477,11 +482,13 @@ syn keyword ngxDirective contained proxy_send_timeout
|
|||
syn keyword ngxDirective contained proxy_session_drop
|
||||
syn keyword ngxDirective contained proxy_set_body
|
||||
syn keyword ngxDirective contained proxy_set_header
|
||||
syn keyword ngxDirective contained proxy_smtp_auth
|
||||
syn keyword ngxDirective contained proxy_socket_keepalive
|
||||
syn keyword ngxDirective contained proxy_ssl
|
||||
syn keyword ngxDirective contained proxy_ssl_certificate
|
||||
syn keyword ngxDirective contained proxy_ssl_certificate_key
|
||||
syn keyword ngxDirective contained proxy_ssl_ciphers
|
||||
syn keyword ngxDirective contained proxy_ssl_conf_command
|
||||
syn keyword ngxDirective contained proxy_ssl_crl
|
||||
syn keyword ngxDirective contained proxy_ssl_name
|
||||
syn keyword ngxDirective contained proxy_ssl_password_file
|
||||
|
|
@ -589,16 +596,21 @@ syn keyword ngxDirective contained ssl_certificate
|
|||
syn keyword ngxDirective contained ssl_certificate_key
|
||||
syn keyword ngxDirective contained ssl_ciphers
|
||||
syn keyword ngxDirective contained ssl_client_certificate
|
||||
syn keyword ngxDirective contained ssl_conf_command
|
||||
syn keyword ngxDirective contained ssl_crl
|
||||
syn keyword ngxDirective contained ssl_dhparam
|
||||
syn keyword ngxDirective contained ssl_early_data
|
||||
syn keyword ngxDirective contained ssl_ecdh_curve
|
||||
syn keyword ngxDirective contained ssl_engine
|
||||
syn keyword ngxDirective contained ssl_handshake_timeout
|
||||
syn keyword ngxDirective contained ssl_ocsp
|
||||
syn keyword ngxDirective contained ssl_ocsp_cache
|
||||
syn keyword ngxDirective contained ssl_ocsp_responder
|
||||
syn keyword ngxDirective contained ssl_password_file
|
||||
syn keyword ngxDirective contained ssl_prefer_server_ciphers
|
||||
syn keyword ngxDirective contained ssl_preread
|
||||
syn keyword ngxDirective contained ssl_protocols
|
||||
syn keyword ngxDirective contained ssl_reject_handshake
|
||||
syn keyword ngxDirective contained ssl_session_cache
|
||||
syn keyword ngxDirective contained ssl_session_ticket_key
|
||||
syn keyword ngxDirective contained ssl_session_tickets
|
||||
|
|
@ -637,6 +649,7 @@ syn keyword ngxDirective contained user
|
|||
syn keyword ngxDirective contained userid
|
||||
syn keyword ngxDirective contained userid_domain
|
||||
syn keyword ngxDirective contained userid_expires
|
||||
syn keyword ngxDirective contained userid_flags
|
||||
syn keyword ngxDirective contained userid_mark
|
||||
syn keyword ngxDirective contained userid_name
|
||||
syn keyword ngxDirective contained userid_p3p
|
||||
|
|
@ -687,6 +700,7 @@ syn keyword ngxDirective contained uwsgi_socket_keepalive
|
|||
syn keyword ngxDirective contained uwsgi_ssl_certificate
|
||||
syn keyword ngxDirective contained uwsgi_ssl_certificate_key
|
||||
syn keyword ngxDirective contained uwsgi_ssl_ciphers
|
||||
syn keyword ngxDirective contained uwsgi_ssl_conf_command
|
||||
syn keyword ngxDirective contained uwsgi_ssl_crl
|
||||
syn keyword ngxDirective contained uwsgi_ssl_name
|
||||
syn keyword ngxDirective contained uwsgi_ssl_password_file
|
||||
|
|
@ -732,6 +746,7 @@ syn keyword ngxDirective contained zone_sync_ssl
|
|||
syn keyword ngxDirective contained zone_sync_ssl_certificate
|
||||
syn keyword ngxDirective contained zone_sync_ssl_certificate_key
|
||||
syn keyword ngxDirective contained zone_sync_ssl_ciphers
|
||||
syn keyword ngxDirective contained zone_sync_ssl_conf_command
|
||||
syn keyword ngxDirective contained zone_sync_ssl_crl
|
||||
syn keyword ngxDirective contained zone_sync_ssl_name
|
||||
syn keyword ngxDirective contained zone_sync_ssl_password_file
|
||||
|
|
@ -770,6 +785,7 @@ syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal
|
|||
syn keyword ngxDirectiveThirdParty contained auth_gss_force_realm
|
||||
syn keyword ngxDirectiveThirdParty contained auth_gss_format_full
|
||||
syn keyword ngxDirectiveThirdParty contained auth_gss_keytab
|
||||
syn keyword ngxDirectiveThirdParty contained auth_gss_map_to_local
|
||||
syn keyword ngxDirectiveThirdParty contained auth_gss_realm
|
||||
syn keyword ngxDirectiveThirdParty contained auth_gss_service_name
|
||||
|
||||
|
|
@ -791,8 +807,8 @@ syn keyword ngxDirectiveThirdParty contained auth_pam_set_pam_env
|
|||
|
||||
" AJP protocol proxy
|
||||
" https://github.com/yaoweibin/nginx_ajp_module
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_buffer_size
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_buffers
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_buffer_size
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_busy_buffers_size
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_cache
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_cache_key
|
||||
|
|
@ -818,6 +834,7 @@ syn keyword ngxDirectiveThirdParty contained ajp_pass_header
|
|||
syn keyword ngxDirectiveThirdParty contained ajp_pass_request_body
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_pass_request_headers
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_read_timeout
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_secret
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_send_lowat
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_send_timeout
|
||||
syn keyword ngxDirectiveThirdParty contained ajp_store
|
||||
|
|
@ -854,8 +871,8 @@ syn keyword ngxDirectiveThirdParty contained content_handler_property
|
|||
syn keyword ngxDirectiveThirdParty contained content_handler_type
|
||||
syn keyword ngxDirectiveThirdParty contained handler_code
|
||||
syn keyword ngxDirectiveThirdParty contained handler_name
|
||||
syn keyword ngxDirectiveThirdParty contained handler_type
|
||||
syn keyword ngxDirectiveThirdParty contained handlers_lazy_init
|
||||
syn keyword ngxDirectiveThirdParty contained handler_type
|
||||
syn keyword ngxDirectiveThirdParty contained header_filter_code
|
||||
syn keyword ngxDirectiveThirdParty contained header_filter_name
|
||||
syn keyword ngxDirectiveThirdParty contained header_filter_property
|
||||
|
|
@ -871,6 +888,10 @@ syn keyword ngxDirectiveThirdParty contained jvm_options
|
|||
syn keyword ngxDirectiveThirdParty contained jvm_path
|
||||
syn keyword ngxDirectiveThirdParty contained jvm_var
|
||||
syn keyword ngxDirectiveThirdParty contained jvm_workers
|
||||
syn keyword ngxDirectiveThirdParty contained log_handler_code
|
||||
syn keyword ngxDirectiveThirdParty contained log_handler_name
|
||||
syn keyword ngxDirectiveThirdParty contained log_handler_property
|
||||
syn keyword ngxDirectiveThirdParty contained log_handler_type
|
||||
syn keyword ngxDirectiveThirdParty contained max_balanced_tcp_connections
|
||||
syn keyword ngxDirectiveThirdParty contained rewrite_handler_code
|
||||
syn keyword ngxDirectiveThirdParty contained rewrite_handler_name
|
||||
|
|
@ -879,6 +900,7 @@ syn keyword ngxDirectiveThirdParty contained rewrite_handler_type
|
|||
syn keyword ngxDirectiveThirdParty contained shared_map
|
||||
syn keyword ngxDirectiveThirdParty contained write_page_size
|
||||
|
||||
|
||||
" Certificate Transparency
|
||||
" https://github.com/grahamedgecombe/nginx-ct
|
||||
syn keyword ngxDirectiveThirdParty contained ssl_ct
|
||||
|
|
@ -942,6 +964,7 @@ syn keyword ngxDirectiveThirdParty contained fancyindex_hide_symlinks
|
|||
syn keyword ngxDirectiveThirdParty contained fancyindex_ignore
|
||||
syn keyword ngxDirectiveThirdParty contained fancyindex_localtime
|
||||
syn keyword ngxDirectiveThirdParty contained fancyindex_name_length
|
||||
syn keyword ngxDirectiveThirdParty contained fancyindex_show_dotfiles
|
||||
syn keyword ngxDirectiveThirdParty contained fancyindex_show_path
|
||||
syn keyword ngxDirectiveThirdParty contained fancyindex_time_format
|
||||
|
||||
|
|
@ -991,8 +1014,8 @@ syn keyword ngxDirectiveThirdParty contained nchan_benchmark_publisher_distribut
|
|||
syn keyword ngxDirectiveThirdParty contained nchan_benchmark_subscriber_distribution
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_benchmark_subscribers_per_channel
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_benchmark_time
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_channel_event_string
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_channel_events_channel_id
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_channel_event_string
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_channel_group
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_channel_group_accounting
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_channel_id
|
||||
|
|
@ -1000,6 +1023,10 @@ syn keyword ngxDirectiveThirdParty contained nchan_channel_id_split_delimiter
|
|||
syn keyword ngxDirectiveThirdParty contained nchan_channel_timeout
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_deflate_message_for_websocket
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_eventsource_event
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_eventsource_ping_comment
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_eventsource_ping_data
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_eventsource_ping_event
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_eventsource_ping_interval
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_group_location
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_group_max_channels
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_group_max_messages
|
||||
|
|
@ -1047,10 +1074,10 @@ syn keyword ngxDirectiveThirdParty contained nchan_store_messages
|
|||
syn keyword ngxDirectiveThirdParty contained nchan_stub_status
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_sub_channel_id
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_subscribe_existing_channels_only
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_subscribe_request
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_subscriber
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_channel_id
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_compound_etag_message_id
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_subscribe_request
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_first_message
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_http_raw_stream_separator
|
||||
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_last_message_id
|
||||
|
|
@ -1311,6 +1338,8 @@ syn keyword ngxDirectiveThirdParty contained body_filter_by_lua_file
|
|||
syn keyword ngxDirectiveThirdParty contained content_by_lua
|
||||
syn keyword ngxDirectiveThirdParty contained content_by_lua_block
|
||||
syn keyword ngxDirectiveThirdParty contained content_by_lua_file
|
||||
syn keyword ngxDirectiveThirdParty contained exit_worker_by_lua_block
|
||||
syn keyword ngxDirectiveThirdParty contained exit_worker_by_lua_file
|
||||
syn keyword ngxDirectiveThirdParty contained header_filter_by_lua
|
||||
syn keyword ngxDirectiveThirdParty contained header_filter_by_lua_block
|
||||
syn keyword ngxDirectiveThirdParty contained header_filter_by_lua_file
|
||||
|
|
@ -1352,6 +1381,7 @@ syn keyword ngxDirectiveThirdParty contained lua_ssl_crl
|
|||
syn keyword ngxDirectiveThirdParty contained lua_ssl_protocols
|
||||
syn keyword ngxDirectiveThirdParty contained lua_ssl_trusted_certificate
|
||||
syn keyword ngxDirectiveThirdParty contained lua_ssl_verify_depth
|
||||
syn keyword ngxDirectiveThirdParty contained lua_thread_cache_max_entries
|
||||
syn keyword ngxDirectiveThirdParty contained lua_transform_underscores_in_response_headers
|
||||
syn keyword ngxDirectiveThirdParty contained lua_use_default_type
|
||||
syn keyword ngxDirectiveThirdParty contained rewrite_by_lua
|
||||
|
|
@ -1987,11 +2017,7 @@ syn keyword ngxDirectiveThirdParty contained concat_unique
|
|||
" update upstreams' config by restful interface
|
||||
" https://github.com/yzprofile/ngx_http_dyups_module
|
||||
syn keyword ngxDirectiveThirdParty contained dyups_interface
|
||||
syn keyword ngxDirectiveThirdParty contained dyups_read_msg_log
|
||||
syn keyword ngxDirectiveThirdParty contained dyups_read_msg_timeout
|
||||
syn keyword ngxDirectiveThirdParty contained dyups_shm_zone_size
|
||||
syn keyword ngxDirectiveThirdParty contained dyups_trylock
|
||||
syn keyword ngxDirectiveThirdParty contained dyups_upstream_conf
|
||||
|
||||
" add given content to the end of the response according to the condition specified
|
||||
" https://github.com/flygoast/ngx_http_footer_if_filter
|
||||
|
|
@ -2271,6 +2297,7 @@ syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie_i
|
|||
syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie_key
|
||||
syn keyword ngxDirectiveThirdParty contained testcookie_refresh_status
|
||||
syn keyword ngxDirectiveThirdParty contained testcookie_refresh_template
|
||||
syn keyword ngxDirectiveThirdParty contained testcookie_samesite
|
||||
syn keyword ngxDirectiveThirdParty contained testcookie_secret
|
||||
syn keyword ngxDirectiveThirdParty contained testcookie_secure_flag
|
||||
syn keyword ngxDirectiveThirdParty contained testcookie_session
|
||||
|
|
@ -2308,31 +2335,105 @@ syn keyword ngxDirectiveThirdParty contained user_agent
|
|||
" https://github.com/flygoast/ngx_http_upstream_ketama_chash
|
||||
syn keyword ngxDirectiveThirdParty contained ketama_chash
|
||||
|
||||
" nginx-sticky-module-ng
|
||||
" https://github.com/ayty-adrianomartins/nginx-sticky-module-ng
|
||||
syn keyword ngxDirectiveThirdParty contained sticky_no_fallback
|
||||
|
||||
" dynamic linking and call the function of your application
|
||||
" https://github.com/Taymindis/nginx-link-function
|
||||
syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_prop
|
||||
syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_req_header
|
||||
syn keyword ngxDirectiveThirdParty contained ngx_link_func_ca_cert
|
||||
syn keyword ngxDirectiveThirdParty contained ngx_link_func_call
|
||||
syn keyword ngxDirectiveThirdParty contained ngx_link_func_download_link_lib
|
||||
syn keyword ngxDirectiveThirdParty contained ngx_link_func_lib
|
||||
syn keyword ngxDirectiveThirdParty contained ngx_link_func_shm_size
|
||||
syn keyword ngxDirectiveThirdParty contained ngx_link_func_subrequest
|
||||
|
||||
" purge content from FastCGI, proxy, SCGI and uWSGI caches
|
||||
" https://github.com/torden/ngx_cache_purge
|
||||
syn keyword ngxDirectiveThirdParty contained cache_purge_response_type
|
||||
|
||||
" set the flags "HttpOnly", "secure" and "SameSite" for cookies
|
||||
" https://github.com/AirisX/nginx_cookie_flag_module
|
||||
syn keyword ngxDirectiveThirdParty contained set_cookie_flag
|
||||
|
||||
" Embed websockify into Nginx (convert any tcp connection into websocket)
|
||||
" https://github.com/tg123/websockify-nginx-module
|
||||
syn keyword ngxDirectiveThirdParty contained websockify_buffer_size
|
||||
syn keyword ngxDirectiveThirdParty contained websockify_connect_timeout
|
||||
syn keyword ngxDirectiveThirdParty contained websockify_pass
|
||||
syn keyword ngxDirectiveThirdParty contained websockify_read_timeout
|
||||
syn keyword ngxDirectiveThirdParty contained websockify_send_timeout
|
||||
|
||||
" IP2Location Nginx
|
||||
" https://github.com/ip2location/ip2location-nginx
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_proxy
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_proxy_recursive
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_areacode
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_city
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_country_long
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_country_short
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_domain
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_elevation
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_iddcode
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_isp
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_latitude
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_longitude
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_mcc
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_mnc
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_mobilebrand
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_netspeed
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_region
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_timezone
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_usagetype
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_weatherstationcode
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_weatherstationname
|
||||
syn keyword ngxDirectiveThirdParty contained ip2location_zipcode
|
||||
|
||||
" IP2Proxy module for Nginx
|
||||
" https://github.com/ip2location/ip2proxy-nginx
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_as
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_asn
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_city
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_country_long
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_country_short
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_database
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_domain
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_isp
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_is_proxy
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_last_seen
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_recursive
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_type
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_region
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_threat
|
||||
syn keyword ngxDirectiveThirdParty contained ip2proxy_usage_type
|
||||
|
||||
|
||||
|
||||
" highlight
|
||||
|
||||
hi link ngxComment Comment
|
||||
hi link ngxParamComment Comment
|
||||
hi link ngxListenComment Comment
|
||||
hi link ngxVariable Identifier
|
||||
hi link ngxVariableString PreProc
|
||||
hi link ngxString String
|
||||
hi link ngxListenString String
|
||||
hi def link ngxComment Comment
|
||||
hi def link ngxParamComment Comment
|
||||
hi def link ngxListenComment Comment
|
||||
hi def link ngxVariable Identifier
|
||||
hi def link ngxVariableString PreProc
|
||||
hi def link ngxString String
|
||||
hi def link ngxListenString String
|
||||
|
||||
hi link ngxBoolean Boolean
|
||||
hi link ngxDirectiveBlock Statement
|
||||
hi link ngxDirectiveImportant Type
|
||||
hi link ngxDirectiveListen Type
|
||||
hi link ngxDirectiveControl Keyword
|
||||
hi link ngxDirectiveError Constant
|
||||
hi link ngxDirectiveDeprecated Error
|
||||
hi link ngxDirective Identifier
|
||||
hi link ngxDirectiveThirdParty Special
|
||||
hi link ngxDirectiveThirdPartyDeprecated Error
|
||||
hi def link ngxBoolean Boolean
|
||||
hi def link ngxDirectiveBlock Statement
|
||||
hi def link ngxDirectiveImportant Type
|
||||
hi def link ngxDirectiveListen Type
|
||||
hi def link ngxDirectiveControl Keyword
|
||||
hi def link ngxDirectiveError Constant
|
||||
hi def link ngxDirectiveDeprecated Error
|
||||
hi def link ngxDirective Identifier
|
||||
hi def link ngxDirectiveThirdParty Special
|
||||
hi def link ngxDirectiveThirdPartyDeprecated Error
|
||||
|
||||
hi link ngxListenOptions Keyword
|
||||
hi link ngxListenOptionsDeprecated Error
|
||||
hi def link ngxListenOptions Keyword
|
||||
hi def link ngxListenOptionsDeprecated Error
|
||||
|
||||
let b:current_syntax = "nginx"
|
||||
|
|
|
|||
13
man/nginx.8
13
man/nginx.8
|
|
@ -25,7 +25,7 @@
|
|||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd December 5, 2019
|
||||
.Dd November 5, 2020
|
||||
.Dt NGINX 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
.Nm
|
||||
.Op Fl ?hqTtVv
|
||||
.Op Fl c Ar file
|
||||
.Op Fl e Ar file
|
||||
.Op Fl g Ar directives
|
||||
.Op Fl p Ar prefix
|
||||
.Op Fl s Ar signal
|
||||
|
|
@ -54,6 +55,12 @@ Print help.
|
|||
.It Fl c Ar file
|
||||
Use an alternative configuration
|
||||
.Ar file .
|
||||
.It Fl e Ar file
|
||||
Use an alternative error log
|
||||
.Ar file .
|
||||
Special value
|
||||
.Cm stderr
|
||||
indicates that the standard error output should be used.
|
||||
.It Fl g Ar directives
|
||||
Set global configuration directives.
|
||||
See
|
||||
|
|
@ -198,10 +205,10 @@ Development of
|
|||
started in 2002, with the first public release on October 4, 2004.
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
.An Igor Sysoev Aq igor@sysoev.ru .
|
||||
.An Igor Sysoev Aq Mt igor@sysoev.ru .
|
||||
.Pp
|
||||
This manual page was originally written by
|
||||
.An Sergey A. Osokin Aq osa@FreeBSD.org.ru
|
||||
.An Sergey A. Osokin Aq Mt osa@FreeBSD.org.ru
|
||||
as a result of compiling many
|
||||
.Nm
|
||||
documents from all over the world.
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ static ngx_uint_t ngx_show_help;
|
|||
static ngx_uint_t ngx_show_version;
|
||||
static ngx_uint_t ngx_show_configure;
|
||||
static u_char *ngx_prefix;
|
||||
static u_char *ngx_error_log;
|
||||
static u_char *ngx_conf_file;
|
||||
static u_char *ngx_conf_params;
|
||||
static char *ngx_signal;
|
||||
|
|
@ -230,7 +231,7 @@ main(int argc, char *const *argv)
|
|||
ngx_pid = ngx_getpid();
|
||||
ngx_parent = ngx_getppid();
|
||||
|
||||
log = ngx_log_init(ngx_prefix);
|
||||
log = ngx_log_init(ngx_prefix, ngx_error_log);
|
||||
if (log == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -393,9 +394,9 @@ ngx_show_version_info(void)
|
|||
|
||||
if (ngx_show_help) {
|
||||
ngx_write_stderr(
|
||||
"Usage: nginx [-?hvVtTq] [-s signal] [-c filename] "
|
||||
"[-p prefix] [-g directives]" NGX_LINEFEED
|
||||
NGX_LINEFEED
|
||||
"Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]" NGX_LINEFEED
|
||||
" [-e filename] [-c filename] [-g directives]"
|
||||
NGX_LINEFEED NGX_LINEFEED
|
||||
"Options:" NGX_LINEFEED
|
||||
" -?,-h : this help" NGX_LINEFEED
|
||||
" -v : show version and exit" NGX_LINEFEED
|
||||
|
|
@ -413,6 +414,12 @@ ngx_show_version_info(void)
|
|||
NGX_LINEFEED
|
||||
#else
|
||||
" -p prefix : set prefix path (default: NONE)" NGX_LINEFEED
|
||||
#endif
|
||||
" -e filename : set error log file (default: "
|
||||
#ifdef NGX_ERROR_LOG_STDERR
|
||||
"stderr)" NGX_LINEFEED
|
||||
#else
|
||||
NGX_ERROR_LOG_PATH ")" NGX_LINEFEED
|
||||
#endif
|
||||
" -c filename : set configuration file (default: " NGX_CONF_PATH
|
||||
")" NGX_LINEFEED
|
||||
|
|
@ -492,6 +499,7 @@ ngx_add_inherited_sockets(ngx_cycle_t *cycle)
|
|||
ngx_memzero(ls, sizeof(ngx_listening_t));
|
||||
|
||||
ls->fd = (ngx_socket_t) s;
|
||||
ls->inherited = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -799,6 +807,24 @@ ngx_get_options(int argc, char *const *argv)
|
|||
ngx_log_stderr(0, "option \"-p\" requires directory name");
|
||||
return NGX_ERROR;
|
||||
|
||||
case 'e':
|
||||
if (*p) {
|
||||
ngx_error_log = p;
|
||||
|
||||
} else if (argv[++i]) {
|
||||
ngx_error_log = (u_char *) argv[i];
|
||||
|
||||
} else {
|
||||
ngx_log_stderr(0, "option \"-e\" requires file name");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_strcmp(ngx_error_log, "stderr") == 0) {
|
||||
ngx_error_log = (u_char *) "";
|
||||
}
|
||||
|
||||
goto next;
|
||||
|
||||
case 'c':
|
||||
if (*p) {
|
||||
ngx_conf_file = p;
|
||||
|
|
@ -991,6 +1017,14 @@ ngx_process_options(ngx_cycle_t *cycle)
|
|||
}
|
||||
}
|
||||
|
||||
if (ngx_error_log) {
|
||||
cycle->error_log.len = ngx_strlen(ngx_error_log);
|
||||
cycle->error_log.data = ngx_error_log;
|
||||
|
||||
} else {
|
||||
ngx_str_set(&cycle->error_log, NGX_ERROR_LOG_PATH);
|
||||
}
|
||||
|
||||
if (ngx_conf_params) {
|
||||
cycle->conf_param.len = ngx_strlen(ngx_conf_params);
|
||||
cycle->conf_param.data = ngx_conf_params;
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define nginx_version 1018000
|
||||
#define NGINX_VERSION "1.18.0"
|
||||
#define nginx_version 1020002
|
||||
#define NGINX_VERSION "1.20.2"
|
||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
|
|
|
|||
|
|
@ -203,16 +203,16 @@ ngx_chain_update_chains(ngx_pool_t *p, ngx_chain_t **free, ngx_chain_t **busy,
|
|||
while (*busy) {
|
||||
cl = *busy;
|
||||
|
||||
if (ngx_buf_size(cl->buf) != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (cl->buf->tag != tag) {
|
||||
*busy = cl->next;
|
||||
ngx_free_chain(p, cl);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_buf_size(cl->buf) != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
cl->buf->pos = cl->buf->start;
|
||||
cl->buf->last = cl->buf->start;
|
||||
|
||||
|
|
|
|||
|
|
@ -125,20 +125,20 @@ typedef struct {
|
|||
#define NGX_CHAIN_ERROR (ngx_chain_t *) NGX_ERROR
|
||||
|
||||
|
||||
#define ngx_buf_in_memory(b) (b->temporary || b->memory || b->mmap)
|
||||
#define ngx_buf_in_memory_only(b) (ngx_buf_in_memory(b) && !b->in_file)
|
||||
#define ngx_buf_in_memory(b) ((b)->temporary || (b)->memory || (b)->mmap)
|
||||
#define ngx_buf_in_memory_only(b) (ngx_buf_in_memory(b) && !(b)->in_file)
|
||||
|
||||
#define ngx_buf_special(b) \
|
||||
((b->flush || b->last_buf || b->sync) \
|
||||
&& !ngx_buf_in_memory(b) && !b->in_file)
|
||||
(((b)->flush || (b)->last_buf || (b)->sync) \
|
||||
&& !ngx_buf_in_memory(b) && !(b)->in_file)
|
||||
|
||||
#define ngx_buf_sync_only(b) \
|
||||
(b->sync \
|
||||
&& !ngx_buf_in_memory(b) && !b->in_file && !b->flush && !b->last_buf)
|
||||
((b)->sync && !ngx_buf_in_memory(b) \
|
||||
&& !(b)->in_file && !(b)->flush && !(b)->last_buf)
|
||||
|
||||
#define ngx_buf_size(b) \
|
||||
(ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos): \
|
||||
(b->file_last - b->file_pos))
|
||||
(ngx_buf_in_memory(b) ? (off_t) ((b)->last - (b)->pos): \
|
||||
((b)->file_last - (b)->file_pos))
|
||||
|
||||
ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size);
|
||||
ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);
|
||||
|
|
@ -149,8 +149,8 @@ ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);
|
|||
|
||||
ngx_chain_t *ngx_alloc_chain_link(ngx_pool_t *pool);
|
||||
#define ngx_free_chain(pool, cl) \
|
||||
cl->next = pool->chain; \
|
||||
pool->chain = cl
|
||||
(cl)->next = (pool)->chain; \
|
||||
(pool)->chain = (cl)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1137,7 +1137,7 @@ ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
a = (ngx_array_t **) (p + cmd->offset);
|
||||
|
||||
if (*a == NULL) {
|
||||
if (*a == NGX_CONF_UNSET_PTR || *a == NULL) {
|
||||
*a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
|
||||
if (*a == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
|
|
|
|||
|
|
@ -1070,7 +1070,8 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
|
|||
|
||||
if (ls[i].sockaddr->sa_family == AF_UNIX
|
||||
&& ngx_process <= NGX_PROCESS_MASTER
|
||||
&& ngx_new_binary == 0)
|
||||
&& ngx_new_binary == 0
|
||||
&& (!ls[i].inherited || ngx_getppid() != ngx_parent))
|
||||
{
|
||||
u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
|
||||
|
||||
|
|
@ -1106,12 +1107,9 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
c = ngx_cycle->free_connections;
|
||||
ngx_drain_connections((ngx_cycle_t *) ngx_cycle);
|
||||
|
||||
if (c == NULL) {
|
||||
ngx_drain_connections((ngx_cycle_t *) ngx_cycle);
|
||||
c = ngx_cycle->free_connections;
|
||||
}
|
||||
c = ngx_cycle->free_connections;
|
||||
|
||||
if (c == NULL) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
||||
|
|
@ -1297,6 +1295,22 @@ ngx_drain_connections(ngx_cycle_t *cycle)
|
|||
ngx_queue_t *q;
|
||||
ngx_connection_t *c;
|
||||
|
||||
if (cycle->free_connection_n > cycle->connection_n / 16
|
||||
|| cycle->reusable_connections_n == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (cycle->connections_reuse_time != ngx_time()) {
|
||||
cycle->connections_reuse_time = ngx_time();
|
||||
|
||||
ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
|
||||
"%ui worker_connections are not enough, "
|
||||
"reusing connections",
|
||||
cycle->connection_n);
|
||||
}
|
||||
|
||||
c = NULL;
|
||||
n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
|
|
@ -1313,6 +1327,21 @@ ngx_drain_connections(ngx_cycle_t *cycle)
|
|||
c->close = 1;
|
||||
c->read->handler(c->read);
|
||||
}
|
||||
|
||||
if (cycle->free_connection_n == 0 && c && c->reusable) {
|
||||
|
||||
/*
|
||||
* if no connections were freed, try to reuse the last
|
||||
* connection again: this should free it as long as
|
||||
* previous reuse moved it to lingering close
|
||||
*/
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
|
||||
"reusing connection again");
|
||||
|
||||
c->close = 1;
|
||||
c->read->handler(c->read);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,6 @@ struct ngx_listening_s {
|
|||
size_t pool_size;
|
||||
/* should be here because of the AcceptEx() preread */
|
||||
size_t post_accept_buffer_size;
|
||||
/* should be here because of the deferred accept */
|
||||
ngx_msec_t post_accept_timeout;
|
||||
|
||||
ngx_listening_t *previous;
|
||||
ngx_connection_t *connection;
|
||||
|
|
@ -164,6 +162,7 @@ struct ngx_connection_s {
|
|||
|
||||
ngx_atomic_uint_t number;
|
||||
|
||||
ngx_msec_t start_time;
|
||||
ngx_uint_t requests;
|
||||
|
||||
unsigned buffered:8;
|
||||
|
|
|
|||
|
|
@ -96,6 +96,15 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
cycle->error_log.len = old_cycle->error_log.len;
|
||||
cycle->error_log.data = ngx_pnalloc(pool, old_cycle->error_log.len + 1);
|
||||
if (cycle->error_log.data == NULL) {
|
||||
ngx_destroy_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
ngx_cpystrn(cycle->error_log.data, old_cycle->error_log.data,
|
||||
old_cycle->error_log.len + 1);
|
||||
|
||||
cycle->conf_file.len = old_cycle->conf_file.len;
|
||||
cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
|
||||
if (cycle->conf_file.data == NULL) {
|
||||
|
|
@ -520,6 +529,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|||
== NGX_OK)
|
||||
{
|
||||
nls[n].fd = ls[i].fd;
|
||||
nls[n].inherited = ls[i].inherited;
|
||||
nls[n].previous = &ls[i];
|
||||
ls[i].remain = 1;
|
||||
|
||||
|
|
@ -1008,6 +1018,7 @@ ngx_int_t
|
|||
ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
|
||||
{
|
||||
size_t len;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t create;
|
||||
ngx_file_t file;
|
||||
u_char pid[NGX_INT64_LEN + 2];
|
||||
|
|
@ -1032,11 +1043,13 @@ ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rc = NGX_OK;
|
||||
|
||||
if (!ngx_test_config) {
|
||||
len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
|
||||
|
||||
if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
rc = NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1045,7 +1058,7 @@ ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
|
|||
ngx_close_file_n " \"%s\" failed", file.name.data);
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct ngx_cycle_s {
|
|||
|
||||
ngx_queue_t reusable_connections_queue;
|
||||
ngx_uint_t reusable_connections_n;
|
||||
time_t connections_reuse_time;
|
||||
|
||||
ngx_array_t listening;
|
||||
ngx_array_t paths;
|
||||
|
|
@ -79,6 +80,7 @@ struct ngx_cycle_s {
|
|||
ngx_str_t conf_param;
|
||||
ngx_str_t conf_prefix;
|
||||
ngx_str_t prefix;
|
||||
ngx_str_t error_log;
|
||||
ngx_str_t lock_file;
|
||||
ngx_str_t hostname;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err)
|
|||
|
||||
|
||||
ngx_log_t *
|
||||
ngx_log_init(u_char *prefix)
|
||||
ngx_log_init(u_char *prefix, u_char *error_log)
|
||||
{
|
||||
u_char *p, *name;
|
||||
size_t nlen, plen;
|
||||
|
|
@ -323,13 +323,11 @@ ngx_log_init(u_char *prefix)
|
|||
ngx_log.file = &ngx_log_file;
|
||||
ngx_log.log_level = NGX_LOG_NOTICE;
|
||||
|
||||
name = (u_char *) NGX_ERROR_LOG_PATH;
|
||||
|
||||
/*
|
||||
* we use ngx_strlen() here since BCC warns about
|
||||
* condition is always false and unreachable code
|
||||
*/
|
||||
if (error_log == NULL) {
|
||||
error_log = (u_char *) NGX_ERROR_LOG_PATH;
|
||||
}
|
||||
|
||||
name = error_log;
|
||||
nlen = ngx_strlen(name);
|
||||
|
||||
if (nlen == 0) {
|
||||
|
|
@ -369,7 +367,7 @@ ngx_log_init(u_char *prefix)
|
|||
*p++ = '/';
|
||||
}
|
||||
|
||||
ngx_cpystrn(p, (u_char *) NGX_ERROR_LOG_PATH, nlen + 1);
|
||||
ngx_cpystrn(p, error_log, nlen + 1);
|
||||
|
||||
p = name;
|
||||
}
|
||||
|
|
@ -403,8 +401,7 @@ ngx_log_init(u_char *prefix)
|
|||
ngx_int_t
|
||||
ngx_log_open_default(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_log_t *log;
|
||||
static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH);
|
||||
ngx_log_t *log;
|
||||
|
||||
if (ngx_log_get_file_log(&cycle->new_log) != NULL) {
|
||||
return NGX_OK;
|
||||
|
|
@ -425,7 +422,7 @@ ngx_log_open_default(ngx_cycle_t *cycle)
|
|||
|
||||
log->log_level = NGX_LOG_ERR;
|
||||
|
||||
log->file = ngx_conf_open_file(cycle, &error_log);
|
||||
log->file = ngx_conf_open_file(cycle, &cycle->error_log);
|
||||
if (log->file == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ void ngx_cdecl ngx_log_debug_core(ngx_log_t *log, ngx_err_t err,
|
|||
|
||||
/*********************************/
|
||||
|
||||
ngx_log_t *ngx_log_init(u_char *prefix);
|
||||
ngx_log_t *ngx_log_init(u_char *prefix, u_char *error_log);
|
||||
void ngx_cdecl ngx_log_abort(ngx_err_t err, const char *fmt, ...);
|
||||
void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...);
|
||||
u_char *ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err);
|
||||
|
|
|
|||
|
|
@ -1563,13 +1563,28 @@ ngx_resolver_udp_read(ngx_event_t *rev)
|
|||
do {
|
||||
n = ngx_udp_recv(c, buf, NGX_RESOLVER_UDP_SIZE);
|
||||
|
||||
if (n < 0) {
|
||||
return;
|
||||
if (n == NGX_AGAIN) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ngx_resolver_process_response(rec->resolver, buf, n, 0);
|
||||
|
||||
} while (rev->ready);
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
failed:
|
||||
|
||||
ngx_close_connection(rec->udp);
|
||||
rec->udp = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1783,6 +1798,12 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
i = sizeof(ngx_resolver_hdr_t);
|
||||
|
||||
while (i < (ngx_uint_t) n) {
|
||||
|
||||
if (buf[i] & 0xc0) {
|
||||
err = "unexpected compression pointer in DNS response";
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (buf[i] == '\0') {
|
||||
goto found;
|
||||
}
|
||||
|
|
@ -1918,7 +1939,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
|
||||
if (rn == NULL) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected response for %V", &name);
|
||||
"unexpected DNS response for %V", &name);
|
||||
ngx_resolver_free(r, name.data);
|
||||
goto failed;
|
||||
}
|
||||
|
|
@ -1930,7 +1951,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
|
||||
if (rn->query6 == NULL || rn->naddrs6 != (u_short) -1) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected response for %V", &name);
|
||||
"unexpected DNS response for %V", &name);
|
||||
ngx_resolver_free(r, name.data);
|
||||
goto failed;
|
||||
}
|
||||
|
|
@ -1949,7 +1970,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
|
||||
if (rn->query == NULL || rn->naddrs != (u_short) -1) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected response for %V", &name);
|
||||
"unexpected DNS response for %V", &name);
|
||||
ngx_resolver_free(r, name.data);
|
||||
goto failed;
|
||||
}
|
||||
|
|
@ -1964,7 +1985,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
|
||||
if (ident != qident) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"wrong ident %ui response for %V, expect %ui",
|
||||
"wrong ident %ui in DNS response for %V, expect %ui",
|
||||
ident, &name, qident);
|
||||
ngx_resolver_free(r, name.data);
|
||||
goto failed;
|
||||
|
|
@ -2149,7 +2170,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
|
||||
if (class != 1) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected RR class %ui", class);
|
||||
"unexpected RR class %ui in DNS response", class);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
|
@ -2218,7 +2239,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
default:
|
||||
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected RR type %ui", type);
|
||||
"unexpected RR type %ui in DNS response", type);
|
||||
}
|
||||
|
||||
i += len;
|
||||
|
|
@ -2567,7 +2588,7 @@ ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
|
||||
if (rn == NULL || rn->query == NULL) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected response for %V", &name);
|
||||
"unexpected DNS response for %V", &name);
|
||||
ngx_resolver_free(r, name.data);
|
||||
goto failed;
|
||||
}
|
||||
|
|
@ -2581,7 +2602,7 @@ ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
|
||||
if (ident != qident) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"wrong ident %ui response for %V, expect %ui",
|
||||
"wrong ident %ui in DNS response for %V, expect %ui",
|
||||
ident, &name, qident);
|
||||
ngx_resolver_free(r, name.data);
|
||||
goto failed;
|
||||
|
|
@ -2691,7 +2712,7 @@ ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
|
||||
if (class != 1) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected RR class %ui", class);
|
||||
"unexpected RR class %ui in DNS response", class);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
|
@ -2734,7 +2755,7 @@ ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n,
|
|||
default:
|
||||
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected RR type %ui", type);
|
||||
"unexpected RR type %ui in DNS response", type);
|
||||
}
|
||||
|
||||
i += len;
|
||||
|
|
@ -3165,7 +3186,7 @@ valid:
|
|||
|
||||
if (rn == NULL || rn->query == NULL) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected response for %V", &name);
|
||||
"unexpected DNS response for %V", &name);
|
||||
ngx_resolver_free(r, name.data);
|
||||
goto failed;
|
||||
}
|
||||
|
|
@ -3174,7 +3195,7 @@ valid:
|
|||
|
||||
if (ident != qident) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"wrong ident %ui response for %V, expect %ui",
|
||||
"wrong ident %ui in DNS response for %V, expect %ui",
|
||||
ident, &name, qident);
|
||||
ngx_resolver_free(r, name.data);
|
||||
goto failed;
|
||||
|
|
@ -3256,7 +3277,7 @@ valid:
|
|||
|
||||
if (class != 1) {
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected RR class %ui", class);
|
||||
"unexpected RR class %ui in DNS response", class);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
|
@ -3283,7 +3304,7 @@ valid:
|
|||
default:
|
||||
|
||||
ngx_log_error(r->log_level, r->log, 0,
|
||||
"unexpected RR type %ui", type);
|
||||
"unexpected RR type %ui in DNS response", type);
|
||||
}
|
||||
|
||||
i += len;
|
||||
|
|
@ -3924,11 +3945,11 @@ ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src,
|
|||
{
|
||||
char *err;
|
||||
u_char *p, *dst;
|
||||
ssize_t len;
|
||||
size_t len;
|
||||
ngx_uint_t i, n;
|
||||
|
||||
p = src;
|
||||
len = -1;
|
||||
len = 0;
|
||||
|
||||
/*
|
||||
* compression pointers allow to create endless loop, so we set limit;
|
||||
|
|
@ -3943,6 +3964,16 @@ ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src,
|
|||
}
|
||||
|
||||
if (n & 0xc0) {
|
||||
if ((n & 0xc0) != 0xc0) {
|
||||
err = "invalid label type in DNS response";
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
if (p >= last) {
|
||||
err = "name is out of DNS response";
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
n = ((n & 0x3f) << 8) + *p;
|
||||
p = &buf[n];
|
||||
|
||||
|
|
@ -3952,12 +3983,12 @@ ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src,
|
|||
}
|
||||
|
||||
if (p >= last) {
|
||||
err = "name is out of response";
|
||||
err = "name is out of DNS response";
|
||||
goto invalid;
|
||||
}
|
||||
}
|
||||
|
||||
err = "compression pointers loop";
|
||||
err = "compression pointers loop in DNS response";
|
||||
|
||||
invalid:
|
||||
|
||||
|
|
@ -3971,7 +4002,7 @@ done:
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (len == -1) {
|
||||
if (len == 0) {
|
||||
ngx_str_null(name);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
@ -3983,30 +4014,23 @@ done:
|
|||
|
||||
name->data = dst;
|
||||
|
||||
n = *src++;
|
||||
|
||||
for ( ;; ) {
|
||||
n = *src++;
|
||||
|
||||
if (n == 0) {
|
||||
name->len = dst - name->data - 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (n & 0xc0) {
|
||||
n = ((n & 0x3f) << 8) + *src;
|
||||
src = &buf[n];
|
||||
|
||||
n = *src++;
|
||||
|
||||
} else {
|
||||
ngx_strlow(dst, src, n);
|
||||
dst += n;
|
||||
src += n;
|
||||
|
||||
n = *src++;
|
||||
|
||||
if (n != 0) {
|
||||
*dst++ = '.';
|
||||
}
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
name->len = dst - name->data;
|
||||
return NGX_OK;
|
||||
*dst++ = '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4444,6 +4468,8 @@ ngx_udp_connect(ngx_resolver_connection_t *rec)
|
|||
|
||||
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
||||
|
||||
c->start_time = ngx_current_msec;
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &rec->log, 0,
|
||||
"connect to %V, fd:%d #%uA", &rec->server, s, c->number);
|
||||
|
||||
|
|
@ -4530,6 +4556,8 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec)
|
|||
|
||||
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
||||
|
||||
c->start_time = ngx_current_msec;
|
||||
|
||||
if (ngx_add_conn) {
|
||||
if (ngx_add_conn(c) == NGX_ERROR) {
|
||||
goto failed;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
static u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64,
|
||||
u_char zero, ngx_uint_t hexadecimal, ngx_uint_t width);
|
||||
static u_char *ngx_sprintf_str(u_char *buf, u_char *last, u_char *src,
|
||||
size_t len, ngx_uint_t hexadecimal);
|
||||
static void ngx_encode_base64_internal(ngx_str_t *dst, ngx_str_t *src,
|
||||
const u_char *basis, ngx_uint_t padding);
|
||||
static ngx_int_t ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src,
|
||||
|
|
@ -101,10 +103,10 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
|
|||
* %M ngx_msec_t
|
||||
* %r rlim_t
|
||||
* %p void *
|
||||
* %V ngx_str_t *
|
||||
* %v ngx_variable_value_t *
|
||||
* %s null-terminated string
|
||||
* %*s length and string
|
||||
* %[x|X]V ngx_str_t *
|
||||
* %[x|X]v ngx_variable_value_t *
|
||||
* %[x|X]s null-terminated string
|
||||
* %*[x|X]s length and string
|
||||
* %Z '\0'
|
||||
* %N '\n'
|
||||
* %c char
|
||||
|
|
@ -165,7 +167,7 @@ ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args)
|
|||
u_char *p, zero;
|
||||
int d;
|
||||
double f;
|
||||
size_t len, slen;
|
||||
size_t slen;
|
||||
int64_t i64;
|
||||
uint64_t ui64, frac;
|
||||
ngx_msec_t ms;
|
||||
|
|
@ -250,8 +252,7 @@ ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args)
|
|||
case 'V':
|
||||
v = va_arg(args, ngx_str_t *);
|
||||
|
||||
len = ngx_min(((size_t) (last - buf)), v->len);
|
||||
buf = ngx_cpymem(buf, v->data, len);
|
||||
buf = ngx_sprintf_str(buf, last, v->data, v->len, hex);
|
||||
fmt++;
|
||||
|
||||
continue;
|
||||
|
|
@ -259,8 +260,7 @@ ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args)
|
|||
case 'v':
|
||||
vv = va_arg(args, ngx_variable_value_t *);
|
||||
|
||||
len = ngx_min(((size_t) (last - buf)), vv->len);
|
||||
buf = ngx_cpymem(buf, vv->data, len);
|
||||
buf = ngx_sprintf_str(buf, last, vv->data, vv->len, hex);
|
||||
fmt++;
|
||||
|
||||
continue;
|
||||
|
|
@ -268,16 +268,7 @@ ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args)
|
|||
case 's':
|
||||
p = va_arg(args, u_char *);
|
||||
|
||||
if (slen == (size_t) -1) {
|
||||
while (*p && buf < last) {
|
||||
*buf++ = *p++;
|
||||
}
|
||||
|
||||
} else {
|
||||
len = ngx_min(((size_t) (last - buf)), slen);
|
||||
buf = ngx_cpymem(buf, p, len);
|
||||
}
|
||||
|
||||
buf = ngx_sprintf_str(buf, last, p, slen, hex);
|
||||
fmt++;
|
||||
|
||||
continue;
|
||||
|
|
@ -576,6 +567,64 @@ ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, u_char zero,
|
|||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_sprintf_str(u_char *buf, u_char *last, u_char *src, size_t len,
|
||||
ngx_uint_t hexadecimal)
|
||||
{
|
||||
static u_char hex[] = "0123456789abcdef";
|
||||
static u_char HEX[] = "0123456789ABCDEF";
|
||||
|
||||
if (hexadecimal == 0) {
|
||||
|
||||
if (len == (size_t) -1) {
|
||||
while (*src && buf < last) {
|
||||
*buf++ = *src++;
|
||||
}
|
||||
|
||||
} else {
|
||||
len = ngx_min((size_t) (last - buf), len);
|
||||
buf = ngx_cpymem(buf, src, len);
|
||||
}
|
||||
|
||||
} else if (hexadecimal == 1) {
|
||||
|
||||
if (len == (size_t) -1) {
|
||||
|
||||
while (*src && buf < last - 1) {
|
||||
*buf++ = hex[*src >> 4];
|
||||
*buf++ = hex[*src++ & 0xf];
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
while (len-- && buf < last - 1) {
|
||||
*buf++ = hex[*src >> 4];
|
||||
*buf++ = hex[*src++ & 0xf];
|
||||
}
|
||||
}
|
||||
|
||||
} else { /* hexadecimal == 2 */
|
||||
|
||||
if (len == (size_t) -1) {
|
||||
|
||||
while (*src && buf < last - 1) {
|
||||
*buf++ = HEX[*src >> 4];
|
||||
*buf++ = HEX[*src++ & 0xf];
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
while (len-- && buf < last - 1) {
|
||||
*buf++ = HEX[*src >> 4];
|
||||
*buf++ = HEX[*src++ & 0xf];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only,
|
||||
* and implement our own ngx_strcasecmp()/ngx_strncasecmp()
|
||||
|
|
|
|||
|
|
@ -399,7 +399,7 @@ ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (ev->active) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"eventport del event: fd:%d", c->fd);
|
||||
|
||||
|
|
|
|||
|
|
@ -257,9 +257,7 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
|
|||
ngx_shmtx_unlock(&ngx_accept_mutex);
|
||||
}
|
||||
|
||||
if (delta) {
|
||||
ngx_event_expire_timers();
|
||||
}
|
||||
ngx_event_expire_timers();
|
||||
|
||||
ngx_event_process_posted(cycle, &ngx_posted_events);
|
||||
}
|
||||
|
|
@ -318,7 +316,7 @@ ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rev->oneshot && !rev->ready) {
|
||||
if (rev->oneshot && rev->ready) {
|
||||
if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,6 +256,8 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
|
||||
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
||||
|
||||
c->start_time = ngx_current_msec;
|
||||
|
||||
#if (NGX_STAT_STUB)
|
||||
(void) ngx_atomic_fetch_add(ngx_stat_handled, 1);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -193,6 +193,8 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||
|
||||
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
||||
|
||||
c->start_time = ngx_current_msec;
|
||||
|
||||
if (ngx_add_conn) {
|
||||
if (ngx_add_conn(c) == NGX_ERROR) {
|
||||
goto failed;
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ static time_t ngx_ssl_parse_time(
|
|||
#if OPENSSL_VERSION_NUMBER > 0x10100000L
|
||||
const
|
||||
#endif
|
||||
ASN1_TIME *asn1time);
|
||||
ASN1_TIME *asn1time, ngx_log_t *log);
|
||||
|
||||
static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
|
||||
static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
|
@ -130,6 +130,7 @@ int ngx_ssl_connection_index;
|
|||
int ngx_ssl_server_conf_index;
|
||||
int ngx_ssl_session_cache_index;
|
||||
int ngx_ssl_session_ticket_keys_index;
|
||||
int ngx_ssl_ocsp_index;
|
||||
int ngx_ssl_certificate_index;
|
||||
int ngx_ssl_next_certificate_index;
|
||||
int ngx_ssl_certificate_name_index;
|
||||
|
|
@ -213,6 +214,13 @@ ngx_ssl_init(ngx_log_t *log)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_ssl_ocsp_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
|
||||
if (ngx_ssl_ocsp_index == -1) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0,
|
||||
"SSL_CTX_get_ex_new_index() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
|
||||
NULL);
|
||||
if (ngx_ssl_certificate_index == -1) {
|
||||
|
|
@ -370,6 +378,10 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
|
|||
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_CLIENT_RENEGOTIATION);
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
|
||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
|
||||
#endif
|
||||
|
||||
#ifdef SSL_MODE_RELEASE_BUFFERS
|
||||
SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||
#endif
|
||||
|
|
@ -912,6 +924,9 @@ ngx_int_t
|
|||
ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
||||
ngx_int_t depth)
|
||||
{
|
||||
SSL_CTX_set_verify(ssl->ctx, SSL_CTX_get_verify_mode(ssl->ctx),
|
||||
ngx_ssl_verify_callback);
|
||||
|
||||
SSL_CTX_set_verify_depth(ssl->ctx, depth);
|
||||
|
||||
if (cert->len == 0) {
|
||||
|
|
@ -1003,26 +1018,52 @@ ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
|
|||
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
|
||||
if (!(c->log->log_level & NGX_LOG_DEBUG_EVENT)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
cert = X509_STORE_CTX_get_current_cert(x509_store);
|
||||
err = X509_STORE_CTX_get_error(x509_store);
|
||||
depth = X509_STORE_CTX_get_error_depth(x509_store);
|
||||
|
||||
sname = X509_get_subject_name(cert);
|
||||
subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)";
|
||||
|
||||
if (sname) {
|
||||
subject = X509_NAME_oneline(sname, NULL, 0);
|
||||
if (subject == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
||||
"X509_NAME_oneline() failed");
|
||||
}
|
||||
|
||||
} else {
|
||||
subject = NULL;
|
||||
}
|
||||
|
||||
iname = X509_get_issuer_name(cert);
|
||||
issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)";
|
||||
|
||||
if (iname) {
|
||||
issuer = X509_NAME_oneline(iname, NULL, 0);
|
||||
if (issuer == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
||||
"X509_NAME_oneline() failed");
|
||||
}
|
||||
|
||||
} else {
|
||||
issuer = NULL;
|
||||
}
|
||||
|
||||
ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"verify:%d, error:%d, depth:%d, "
|
||||
"subject:\"%s\", issuer:\"%s\"",
|
||||
ok, err, depth, subject, issuer);
|
||||
ok, err, depth,
|
||||
subject ? subject : "(none)",
|
||||
issuer ? issuer : "(none)");
|
||||
|
||||
if (sname) {
|
||||
if (subject) {
|
||||
OPENSSL_free(subject);
|
||||
}
|
||||
|
||||
if (iname) {
|
||||
if (issuer) {
|
||||
OPENSSL_free(issuer);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1079,6 +1120,8 @@ ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
|
|||
}
|
||||
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER)
|
||||
|
||||
RSA *
|
||||
ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
|
||||
int key_length)
|
||||
|
|
@ -1089,7 +1132,7 @@ ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100003L && !defined OPENSSL_NO_DEPRECATED)
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
|
||||
if (key == NULL) {
|
||||
key = RSA_generate_key(512, RSA_F4, NULL, NULL);
|
||||
|
|
@ -1100,6 +1143,8 @@ ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
|
|||
return key;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
ngx_array_t *
|
||||
ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file)
|
||||
|
|
@ -1313,7 +1358,6 @@ ngx_ssl_passwords_cleanup(void *data)
|
|||
ngx_int_t
|
||||
ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
|
||||
{
|
||||
DH *dh;
|
||||
BIO *bio;
|
||||
|
||||
if (file->len == 0) {
|
||||
|
|
@ -1331,6 +1375,10 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
#ifdef SSL_CTX_set_tmp_dh
|
||||
{
|
||||
DH *dh;
|
||||
|
||||
dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
|
||||
if (dh == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
|
|
@ -1339,9 +1387,42 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
SSL_CTX_set_tmp_dh(ssl->ctx, dh);
|
||||
if (SSL_CTX_set_tmp_dh(ssl->ctx, dh) != 1) {
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
"SSL_CTX_set_tmp_dh(\"%s\") failed", file->data);
|
||||
DH_free(dh);
|
||||
BIO_free(bio);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
DH_free(dh);
|
||||
}
|
||||
#else
|
||||
{
|
||||
EVP_PKEY *dh;
|
||||
|
||||
/*
|
||||
* PEM_read_bio_DHparams() and SSL_CTX_set_tmp_dh()
|
||||
* are deprecated in OpenSSL 3.0
|
||||
*/
|
||||
|
||||
dh = PEM_read_bio_Parameters(bio, NULL);
|
||||
if (dh == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
"PEM_read_bio_Parameters(\"%s\") failed", file->data);
|
||||
BIO_free(bio);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (SSL_CTX_set0_tmp_dh_pkey(ssl->ctx, dh) != 1) {
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
"SSL_CTX_set0_tmp_dh_pkey(\%s\") failed", file->data);
|
||||
BIO_free(bio);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BIO_free(bio);
|
||||
|
||||
return NGX_OK;
|
||||
|
|
@ -1459,6 +1540,78 @@ ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable)
|
|||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_ssl_conf_commands(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *commands)
|
||||
{
|
||||
if (commands == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#ifdef SSL_CONF_FLAG_FILE
|
||||
{
|
||||
int type;
|
||||
u_char *key, *value;
|
||||
ngx_uint_t i;
|
||||
ngx_keyval_t *cmd;
|
||||
SSL_CONF_CTX *cctx;
|
||||
|
||||
cctx = SSL_CONF_CTX_new();
|
||||
if (cctx == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
"SSL_CONF_CTX_new() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
|
||||
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
|
||||
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
|
||||
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
|
||||
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SHOW_ERRORS);
|
||||
|
||||
SSL_CONF_CTX_set_ssl_ctx(cctx, ssl->ctx);
|
||||
|
||||
cmd = commands->elts;
|
||||
for (i = 0; i < commands->nelts; i++) {
|
||||
|
||||
key = cmd[i].key.data;
|
||||
type = SSL_CONF_cmd_value_type(cctx, (char *) key);
|
||||
|
||||
if (type == SSL_CONF_TYPE_FILE || type == SSL_CONF_TYPE_DIR) {
|
||||
if (ngx_conf_full_name(cf->cycle, &cmd[i].value, 1) != NGX_OK) {
|
||||
SSL_CONF_CTX_free(cctx);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
value = cmd[i].value.data;
|
||||
|
||||
if (SSL_CONF_cmd(cctx, (char *) key, (char *) value) <= 0) {
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
"SSL_CONF_cmd(\"%s\", \"%s\") failed", key, value);
|
||||
SSL_CONF_CTX_free(cctx);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (SSL_CONF_CTX_finish(cctx) != 1) {
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
"SSL_CONF_finish() failed");
|
||||
SSL_CONF_CTX_free(cctx);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
SSL_CONF_CTX_free(cctx);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
#else
|
||||
ngx_log_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
"SSL_CONF_cmd() is not available on this platform");
|
||||
return NGX_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_ssl_client_session_cache(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable)
|
||||
{
|
||||
|
|
@ -1594,6 +1747,7 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|||
{
|
||||
int n, sslerr;
|
||||
ngx_err_t err;
|
||||
ngx_int_t rc;
|
||||
|
||||
#ifdef SSL_READ_EARLY_DATA_SUCCESS
|
||||
if (c->ssl->try_early_data) {
|
||||
|
|
@ -1601,6 +1755,10 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (c->ssl->in_ocsp) {
|
||||
return ngx_ssl_ocsp_validate(c);
|
||||
}
|
||||
|
||||
ngx_ssl_clear_error(c->log);
|
||||
|
||||
n = SSL_do_handshake(c->ssl->connection);
|
||||
|
|
@ -1621,13 +1779,14 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|||
ngx_ssl_handshake_log(c);
|
||||
#endif
|
||||
|
||||
c->ssl->handshaked = 1;
|
||||
|
||||
c->recv = ngx_ssl_recv;
|
||||
c->send = ngx_ssl_write;
|
||||
c->recv_chain = ngx_ssl_recv_chain;
|
||||
c->send_chain = ngx_ssl_send_chain;
|
||||
|
||||
c->read->ready = 1;
|
||||
c->write->ready = 1;
|
||||
|
||||
#ifndef SSL_OP_NO_RENEGOTIATION
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
|
||||
|
|
@ -1641,6 +1800,20 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
rc = ngx_ssl_ocsp_validate(c);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
c->read->handler = ngx_ssl_handshake_handler;
|
||||
c->write->handler = ngx_ssl_handshake_handler;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
c->ssl->handshaked = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1693,6 +1866,13 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (c->ssl->handshake_rejected) {
|
||||
ngx_connection_error(c, err, "handshake rejected");
|
||||
ERR_clear_error();
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
c->read->error = 1;
|
||||
|
||||
ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed");
|
||||
|
|
@ -1710,6 +1890,7 @@ ngx_ssl_try_early_data(ngx_connection_t *c)
|
|||
u_char buf;
|
||||
size_t readbytes;
|
||||
ngx_err_t err;
|
||||
ngx_int_t rc;
|
||||
|
||||
ngx_ssl_clear_error(c->log);
|
||||
|
||||
|
|
@ -1744,7 +1925,6 @@ ngx_ssl_try_early_data(ngx_connection_t *c)
|
|||
c->ssl->early_buf = buf;
|
||||
c->ssl->early_preread = 1;
|
||||
|
||||
c->ssl->handshaked = 1;
|
||||
c->ssl->in_early = 1;
|
||||
|
||||
c->recv = ngx_ssl_recv;
|
||||
|
|
@ -1752,6 +1932,23 @@ ngx_ssl_try_early_data(ngx_connection_t *c)
|
|||
c->recv_chain = ngx_ssl_recv_chain;
|
||||
c->send_chain = ngx_ssl_send_chain;
|
||||
|
||||
c->read->ready = 1;
|
||||
c->write->ready = 1;
|
||||
|
||||
rc = ngx_ssl_ocsp_validate(c);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
c->read->handler = ngx_ssl_handshake_handler;
|
||||
c->write->handler = ngx_ssl_handshake_handler;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
c->ssl->handshaked = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1827,6 +2024,10 @@ ngx_ssl_handshake_log(ngx_connection_t *c)
|
|||
#endif
|
||||
SSL_CIPHER *cipher;
|
||||
|
||||
if (!(c->log->log_level & NGX_LOG_DEBUG_EVENT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
cipher = SSL_get_current_cipher(c->ssl->connection);
|
||||
|
||||
if (cipher) {
|
||||
|
|
@ -2531,6 +2732,18 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
|
|||
|
||||
sslerr = SSL_get_error(c->ssl->connection, n);
|
||||
|
||||
if (sslerr == SSL_ERROR_ZERO_RETURN) {
|
||||
|
||||
/*
|
||||
* OpenSSL 1.1.1 fails to return SSL_ERROR_SYSCALL if an error
|
||||
* happens during SSL_write() after close_notify alert from the
|
||||
* peer, and returns SSL_ERROR_ZERO_RETURN instead,
|
||||
* https://git.openssl.org/?p=openssl.git;a=commitdiff;h=8051ab2
|
||||
*/
|
||||
|
||||
sslerr = SSL_ERROR_SYSCALL;
|
||||
}
|
||||
|
||||
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
|
||||
|
|
@ -2732,8 +2945,14 @@ ngx_ssl_free_buffer(ngx_connection_t *c)
|
|||
ngx_int_t
|
||||
ngx_ssl_shutdown(ngx_connection_t *c)
|
||||
{
|
||||
int n, sslerr, mode;
|
||||
ngx_err_t err;
|
||||
int n, sslerr, mode;
|
||||
ngx_int_t rc;
|
||||
ngx_err_t err;
|
||||
ngx_uint_t tries;
|
||||
|
||||
rc = NGX_OK;
|
||||
|
||||
ngx_ssl_ocsp_cleanup(c);
|
||||
|
||||
if (SSL_in_init(c->ssl->connection)) {
|
||||
/*
|
||||
|
|
@ -2742,13 +2961,10 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|||
* Avoid calling SSL_shutdown() if handshake wasn't completed.
|
||||
*/
|
||||
|
||||
SSL_free(c->ssl->connection);
|
||||
c->ssl = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (c->timedout) {
|
||||
if (c->timedout || c->error || c->buffered) {
|
||||
mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
|
||||
SSL_set_quiet_shutdown(c->ssl->connection, 1);
|
||||
|
||||
|
|
@ -2772,55 +2988,87 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|||
|
||||
ngx_ssl_clear_error(c->log);
|
||||
|
||||
n = SSL_shutdown(c->ssl->connection);
|
||||
tries = 2;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
|
||||
for ( ;; ) {
|
||||
|
||||
sslerr = 0;
|
||||
/*
|
||||
* For bidirectional shutdown, SSL_shutdown() needs to be called
|
||||
* twice: first call sends the "close notify" alert and returns 0,
|
||||
* second call waits for the peer's "close notify" alert.
|
||||
*/
|
||||
|
||||
/* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */
|
||||
n = SSL_shutdown(c->ssl->connection);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
|
||||
|
||||
if (n == 1) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (n == 0 && tries-- > 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */
|
||||
|
||||
if (n != 1 && ERR_peek_error()) {
|
||||
sslerr = SSL_get_error(c->ssl->connection, n);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"SSL_get_error: %d", sslerr);
|
||||
}
|
||||
|
||||
if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) {
|
||||
SSL_free(c->ssl->connection);
|
||||
c->ssl = NULL;
|
||||
if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
|
||||
c->read->handler = ngx_ssl_shutdown_handler;
|
||||
c->write->handler = ngx_ssl_shutdown_handler;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
if (sslerr == SSL_ERROR_WANT_READ) {
|
||||
c->read->ready = 0;
|
||||
|
||||
if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
|
||||
c->read->handler = ngx_ssl_shutdown_handler;
|
||||
c->write->handler = ngx_ssl_shutdown_handler;
|
||||
} else {
|
||||
c->write->ready = 0;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ngx_add_timer(c->read, 3000);
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (sslerr == SSL_ERROR_WANT_READ) {
|
||||
ngx_add_timer(c->read, 30000);
|
||||
}
|
||||
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
||||
|
||||
return NGX_AGAIN;
|
||||
ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
||||
failed:
|
||||
|
||||
ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
|
||||
rc = NGX_ERROR;
|
||||
|
||||
done:
|
||||
|
||||
if (c->ssl->shutdown_without_free) {
|
||||
c->ssl->shutdown_without_free = 0;
|
||||
c->recv = ngx_recv;
|
||||
return rc;
|
||||
}
|
||||
|
||||
SSL_free(c->ssl->connection);
|
||||
c->ssl = NULL;
|
||||
c->recv = ngx_recv;
|
||||
|
||||
return NGX_ERROR;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3036,7 +3284,7 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
|
|||
|
||||
for ( ;; ) {
|
||||
|
||||
n = ERR_peek_error_line_data(NULL, NULL, &data, &flags);
|
||||
n = ERR_peek_error_data(&data, &flags);
|
||||
|
||||
if (n == 0) {
|
||||
break;
|
||||
|
|
@ -3202,8 +3450,9 @@ ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
if (SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index) == NULL) {
|
||||
|
||||
if (SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index) == NULL
|
||||
&& certificates != NULL)
|
||||
{
|
||||
/*
|
||||
* If certificates are loaded dynamically, we use certificate
|
||||
* names as specified in the configuration (with variables).
|
||||
|
|
@ -3897,9 +4146,6 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
|||
ngx_ssl_session_ticket_key_t *key;
|
||||
const EVP_MD *digest;
|
||||
const EVP_CIPHER *cipher;
|
||||
#if (NGX_DEBUG)
|
||||
u_char buf[32];
|
||||
#endif
|
||||
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
ssl_ctx = c->ssl->session_ctx;
|
||||
|
|
@ -3921,8 +4167,8 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
|||
/* encrypt session ticket */
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl session ticket encrypt, key: \"%*s\" (%s session)",
|
||||
ngx_hex_dump(buf, key[0].name, 16) - buf, buf,
|
||||
"ssl session ticket encrypt, key: \"%*xs\" (%s session)",
|
||||
(size_t) 16, key[0].name,
|
||||
SSL_session_reused(ssl_conn) ? "reused" : "new");
|
||||
|
||||
if (key[0].size == 48) {
|
||||
|
|
@ -3968,17 +4214,16 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
|||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl session ticket decrypt, key: \"%*s\" not found",
|
||||
ngx_hex_dump(buf, name, 16) - buf, buf);
|
||||
"ssl session ticket decrypt, key: \"%*xs\" not found",
|
||||
(size_t) 16, name);
|
||||
|
||||
return 0;
|
||||
|
||||
found:
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl session ticket decrypt, key: \"%*s\"%s",
|
||||
ngx_hex_dump(buf, key[i].name, 16) - buf, buf,
|
||||
(i == 0) ? " (default)" : "");
|
||||
"ssl session ticket decrypt, key: \"%*xs\"%s",
|
||||
(size_t) 16, key[i].name, (i == 0) ? " (default)" : "");
|
||||
|
||||
if (key[i].size == 48) {
|
||||
cipher = EVP_aes_128_cbc();
|
||||
|
|
@ -4635,11 +4880,13 @@ ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
|
@ -4687,11 +4934,13 @@ ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
|
@ -4740,6 +4989,11 @@ ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
|
|||
}
|
||||
|
||||
p = X509_NAME_oneline(name, NULL, 0);
|
||||
if (p == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (len = 0; p[len]; len++) { /* void */ }
|
||||
|
||||
|
|
@ -4783,6 +5037,11 @@ ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
|
|||
}
|
||||
|
||||
p = X509_NAME_oneline(name, NULL, 0);
|
||||
if (p == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (len = 0; p[len]; len++) { /* void */ }
|
||||
|
||||
|
|
@ -4819,6 +5078,7 @@ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
@ -4857,6 +5117,7 @@ ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|||
}
|
||||
|
||||
if (!X509_digest(cert, EVP_sha1(), buf, &len)) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_digest() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
@ -4894,11 +5155,14 @@ ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|||
rc = SSL_get_verify_result(c->ssl->connection);
|
||||
|
||||
if (rc == X509_V_OK) {
|
||||
ngx_str_set(s, "SUCCESS");
|
||||
return NGX_OK;
|
||||
}
|
||||
if (ngx_ssl_ocsp_get_status(c, &str) == NGX_OK) {
|
||||
ngx_str_set(s, "SUCCESS");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
str = X509_verify_cert_error_string(rc);
|
||||
} else {
|
||||
str = X509_verify_cert_error_string(rc);
|
||||
}
|
||||
|
||||
s->data = ngx_pnalloc(pool, sizeof("FAILED:") - 1 + ngx_strlen(str));
|
||||
if (s->data == NULL) {
|
||||
|
|
@ -4927,6 +5191,7 @@ ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
@ -4971,6 +5236,7 @@ ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
@ -5013,9 +5279,9 @@ ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
|||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER > 0x10100000L
|
||||
end = ngx_ssl_parse_time(X509_get0_notAfter(cert));
|
||||
end = ngx_ssl_parse_time(X509_get0_notAfter(cert), c->log);
|
||||
#else
|
||||
end = ngx_ssl_parse_time(X509_get_notAfter(cert));
|
||||
end = ngx_ssl_parse_time(X509_get_notAfter(cert), c->log);
|
||||
#endif
|
||||
|
||||
if (end == (time_t) NGX_ERROR) {
|
||||
|
|
@ -5050,7 +5316,7 @@ ngx_ssl_parse_time(
|
|||
#if OPENSSL_VERSION_NUMBER > 0x10100000L
|
||||
const
|
||||
#endif
|
||||
ASN1_TIME *asn1time)
|
||||
ASN1_TIME *asn1time, ngx_log_t *log)
|
||||
{
|
||||
BIO *bio;
|
||||
char *value;
|
||||
|
|
@ -5066,6 +5332,7 @@ ngx_ssl_parse_time(
|
|||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "BIO_new() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
|
|
@ -64,6 +66,19 @@
|
|||
#endif
|
||||
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined SSL_get_peer_certificate)
|
||||
#define SSL_get_peer_certificate(s) SSL_get1_peer_certificate(s)
|
||||
#endif
|
||||
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x30000000L && !defined ERR_peek_error_data)
|
||||
#define ERR_peek_error_data(d, f) ERR_peek_error_line_data(NULL, NULL, d, f)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;
|
||||
|
||||
|
||||
struct ngx_ssl_s {
|
||||
SSL_CTX *ctx;
|
||||
ngx_log_t *log;
|
||||
|
|
@ -87,16 +102,21 @@ struct ngx_ssl_connection_s {
|
|||
ngx_event_handler_pt saved_read_handler;
|
||||
ngx_event_handler_pt saved_write_handler;
|
||||
|
||||
ngx_ssl_ocsp_t *ocsp;
|
||||
|
||||
u_char early_buf;
|
||||
|
||||
unsigned handshaked:1;
|
||||
unsigned handshake_rejected:1;
|
||||
unsigned renegotiation:1;
|
||||
unsigned buffer:1;
|
||||
unsigned no_wait_shutdown:1;
|
||||
unsigned no_send_shutdown:1;
|
||||
unsigned shutdown_without_free:1;
|
||||
unsigned handshake_buffer_set:1;
|
||||
unsigned try_early_data:1;
|
||||
unsigned in_early:1;
|
||||
unsigned in_ocsp:1;
|
||||
unsigned early_preread:1;
|
||||
unsigned write_blocked:1;
|
||||
};
|
||||
|
|
@ -180,8 +200,18 @@ ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
|||
ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify);
|
||||
ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||
ngx_resolver_t *resolver, ngx_msec_t resolver_timeout);
|
||||
ngx_int_t ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder,
|
||||
ngx_uint_t depth, ngx_shm_zone_t *shm_zone);
|
||||
ngx_int_t ngx_ssl_ocsp_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||
ngx_resolver_t *resolver, ngx_msec_t resolver_timeout);
|
||||
ngx_int_t ngx_ssl_ocsp_validate(ngx_connection_t *c);
|
||||
ngx_int_t ngx_ssl_ocsp_get_status(ngx_connection_t *c, const char **s);
|
||||
void ngx_ssl_ocsp_cleanup(ngx_connection_t *c);
|
||||
ngx_int_t ngx_ssl_ocsp_cache_init(ngx_shm_zone_t *shm_zone, void *data);
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER)
|
||||
RSA *ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
|
||||
int key_length);
|
||||
#endif
|
||||
ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file);
|
||||
ngx_array_t *ngx_ssl_preserve_passwords(ngx_conf_t *cf,
|
||||
ngx_array_t *passwords);
|
||||
|
|
@ -189,6 +219,9 @@ ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
|
|||
ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
|
||||
ngx_int_t ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||
ngx_uint_t enable);
|
||||
ngx_int_t ngx_ssl_conf_commands(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||
ngx_array_t *commands);
|
||||
|
||||
ngx_int_t ngx_ssl_client_session_cache(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||
ngx_uint_t enable);
|
||||
ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
|
||||
|
|
@ -197,6 +230,7 @@ ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
|
|||
ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||
ngx_array_t *paths);
|
||||
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
|
||||
|
||||
ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
|
||||
ngx_uint_t flags);
|
||||
|
||||
|
|
@ -281,6 +315,7 @@ extern int ngx_ssl_connection_index;
|
|||
extern int ngx_ssl_server_conf_index;
|
||||
extern int ngx_ssl_session_cache_index;
|
||||
extern int ngx_ssl_session_ticket_keys_index;
|
||||
extern int ngx_ssl_ocsp_index;
|
||||
extern int ngx_ssl_certificate_index;
|
||||
extern int ngx_ssl_next_certificate_index;
|
||||
extern int ngx_ssl_certificate_name_index;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -960,6 +960,22 @@ ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (p->upstream_done) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
|
||||
"input data after close");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (p->length == 0) {
|
||||
p->upstream_done = 1;
|
||||
|
||||
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||
"upstream sent more data than specified in "
|
||||
"\"Content-Length\" header");
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
cl = ngx_chain_get_free_buf(p->pool, &p->free);
|
||||
if (cl == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
@ -987,6 +1003,18 @@ ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (b->last - b->pos > p->length) {
|
||||
|
||||
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||
"upstream sent more data than specified in "
|
||||
"\"Content-Length\" header");
|
||||
|
||||
b->last = b->pos + p->length;
|
||||
p->upstream_done = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
p->length -= b->last - b->pos;
|
||||
|
||||
return NGX_OK;
|
||||
|
|
|
|||
|
|
@ -363,6 +363,8 @@ ngx_event_recvmsg(ngx_event_t *ev)
|
|||
|
||||
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
||||
|
||||
c->start_time = ngx_current_msec;
|
||||
|
||||
#if (NGX_STAT_STUB)
|
||||
(void) ngx_atomic_fetch_add(ngx_stat_handled, 1);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -81,12 +81,15 @@ typedef struct {
|
|||
size_t length;
|
||||
size_t padding;
|
||||
|
||||
off_t rest;
|
||||
|
||||
ngx_chain_t *free;
|
||||
ngx_chain_t *busy;
|
||||
|
||||
unsigned fastcgi_stdout:1;
|
||||
unsigned large_stderr:1;
|
||||
unsigned header_sent:1;
|
||||
unsigned closed:1;
|
||||
|
||||
ngx_array_t *split_parts;
|
||||
|
||||
|
|
@ -2075,13 +2078,31 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||
static ngx_int_t
|
||||
ngx_http_fastcgi_input_filter_init(void *data)
|
||||
{
|
||||
ngx_http_request_t *r = data;
|
||||
ngx_http_request_t *r = data;
|
||||
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_http_fastcgi_ctx_t *f;
|
||||
ngx_http_fastcgi_loc_conf_t *flcf;
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
|
||||
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
|
||||
|
||||
r->upstream->pipe->length = flcf->keep_conn ?
|
||||
(off_t) sizeof(ngx_http_fastcgi_header_t) : -1;
|
||||
u->pipe->length = flcf->keep_conn ?
|
||||
(off_t) sizeof(ngx_http_fastcgi_header_t) : -1;
|
||||
|
||||
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
|
||||
|| u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED)
|
||||
{
|
||||
f->rest = 0;
|
||||
|
||||
} else if (r->method == NGX_HTTP_HEAD) {
|
||||
f->rest = -2;
|
||||
|
||||
} else {
|
||||
f->rest = u->headers_in.content_length_n;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
@ -2106,6 +2127,15 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
|
||||
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
|
||||
|
||||
if (p->upstream_done || f->closed) {
|
||||
r->upstream->keepalive = 0;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||
"http fastcgi data after close");
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
b = NULL;
|
||||
prev = &buf->shadow;
|
||||
|
||||
|
|
@ -2128,13 +2158,25 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
|
||||
f->state = ngx_http_fastcgi_st_padding;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||
"http fastcgi closed stdout");
|
||||
|
||||
if (f->rest > 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, p->log, 0,
|
||||
"upstream prematurely closed "
|
||||
"FastCGI stdout");
|
||||
|
||||
p->upstream_error = 1;
|
||||
p->upstream_eof = 0;
|
||||
f->closed = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!flcf->keep_conn) {
|
||||
p->upstream_done = 1;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||
"http fastcgi closed stdout");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2143,6 +2185,18 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||
"http fastcgi sent end request");
|
||||
|
||||
if (f->rest > 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, p->log, 0,
|
||||
"upstream prematurely closed "
|
||||
"FastCGI request");
|
||||
|
||||
p->upstream_error = 1;
|
||||
p->upstream_eof = 0;
|
||||
f->closed = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!flcf->keep_conn) {
|
||||
p->upstream_done = 1;
|
||||
break;
|
||||
|
|
@ -2252,6 +2306,18 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
break;
|
||||
}
|
||||
|
||||
if (f->rest == -2) {
|
||||
f->rest = r->upstream->headers_in.content_length_n;
|
||||
}
|
||||
|
||||
if (f->rest == 0) {
|
||||
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||
"upstream sent more data than specified in "
|
||||
"\"Content-Length\" header");
|
||||
p->upstream_done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
cl = ngx_chain_get_free_buf(p->pool, &p->free);
|
||||
if (cl == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
@ -2289,15 +2355,27 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||
f->pos += f->length;
|
||||
b->last = f->pos;
|
||||
|
||||
continue;
|
||||
} else {
|
||||
f->length -= f->last - f->pos;
|
||||
f->pos = f->last;
|
||||
b->last = f->last;
|
||||
}
|
||||
|
||||
f->length -= f->last - f->pos;
|
||||
if (f->rest > 0) {
|
||||
|
||||
b->last = f->last;
|
||||
if (b->last - b->pos > f->rest) {
|
||||
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||
"upstream sent more data than specified in "
|
||||
"\"Content-Length\" header");
|
||||
|
||||
break;
|
||||
b->last = b->pos + f->rest;
|
||||
p->upstream_done = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
f->rest -= b->last - b->pos;
|
||||
}
|
||||
}
|
||||
|
||||
if (flcf->keep_conn) {
|
||||
|
|
@ -2391,6 +2469,14 @@ ngx_http_fastcgi_non_buffered_filter(void *data, ssize_t bytes)
|
|||
|
||||
if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
|
||||
|
||||
if (f->rest > 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream prematurely closed "
|
||||
"FastCGI request");
|
||||
u->error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (f->pos + f->padding < f->last) {
|
||||
u->length = 0;
|
||||
break;
|
||||
|
|
@ -2486,6 +2572,14 @@ ngx_http_fastcgi_non_buffered_filter(void *data, ssize_t bytes)
|
|||
break;
|
||||
}
|
||||
|
||||
if (f->rest == 0) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent more data than specified in "
|
||||
"\"Content-Length\" header");
|
||||
u->length = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
|
||||
if (cl == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
@ -2510,13 +2604,27 @@ ngx_http_fastcgi_non_buffered_filter(void *data, ssize_t bytes)
|
|||
f->pos += f->length;
|
||||
b->last = f->pos;
|
||||
|
||||
continue;
|
||||
} else {
|
||||
f->length -= f->last - f->pos;
|
||||
f->pos = f->last;
|
||||
b->last = f->last;
|
||||
}
|
||||
|
||||
f->length -= f->last - f->pos;
|
||||
b->last = f->last;
|
||||
if (f->rest > 0) {
|
||||
|
||||
break;
|
||||
if (b->last - b->pos > f->rest) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent more data than specified in "
|
||||
"\"Content-Length\" header");
|
||||
|
||||
b->last = b->pos + f->rest;
|
||||
u->length = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
f->rest -= b->last - b->pos;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
|
|
|||
|
|
@ -156,12 +156,6 @@ ngx_http_flv_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
if (!of.is_file) {
|
||||
|
||||
if (ngx_close_file(of.fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
||||
ngx_close_file_n " \"%s\" failed", path.data);
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ typedef struct {
|
|||
ngx_str_t ssl_certificate;
|
||||
ngx_str_t ssl_certificate_key;
|
||||
ngx_array_t *ssl_passwords;
|
||||
ngx_array_t *ssl_conf_commands;
|
||||
#endif
|
||||
} ngx_http_grpc_loc_conf_t;
|
||||
|
||||
|
|
@ -84,6 +85,8 @@ typedef struct {
|
|||
ngx_uint_t pings;
|
||||
ngx_uint_t settings;
|
||||
|
||||
off_t length;
|
||||
|
||||
ssize_t send_window;
|
||||
size_t recv_window;
|
||||
|
||||
|
|
@ -120,6 +123,8 @@ typedef struct {
|
|||
unsigned end_stream:1;
|
||||
unsigned done:1;
|
||||
unsigned status:1;
|
||||
unsigned rst:1;
|
||||
unsigned goaway:1;
|
||||
|
||||
ngx_http_request_t *request;
|
||||
|
||||
|
|
@ -205,6 +210,8 @@ static char *ngx_http_grpc_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
#if (NGX_HTTP_SSL)
|
||||
static char *ngx_http_grpc_ssl_password_file(ngx_conf_t *cf,
|
||||
ngx_command_t *cmd, void *conf);
|
||||
static char *ngx_http_grpc_ssl_conf_command_check(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
static ngx_int_t ngx_http_grpc_set_ssl(ngx_conf_t *cf,
|
||||
ngx_http_grpc_loc_conf_t *glcf);
|
||||
#endif
|
||||
|
|
@ -239,6 +246,9 @@ static ngx_conf_bitmask_t ngx_http_grpc_ssl_protocols[] = {
|
|||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
static ngx_conf_post_t ngx_http_grpc_ssl_conf_command_post =
|
||||
{ ngx_http_grpc_ssl_conf_command_check };
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -435,6 +445,13 @@ static ngx_command_t ngx_http_grpc_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("grpc_ssl_conf_command"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
|
||||
ngx_conf_set_keyval_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_grpc_loc_conf_t, ssl_conf_commands),
|
||||
&ngx_http_grpc_ssl_conf_command_post },
|
||||
|
||||
#endif
|
||||
|
||||
ngx_null_command
|
||||
|
|
@ -1125,20 +1142,11 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
|
|||
|
||||
f->flags |= NGX_HTTP_V2_END_HEADERS_FLAG;
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
if (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP) {
|
||||
u_char buf[512];
|
||||
size_t n, m;
|
||||
|
||||
n = ngx_min(b->last - b->pos, 256);
|
||||
m = ngx_hex_dump(buf, b->pos, n) - buf;
|
||||
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"grpc header: %*s%s, len: %uz",
|
||||
m, buf, b->last - b->pos > 256 ? "..." : "",
|
||||
b->last - b->pos);
|
||||
}
|
||||
#endif
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"grpc header: %*xs%s, len: %uz",
|
||||
(size_t) ngx_min(b->last - b->pos, 256), b->pos,
|
||||
b->last - b->pos > 256 ? "..." : "",
|
||||
b->last - b->pos);
|
||||
|
||||
if (r->request_body_no_buffering) {
|
||||
|
||||
|
|
@ -1205,6 +1213,8 @@ ngx_http_grpc_reinit_request(ngx_http_request_t *r)
|
|||
ctx->end_stream = 0;
|
||||
ctx->done = 0;
|
||||
ctx->status = 0;
|
||||
ctx->rst = 0;
|
||||
ctx->goaway = 0;
|
||||
ctx->connection = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
|
|
@ -1560,6 +1570,7 @@ ngx_http_grpc_body_output_filter(void *data, ngx_chain_t *in)
|
|||
&& ctx->out == NULL
|
||||
&& ctx->output_closed
|
||||
&& !ctx->output_blocked
|
||||
&& !ctx->goaway
|
||||
&& ctx->state == ngx_http_grpc_st_start)
|
||||
{
|
||||
u->keepalive = 1;
|
||||
|
|
@ -1587,20 +1598,11 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
|
|||
u = r->upstream;
|
||||
b = &u->buffer;
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
if (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP) {
|
||||
u_char buf[512];
|
||||
size_t n, m;
|
||||
|
||||
n = ngx_min(b->last - b->pos, 256);
|
||||
m = ngx_hex_dump(buf, b->pos, n) - buf;
|
||||
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"grpc response: %*s%s, len: %uz",
|
||||
m, buf, b->last - b->pos > 256 ? "..." : "",
|
||||
b->last - b->pos);
|
||||
}
|
||||
#endif
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"grpc response: %*xs%s, len: %uz",
|
||||
(size_t) ngx_min(b->last - b->pos, 256),
|
||||
b->pos, b->last - b->pos > 256 ? "..." : "",
|
||||
b->last - b->pos);
|
||||
|
||||
ctx = ngx_http_grpc_get_ctx(r);
|
||||
|
||||
|
|
@ -1718,6 +1720,8 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
|
|||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
}
|
||||
|
||||
ctx->goaway = 1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1911,6 +1915,7 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
|
|||
&& ctx->out == NULL
|
||||
&& ctx->output_closed
|
||||
&& !ctx->output_blocked
|
||||
&& !ctx->goaway
|
||||
&& b->last == b->pos)
|
||||
{
|
||||
u->keepalive = 1;
|
||||
|
|
@ -1951,10 +1956,29 @@ ngx_http_grpc_filter_init(void *data)
|
|||
r = ctx->request;
|
||||
u = r->upstream;
|
||||
|
||||
u->length = 1;
|
||||
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
|
||||
|| u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED
|
||||
|| r->method == NGX_HTTP_HEAD)
|
||||
{
|
||||
ctx->length = 0;
|
||||
|
||||
} else {
|
||||
ctx->length = u->headers_in.content_length_n;
|
||||
}
|
||||
|
||||
if (ctx->end_stream) {
|
||||
|
||||
if (ctx->length > 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream prematurely closed stream");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->length = 0;
|
||||
ctx->done = 1;
|
||||
|
||||
} else {
|
||||
u->length = 1;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
|
@ -1997,6 +2021,12 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
|
|||
|
||||
if (ctx->done) {
|
||||
|
||||
if (ctx->length > 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream prematurely closed stream");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have finished parsing the response and the
|
||||
* remaining control frames. If there are unsent
|
||||
|
|
@ -2014,6 +2044,7 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
|
|||
if (ctx->in == NULL
|
||||
&& ctx->output_closed
|
||||
&& !ctx->output_blocked
|
||||
&& !ctx->goaway
|
||||
&& ctx->state == ngx_http_grpc_st_start)
|
||||
{
|
||||
u->keepalive = 1;
|
||||
|
|
@ -2088,7 +2119,10 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ctx->stream_id && ctx->done) {
|
||||
if (ctx->stream_id && ctx->done
|
||||
&& ctx->type != NGX_HTTP_V2_RST_STREAM_FRAME
|
||||
&& ctx->type != NGX_HTTP_V2_WINDOW_UPDATE_FRAME)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent frame for closed stream %ui",
|
||||
ctx->stream_id);
|
||||
|
|
@ -2131,11 +2165,21 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream rejected request with error %ui",
|
||||
ctx->error);
|
||||
if (ctx->error || !ctx->done) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream rejected request with error %ui",
|
||||
ctx->error);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_ERROR;
|
||||
if (ctx->rst) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent frame for closed stream %ui",
|
||||
ctx->stream_id);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->rst = 1;
|
||||
}
|
||||
|
||||
if (ctx->type == NGX_HTTP_V2_GOAWAY_FRAME) {
|
||||
|
|
@ -2170,6 +2214,8 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->goaway = 1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2402,6 +2448,18 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
|
|||
b->pos = b->last;
|
||||
buf->last = b->pos;
|
||||
|
||||
if (ctx->length != -1) {
|
||||
|
||||
if (buf->last - buf->pos > ctx->length) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent response body larger "
|
||||
"than indicated content length");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->length -= buf->last - buf->pos;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
|
|
@ -2409,6 +2467,18 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
|
|||
buf->last = b->pos;
|
||||
ctx->rest = ctx->padding;
|
||||
|
||||
if (ctx->length != -1) {
|
||||
|
||||
if (buf->last - buf->pos > ctx->length) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent response body larger "
|
||||
"than indicated content length");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->length -= buf->last - buf->pos;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if (ctx->padding) {
|
||||
|
|
@ -4272,7 +4342,6 @@ ngx_http_grpc_create_loc_conf(ngx_conf_t *cf)
|
|||
* conf->upstream.hide_headers_hash = { NULL, 0 };
|
||||
* conf->upstream.ssl_name = NULL;
|
||||
*
|
||||
* conf->headers_source = NULL;
|
||||
* conf->headers.lengths = NULL;
|
||||
* conf->headers.values = NULL;
|
||||
* conf->headers.hash = { NULL, 0 };
|
||||
|
|
@ -4308,6 +4377,7 @@ ngx_http_grpc_create_loc_conf(ngx_conf_t *cf)
|
|||
conf->upstream.ssl_verify = NGX_CONF_UNSET;
|
||||
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
|
||||
conf->ssl_passwords = NGX_CONF_UNSET_PTR;
|
||||
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
|
||||
#endif
|
||||
|
||||
/* the hardcoded values */
|
||||
|
|
@ -4325,6 +4395,8 @@ ngx_http_grpc_create_loc_conf(ngx_conf_t *cf)
|
|||
conf->upstream.pass_trailers = 1;
|
||||
conf->upstream.preserve_output = 1;
|
||||
|
||||
conf->headers_source = NGX_CONF_UNSET_PTR;
|
||||
|
||||
ngx_str_set(&conf->upstream.module, "grpc");
|
||||
|
||||
return conf;
|
||||
|
|
@ -4416,6 +4488,9 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
prev->ssl_certificate_key, "");
|
||||
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
|
||||
prev->ssl_conf_commands, NULL);
|
||||
|
||||
if (conf->ssl && ngx_http_grpc_set_ssl(cf, conf) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
|
@ -4455,9 +4530,10 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
clcf->handler = ngx_http_grpc_handler;
|
||||
}
|
||||
|
||||
if (conf->headers_source == NULL) {
|
||||
ngx_conf_merge_ptr_value(conf->headers_source, prev->headers_source, NULL);
|
||||
|
||||
if (conf->headers_source == prev->headers_source) {
|
||||
conf->headers = prev->headers;
|
||||
conf->headers_source = prev->headers_source;
|
||||
conf->host_set = prev->host_set;
|
||||
}
|
||||
|
||||
|
|
@ -4782,6 +4858,17 @@ ngx_http_grpc_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_grpc_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf)
|
||||
{
|
||||
|
|
@ -4872,6 +4959,12 @@ ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf)
|
|||
|
||||
#endif
|
||||
|
||||
if (ngx_ssl_conf_commands(cf, glcf->upstream.ssl, glcf->ssl_conf_commands)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ typedef struct {
|
|||
unsigned done:1;
|
||||
unsigned nomem:1;
|
||||
unsigned buffering:1;
|
||||
unsigned intel:1;
|
||||
unsigned zlib_ng:1;
|
||||
|
||||
size_t zin;
|
||||
size_t zout;
|
||||
|
|
@ -213,7 +213,7 @@ static ngx_str_t ngx_http_gzip_ratio = ngx_string("gzip_ratio");
|
|||
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
|
||||
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
|
||||
|
||||
static ngx_uint_t ngx_http_gzip_assume_intel;
|
||||
static ngx_uint_t ngx_http_gzip_assume_zlib_ng;
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
|
|
@ -501,18 +501,21 @@ ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
|||
* 8K is for zlib deflate_state, it takes
|
||||
* *) 5816 bytes on i386 and sparc64 (32-bit mode)
|
||||
* *) 5920 bytes on amd64 and sparc64
|
||||
*
|
||||
* A zlib variant from Intel (https://github.com/jtkukunas/zlib)
|
||||
* uses additional 16-byte padding in one of window-sized buffers.
|
||||
*/
|
||||
|
||||
if (!ngx_http_gzip_assume_intel) {
|
||||
ctx->allocated = 8192 + (1 << (wbits + 2)) + (1 << (memlevel + 9));
|
||||
if (!ngx_http_gzip_assume_zlib_ng) {
|
||||
ctx->allocated = 8192 + 16 + (1 << (wbits + 2))
|
||||
+ (1 << (memlevel + 9));
|
||||
|
||||
} else {
|
||||
/*
|
||||
* A zlib variant from Intel, https://github.com/jtkukunas/zlib.
|
||||
* It can force window bits to 13 for fast compression level,
|
||||
* on processors with SSE 4.2 it uses 64K hash instead of scaling
|
||||
* it from the specified memory level, and also introduces
|
||||
* 16-byte padding in one out of the two window-sized buffers.
|
||||
* Another zlib variant, https://github.com/zlib-ng/zlib-ng.
|
||||
* It forces window bits to 13 for fast compression level,
|
||||
* uses 16-byte padding in one of window-sized buffers, and
|
||||
* uses 128K hash.
|
||||
*/
|
||||
|
||||
if (conf->level == 1) {
|
||||
|
|
@ -520,9 +523,8 @@ ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
|||
}
|
||||
|
||||
ctx->allocated = 8192 + 16 + (1 << (wbits + 2))
|
||||
+ (1 << (ngx_max(memlevel, 8) + 8))
|
||||
+ (1 << (memlevel + 8));
|
||||
ctx->intel = 1;
|
||||
+ 131072 + (1 << (memlevel + 8));
|
||||
ctx->zlib_ng = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -945,13 +947,13 @@ ngx_http_gzip_filter_alloc(void *opaque, u_int items, u_int size)
|
|||
return p;
|
||||
}
|
||||
|
||||
if (ctx->intel) {
|
||||
if (ctx->zlib_ng) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ctx->request->connection->log, 0,
|
||||
"gzip filter failed to use preallocated memory: "
|
||||
"%ud of %ui", items * size, ctx->allocated);
|
||||
|
||||
} else {
|
||||
ngx_http_gzip_assume_intel = 1;
|
||||
ngx_http_gzip_assume_zlib_ng = 1;
|
||||
}
|
||||
|
||||
p = ngx_palloc(ctx->request->pool, items * size);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit,
|
|||
ngx_uint_t hash, ngx_str_t *key, ngx_uint_t *ep, ngx_uint_t account);
|
||||
static ngx_msec_t ngx_http_limit_req_account(ngx_http_limit_req_limit_t *limits,
|
||||
ngx_uint_t n, ngx_uint_t *ep, ngx_http_limit_req_limit_t **limit);
|
||||
static void ngx_http_limit_req_unlock(ngx_http_limit_req_limit_t *limits,
|
||||
ngx_uint_t n);
|
||||
static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx,
|
||||
ngx_uint_t n);
|
||||
|
||||
|
|
@ -223,6 +225,7 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
|
|||
ctx = limit->shm_zone->data;
|
||||
|
||||
if (ngx_http_complex_value(r, &ctx->key, &key) != NGX_OK) {
|
||||
ngx_http_limit_req_unlock(limits, n);
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -270,21 +273,7 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
|
|||
&limit->shm_zone->shm.name);
|
||||
}
|
||||
|
||||
while (n--) {
|
||||
ctx = limits[n].shm_zone->data;
|
||||
|
||||
if (ctx->node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_shmtx_lock(&ctx->shpool->mutex);
|
||||
|
||||
ctx->node->count--;
|
||||
|
||||
ngx_shmtx_unlock(&ctx->shpool->mutex);
|
||||
|
||||
ctx->node = NULL;
|
||||
}
|
||||
ngx_http_limit_req_unlock(limits, n);
|
||||
|
||||
if (lrcf->dry_run) {
|
||||
r->main->limit_req_status = NGX_HTTP_LIMIT_REQ_REJECTED_DRY_RUN;
|
||||
|
|
@ -321,8 +310,13 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
|
|||
|
||||
r->main->limit_req_status = NGX_HTTP_LIMIT_REQ_DELAYED;
|
||||
|
||||
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
if (r->connection->read->ready) {
|
||||
ngx_post_event(r->connection->read, &ngx_posted_events);
|
||||
|
||||
} else {
|
||||
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
r->read_event_handler = ngx_http_test_reading;
|
||||
|
|
@ -612,6 +606,29 @@ ngx_http_limit_req_account(ngx_http_limit_req_limit_t *limits, ngx_uint_t n,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_limit_req_unlock(ngx_http_limit_req_limit_t *limits, ngx_uint_t n)
|
||||
{
|
||||
ngx_http_limit_req_ctx_t *ctx;
|
||||
|
||||
while (n--) {
|
||||
ctx = limits[n].shm_zone->data;
|
||||
|
||||
if (ctx->node == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_shmtx_lock(&ctx->shpool->mutex);
|
||||
|
||||
ctx->node->count--;
|
||||
|
||||
ngx_shmtx_unlock(&ctx->shpool->mutex);
|
||||
|
||||
ctx->node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -485,10 +485,11 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
|
|||
|
||||
if (u->length == (ssize_t) ctx->rest) {
|
||||
|
||||
if (ngx_strncmp(b->last,
|
||||
if (bytes > u->length
|
||||
|| ngx_strncmp(b->last,
|
||||
ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
|
||||
bytes)
|
||||
!= 0)
|
||||
!= 0)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
|
||||
"memcached sent invalid trailer");
|
||||
|
|
@ -540,7 +541,9 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
|
|||
|
||||
last += (size_t) (u->length - NGX_HTTP_MEMCACHED_END);
|
||||
|
||||
if (ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0) {
|
||||
if (bytes > u->length
|
||||
|| ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
|
||||
"memcached sent invalid trailer");
|
||||
|
||||
|
|
|
|||
|
|
@ -521,12 +521,6 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
if (!of.is_file) {
|
||||
|
||||
if (ngx_close_file(of.fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
||||
ngx_close_file_n " \"%s\" failed", path.data);
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -49,6 +49,7 @@ static ngx_int_t ngx_http_scgi_create_request(ngx_http_request_t *r);
|
|||
static ngx_int_t ngx_http_scgi_reinit_request(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_scgi_process_status_line(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_scgi_process_header(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_scgi_input_filter_init(void *data);
|
||||
static void ngx_http_scgi_abort_request(ngx_http_request_t *r);
|
||||
static void ngx_http_scgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
|
||||
|
||||
|
|
@ -534,6 +535,10 @@ ngx_http_scgi_handler(ngx_http_request_t *r)
|
|||
u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
|
||||
u->pipe->input_ctx = r;
|
||||
|
||||
u->input_filter_init = ngx_http_scgi_input_filter_init;
|
||||
u->input_filter = ngx_http_upstream_non_buffered_filter;
|
||||
u->input_filter_ctx = r;
|
||||
|
||||
if (!scf->upstream.request_buffering
|
||||
&& scf->upstream.pass_request_body
|
||||
&& !r->headers_in.chunked)
|
||||
|
|
@ -1145,6 +1150,37 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_scgi_input_filter_init(void *data)
|
||||
{
|
||||
ngx_http_request_t *r = data;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http scgi filter init s:%ui l:%O",
|
||||
u->headers_in.status_n, u->headers_in.content_length_n);
|
||||
|
||||
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
|
||||
|| u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED)
|
||||
{
|
||||
u->pipe->length = 0;
|
||||
u->length = 0;
|
||||
|
||||
} else if (r->method == NGX_HTTP_HEAD) {
|
||||
u->pipe->length = -1;
|
||||
u->length = -1;
|
||||
|
||||
} else {
|
||||
u->pipe->length = u->headers_in.content_length_n;
|
||||
u->length = u->headers_in.content_length_n;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_scgi_abort_request(ngx_http_request_t *r)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -180,6 +180,11 @@ ngx_http_slice_header_filter(ngx_http_request_t *r)
|
|||
r->headers_out.content_range->hash = 0;
|
||||
r->headers_out.content_range = NULL;
|
||||
|
||||
if (r->headers_out.accept_ranges) {
|
||||
r->headers_out.accept_ranges->hash = 0;
|
||||
r->headers_out.accept_ranges = NULL;
|
||||
}
|
||||
|
||||
r->allow_ranges = 1;
|
||||
r->subrequest_ranges = 1;
|
||||
r->single_range = 1;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,11 @@ static char *ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
void *conf);
|
||||
static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
static char *ngx_http_ssl_conf_command_check(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
|
||||
static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
|
||||
|
||||
|
|
@ -74,11 +79,23 @@ static ngx_conf_enum_t ngx_http_ssl_verify[] = {
|
|||
};
|
||||
|
||||
|
||||
static ngx_conf_enum_t ngx_http_ssl_ocsp[] = {
|
||||
{ ngx_string("off"), 0 },
|
||||
{ ngx_string("on"), 1 },
|
||||
{ ngx_string("leaf"), 2 },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_conf_deprecated_t ngx_http_ssl_deprecated = {
|
||||
ngx_conf_deprecated, "ssl", "listen ... ssl"
|
||||
};
|
||||
|
||||
|
||||
static ngx_conf_post_t ngx_http_ssl_conf_command_post =
|
||||
{ ngx_http_ssl_conf_command_check };
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_ssl_commands[] = {
|
||||
|
||||
{ ngx_string("ssl"),
|
||||
|
|
@ -214,6 +231,27 @@ static ngx_command_t ngx_http_ssl_commands[] = {
|
|||
offsetof(ngx_http_ssl_srv_conf_t, crl),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("ssl_ocsp"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_enum_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_ssl_srv_conf_t, ocsp),
|
||||
&ngx_http_ssl_ocsp },
|
||||
|
||||
{ ngx_string("ssl_ocsp_responder"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_str_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_ssl_srv_conf_t, ocsp_responder),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("ssl_ocsp_cache"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_ssl_ocsp_cache,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("ssl_stapling"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
|
|
@ -249,6 +287,20 @@ static ngx_command_t ngx_http_ssl_commands[] = {
|
|||
offsetof(ngx_http_ssl_srv_conf_t, early_data),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("ssl_conf_command"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
|
||||
ngx_conf_set_keyval_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_ssl_srv_conf_t, conf_commands),
|
||||
&ngx_http_ssl_conf_command_post },
|
||||
|
||||
{ ngx_string("ssl_reject_handshake"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_ssl_srv_conf_t, reject_handshake),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
|
@ -561,6 +613,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
|
|||
* sscf->crl = { 0, NULL };
|
||||
* sscf->ciphers = { 0, NULL };
|
||||
* sscf->shm_zone = NULL;
|
||||
* sscf->ocsp_responder = { 0, NULL };
|
||||
* sscf->stapling_file = { 0, NULL };
|
||||
* sscf->stapling_responder = { 0, NULL };
|
||||
*/
|
||||
|
|
@ -568,16 +621,20 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
|
|||
sscf->enable = NGX_CONF_UNSET;
|
||||
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
|
||||
sscf->early_data = NGX_CONF_UNSET;
|
||||
sscf->reject_handshake = NGX_CONF_UNSET;
|
||||
sscf->buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
sscf->verify = NGX_CONF_UNSET_UINT;
|
||||
sscf->verify_depth = NGX_CONF_UNSET_UINT;
|
||||
sscf->certificates = NGX_CONF_UNSET_PTR;
|
||||
sscf->certificate_keys = NGX_CONF_UNSET_PTR;
|
||||
sscf->passwords = NGX_CONF_UNSET_PTR;
|
||||
sscf->conf_commands = NGX_CONF_UNSET_PTR;
|
||||
sscf->builtin_session_cache = NGX_CONF_UNSET;
|
||||
sscf->session_timeout = NGX_CONF_UNSET;
|
||||
sscf->session_tickets = NGX_CONF_UNSET;
|
||||
sscf->session_ticket_keys = NGX_CONF_UNSET_PTR;
|
||||
sscf->ocsp = NGX_CONF_UNSET_UINT;
|
||||
sscf->ocsp_cache_zone = NGX_CONF_UNSET_PTR;
|
||||
sscf->stapling = NGX_CONF_UNSET;
|
||||
sscf->stapling_verify = NGX_CONF_UNSET;
|
||||
|
||||
|
|
@ -611,6 +668,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
prev->prefer_server_ciphers, 0);
|
||||
|
||||
ngx_conf_merge_value(conf->early_data, prev->early_data, 0);
|
||||
ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
|
||||
|
||||
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
|
||||
(NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
|
||||
|
|
@ -641,6 +699,13 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->ocsp, prev->ocsp, 0);
|
||||
ngx_conf_merge_str_value(conf->ocsp_responder, prev->ocsp_responder, "");
|
||||
ngx_conf_merge_ptr_value(conf->ocsp_cache_zone,
|
||||
prev->ocsp_cache_zone, NULL);
|
||||
|
||||
ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
|
||||
ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
|
||||
ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
|
||||
|
|
@ -651,7 +716,27 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
if (conf->enable) {
|
||||
|
||||
if (conf->certificates == NULL) {
|
||||
if (conf->certificates) {
|
||||
if (conf->certificate_keys == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"ssl_certificate_key\" is defined for "
|
||||
"the \"ssl\" directive in %s:%ui",
|
||||
conf->file, conf->line);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (conf->certificate_keys->nelts < conf->certificates->nelts) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"ssl_certificate_key\" is defined "
|
||||
"for certificate \"%V\" and "
|
||||
"the \"ssl\" directive in %s:%ui",
|
||||
((ngx_str_t *) conf->certificates->elts)
|
||||
+ conf->certificates->nelts - 1,
|
||||
conf->file, conf->line);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
} else if (!conf->reject_handshake) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"ssl_certificate\" is defined for "
|
||||
"the \"ssl\" directive in %s:%ui",
|
||||
|
|
@ -659,30 +744,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (conf->certificate_keys == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"ssl_certificate_key\" is defined for "
|
||||
"the \"ssl\" directive in %s:%ui",
|
||||
conf->file, conf->line);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (conf->certificate_keys->nelts < conf->certificates->nelts) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"ssl_certificate_key\" is defined "
|
||||
"for certificate \"%V\" and "
|
||||
"the \"ssl\" directive in %s:%ui",
|
||||
((ngx_str_t *) conf->certificates->elts)
|
||||
+ conf->certificates->nelts - 1,
|
||||
conf->file, conf->line);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (conf->certificates == NULL) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
} else if (conf->certificates) {
|
||||
|
||||
if (conf->certificate_keys == NULL
|
||||
|| conf->certificate_keys->nelts < conf->certificates->nelts)
|
||||
|
|
@ -694,6 +756,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
+ conf->certificates->nelts - 1);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
} else if (!conf->reject_handshake) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
|
||||
|
|
@ -752,7 +817,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
return NGX_CONF_ERROR;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
} else if (conf->certificates) {
|
||||
|
||||
/* configure certificates */
|
||||
|
||||
|
|
@ -802,6 +867,23 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (conf->ocsp) {
|
||||
|
||||
if (conf->verify == 3) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"\"ssl_ocsp\" is incompatible with "
|
||||
"\"ssl_verify_client optional_no_ca\"");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, conf->ocsp,
|
||||
conf->ocsp_cache_zone)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
|
@ -857,6 +939,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
|
@ -870,6 +956,10 @@ ngx_http_ssl_compile_certificates(ngx_conf_t *cf,
|
|||
ngx_http_complex_value_t *cv;
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
|
||||
if (conf->certificates == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
cert = conf->certificates->elts;
|
||||
key = conf->certificate_keys->elts;
|
||||
nelts = conf->certificates->nelts;
|
||||
|
|
@ -1100,6 +1190,96 @@ invalid:
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_ssl_srv_conf_t *sscf = conf;
|
||||
|
||||
size_t len;
|
||||
ngx_int_t n;
|
||||
ngx_str_t *value, name, size;
|
||||
ngx_uint_t j;
|
||||
|
||||
if (sscf->ocsp_cache_zone != NGX_CONF_UNSET_PTR) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (ngx_strcmp(value[1].data, "off") == 0) {
|
||||
sscf->ocsp_cache_zone = NULL;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (value[1].len <= sizeof("shared:") - 1
|
||||
|| ngx_strncmp(value[1].data, "shared:", sizeof("shared:") - 1) != 0)
|
||||
{
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
|
||||
for (j = sizeof("shared:") - 1; j < value[1].len; j++) {
|
||||
if (value[1].data[j] == ':') {
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
name.len = len;
|
||||
name.data = value[1].data + sizeof("shared:") - 1;
|
||||
|
||||
size.len = value[1].len - j - 1;
|
||||
size.data = name.data + len + 1;
|
||||
|
||||
n = ngx_parse_size(&size);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
if (n < (ngx_int_t) (8 * ngx_pagesize)) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"OCSP cache \"%V\" is too small", &value[1]);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
sscf->ocsp_cache_zone = ngx_shared_memory_add(cf, &name, n,
|
||||
&ngx_http_ssl_module_ctx);
|
||||
if (sscf->ocsp_cache_zone == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
sscf->ocsp_cache_zone->init = ngx_ssl_ocsp_cache_init;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
invalid:
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid OCSP cache \"%V\"", &value[1]);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssl_init(ngx_conf_t *cf)
|
||||
{
|
||||
|
|
@ -1118,17 +1298,28 @@ ngx_http_ssl_init(ngx_conf_t *cf)
|
|||
|
||||
sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
|
||||
|
||||
if (sscf->ssl.ctx == NULL || !sscf->stapling) {
|
||||
if (sscf->ssl.ctx == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
|
||||
|
||||
if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
|
||||
if (sscf->stapling) {
|
||||
if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
|
||||
clcf->resolver_timeout)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (sscf->ocsp) {
|
||||
if (ngx_ssl_ocsp_resolver(cf, &sscf->ssl, clcf->resolver,
|
||||
clcf->resolver_timeout)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1149,7 +1340,33 @@ ngx_http_ssl_init(ngx_conf_t *cf)
|
|||
cscf = addr[a].default_server;
|
||||
sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
|
||||
|
||||
if (sscf->certificates == NULL) {
|
||||
if (sscf->certificates) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sscf->reject_handshake) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"ssl_certificate\" is defined for "
|
||||
"the \"listen ... ssl\" directive in %s:%ui",
|
||||
cscf->file_name, cscf->line);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* if no certificates are defined in the default server,
|
||||
* check all non-default server blocks
|
||||
*/
|
||||
|
||||
cscfp = addr[a].servers.elts;
|
||||
for (s = 0; s < addr[a].servers.nelts; s++) {
|
||||
|
||||
cscf = cscfp[s];
|
||||
sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
|
||||
|
||||
if (sscf->certificates || sscf->reject_handshake) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"ssl_certificate\" is defined for "
|
||||
"the \"listen ... ssl\" directive in %s:%ui",
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ typedef struct {
|
|||
|
||||
ngx_flag_t prefer_server_ciphers;
|
||||
ngx_flag_t early_data;
|
||||
ngx_flag_t reject_handshake;
|
||||
|
||||
ngx_uint_t protocols;
|
||||
|
||||
|
|
@ -48,12 +49,17 @@ typedef struct {
|
|||
ngx_str_t ciphers;
|
||||
|
||||
ngx_array_t *passwords;
|
||||
ngx_array_t *conf_commands;
|
||||
|
||||
ngx_shm_zone_t *shm_zone;
|
||||
|
||||
ngx_flag_t session_tickets;
|
||||
ngx_array_t *session_ticket_keys;
|
||||
|
||||
ngx_uint_t ocsp;
|
||||
ngx_str_t ocsp_responder;
|
||||
ngx_shm_zone_t *ocsp_cache_zone;
|
||||
|
||||
ngx_flag_t stapling;
|
||||
ngx_flag_t stapling_verify;
|
||||
ngx_str_t stapling_file;
|
||||
|
|
|
|||
|
|
@ -103,16 +103,6 @@ ngx_http_stub_status_handler(ngx_http_request_t *r)
|
|||
ngx_str_set(&r->headers_out.content_type, "text/plain");
|
||||
r->headers_out.content_type_lowcase = NULL;
|
||||
|
||||
if (r->method == NGX_HTTP_HEAD) {
|
||||
r->headers_out.status = NGX_HTTP_OK;
|
||||
|
||||
rc = ngx_http_send_header(r);
|
||||
|
||||
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
size = sizeof("Active connections: \n") + NGX_ATOMIC_T_LEN
|
||||
+ sizeof("server accepts handled requests\n") - 1
|
||||
+ 6 + 3 * NGX_ATOMIC_T_LEN
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
typedef struct {
|
||||
ngx_uint_t max_cached;
|
||||
ngx_uint_t requests;
|
||||
ngx_msec_t time;
|
||||
ngx_msec_t timeout;
|
||||
|
||||
ngx_queue_t cache;
|
||||
|
|
@ -86,6 +87,13 @@ static ngx_command_t ngx_http_upstream_keepalive_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("keepalive_time"),
|
||||
NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_upstream_keepalive_srv_conf_t, time),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("keepalive_timeout"),
|
||||
NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
|
|
@ -149,8 +157,9 @@ ngx_http_upstream_init_keepalive(ngx_conf_t *cf,
|
|||
kcf = ngx_http_conf_upstream_srv_conf(us,
|
||||
ngx_http_upstream_keepalive_module);
|
||||
|
||||
ngx_conf_init_msec_value(kcf->time, 3600000);
|
||||
ngx_conf_init_msec_value(kcf->timeout, 60000);
|
||||
ngx_conf_init_uint_value(kcf->requests, 100);
|
||||
ngx_conf_init_uint_value(kcf->requests, 1000);
|
||||
|
||||
if (kcf->original_init_upstream(cf, us) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
|
|
@ -326,6 +335,10 @@ ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc, void *data,
|
|||
goto invalid;
|
||||
}
|
||||
|
||||
if (ngx_current_msec - c->start_time > kp->conf->time) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
if (!u->keepalive) {
|
||||
goto invalid;
|
||||
}
|
||||
|
|
@ -513,6 +526,7 @@ ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf)
|
|||
* conf->max_cached = 0;
|
||||
*/
|
||||
|
||||
conf->time = NGX_CONF_UNSET_MSEC;
|
||||
conf->timeout = NGX_CONF_UNSET_MSEC;
|
||||
conf->requests = NGX_CONF_UNSET_UINT;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,21 @@
|
|||
#define NGX_HTTP_USERID_V1 2
|
||||
#define NGX_HTTP_USERID_ON 3
|
||||
|
||||
#define NGX_HTTP_USERID_COOKIE_OFF 0x0002
|
||||
#define NGX_HTTP_USERID_COOKIE_SECURE 0x0004
|
||||
#define NGX_HTTP_USERID_COOKIE_HTTPONLY 0x0008
|
||||
#define NGX_HTTP_USERID_COOKIE_SAMESITE 0x0010
|
||||
#define NGX_HTTP_USERID_COOKIE_SAMESITE_STRICT 0x0020
|
||||
#define NGX_HTTP_USERID_COOKIE_SAMESITE_LAX 0x0040
|
||||
#define NGX_HTTP_USERID_COOKIE_SAMESITE_NONE 0x0080
|
||||
|
||||
/* 31 Dec 2037 23:55:55 GMT */
|
||||
#define NGX_HTTP_USERID_MAX_EXPIRES 2145916555
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t enable;
|
||||
ngx_uint_t flags;
|
||||
|
||||
ngx_int_t service;
|
||||
|
||||
|
|
@ -88,6 +97,20 @@ static ngx_conf_enum_t ngx_http_userid_state[] = {
|
|||
};
|
||||
|
||||
|
||||
static ngx_conf_bitmask_t ngx_http_userid_flags[] = {
|
||||
{ ngx_string("off"), NGX_HTTP_USERID_COOKIE_OFF },
|
||||
{ ngx_string("secure"), NGX_HTTP_USERID_COOKIE_SECURE },
|
||||
{ ngx_string("httponly"), NGX_HTTP_USERID_COOKIE_HTTPONLY },
|
||||
{ ngx_string("samesite=strict"),
|
||||
NGX_HTTP_USERID_COOKIE_SAMESITE|NGX_HTTP_USERID_COOKIE_SAMESITE_STRICT },
|
||||
{ ngx_string("samesite=lax"),
|
||||
NGX_HTTP_USERID_COOKIE_SAMESITE|NGX_HTTP_USERID_COOKIE_SAMESITE_LAX },
|
||||
{ ngx_string("samesite=none"),
|
||||
NGX_HTTP_USERID_COOKIE_SAMESITE|NGX_HTTP_USERID_COOKIE_SAMESITE_NONE },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_conf_post_handler_pt ngx_http_userid_domain_p =
|
||||
ngx_http_userid_domain;
|
||||
static ngx_conf_post_handler_pt ngx_http_userid_path_p = ngx_http_userid_path;
|
||||
|
|
@ -138,6 +161,13 @@ static ngx_command_t ngx_http_userid_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("userid_flags"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
|
||||
ngx_conf_set_bitmask_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_userid_conf_t, flags),
|
||||
&ngx_http_userid_flags },
|
||||
|
||||
{ ngx_string("userid_p3p"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_str_slot,
|
||||
|
|
@ -383,6 +413,26 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
|
|||
len += conf->domain.len;
|
||||
}
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_SECURE) {
|
||||
len += sizeof("; secure") - 1;
|
||||
}
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_HTTPONLY) {
|
||||
len += sizeof("; httponly") - 1;
|
||||
}
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_SAMESITE_STRICT) {
|
||||
len += sizeof("; samesite=strict") - 1;
|
||||
}
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_SAMESITE_LAX) {
|
||||
len += sizeof("; samesite=lax") - 1;
|
||||
}
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_SAMESITE_NONE) {
|
||||
len += sizeof("; samesite=none") - 1;
|
||||
}
|
||||
|
||||
cookie = ngx_pnalloc(r->pool, len);
|
||||
if (cookie == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
@ -422,6 +472,26 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
|
|||
|
||||
p = ngx_copy(p, conf->path.data, conf->path.len);
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_SECURE) {
|
||||
p = ngx_cpymem(p, "; secure", sizeof("; secure") - 1);
|
||||
}
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_HTTPONLY) {
|
||||
p = ngx_cpymem(p, "; httponly", sizeof("; httponly") - 1);
|
||||
}
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_SAMESITE_STRICT) {
|
||||
p = ngx_cpymem(p, "; samesite=strict", sizeof("; samesite=strict") - 1);
|
||||
}
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_SAMESITE_LAX) {
|
||||
p = ngx_cpymem(p, "; samesite=lax", sizeof("; samesite=lax") - 1);
|
||||
}
|
||||
|
||||
if (conf->flags & NGX_HTTP_USERID_COOKIE_SAMESITE_NONE) {
|
||||
p = ngx_cpymem(p, "; samesite=none", sizeof("; samesite=none") - 1);
|
||||
}
|
||||
|
||||
set_cookie = ngx_list_push(&r->headers_out.headers);
|
||||
if (set_cookie == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
@ -658,6 +728,7 @@ ngx_http_userid_create_conf(ngx_conf_t *cf)
|
|||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->flags = 0;
|
||||
* conf->name = { 0, NULL };
|
||||
* conf->domain = { 0, NULL };
|
||||
* conf->path = { 0, NULL };
|
||||
|
|
@ -682,6 +753,9 @@ ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_uint_value(conf->enable, prev->enable,
|
||||
NGX_HTTP_USERID_OFF);
|
||||
|
||||
ngx_conf_merge_bitmask_value(conf->flags, prev->flags,
|
||||
(NGX_CONF_BITMASK_SET|NGX_HTTP_USERID_COOKIE_OFF));
|
||||
|
||||
ngx_conf_merge_str_value(conf->name, prev->name, "uid");
|
||||
ngx_conf_merge_str_value(conf->domain, prev->domain, "");
|
||||
ngx_conf_merge_str_value(conf->path, prev->path, "; path=/");
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ typedef struct {
|
|||
ngx_str_t ssl_certificate;
|
||||
ngx_str_t ssl_certificate_key;
|
||||
ngx_array_t *ssl_passwords;
|
||||
ngx_array_t *ssl_conf_commands;
|
||||
#endif
|
||||
} ngx_http_uwsgi_loc_conf_t;
|
||||
|
||||
|
|
@ -67,6 +68,7 @@ static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
|
|||
static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_uwsgi_input_filter_init(void *data);
|
||||
static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
|
||||
static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
|
||||
ngx_int_t rc);
|
||||
|
|
@ -95,6 +97,8 @@ static char *ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
#if (NGX_HTTP_SSL)
|
||||
static char *ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf,
|
||||
ngx_command_t *cmd, void *conf);
|
||||
static char *ngx_http_uwsgi_ssl_conf_command_check(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf,
|
||||
ngx_http_uwsgi_loc_conf_t *uwcf);
|
||||
#endif
|
||||
|
|
@ -133,6 +137,9 @@ static ngx_conf_bitmask_t ngx_http_uwsgi_ssl_protocols[] = {
|
|||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
static ngx_conf_post_t ngx_http_uwsgi_ssl_conf_command_post =
|
||||
{ ngx_http_uwsgi_ssl_conf_command_check };
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -560,6 +567,13 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("uwsgi_ssl_conf_command"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
|
||||
ngx_conf_set_keyval_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_uwsgi_loc_conf_t, ssl_conf_commands),
|
||||
&ngx_http_uwsgi_ssl_conf_command_post },
|
||||
|
||||
#endif
|
||||
|
||||
ngx_null_command
|
||||
|
|
@ -703,6 +717,10 @@ ngx_http_uwsgi_handler(ngx_http_request_t *r)
|
|||
u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
|
||||
u->pipe->input_ctx = r;
|
||||
|
||||
u->input_filter_init = ngx_http_uwsgi_input_filter_init;
|
||||
u->input_filter = ngx_http_upstream_non_buffered_filter;
|
||||
u->input_filter_ctx = r;
|
||||
|
||||
if (!uwcf->upstream.request_buffering
|
||||
&& uwcf->upstream.pass_request_body
|
||||
&& !r->headers_in.chunked)
|
||||
|
|
@ -1141,6 +1159,7 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
|||
r->upstream->request_bufs = cl;
|
||||
}
|
||||
|
||||
b->flush = 1;
|
||||
cl->next = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
|
|
@ -1355,6 +1374,37 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_uwsgi_input_filter_init(void *data)
|
||||
{
|
||||
ngx_http_request_t *r = data;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http uwsgi filter init s:%ui l:%O",
|
||||
u->headers_in.status_n, u->headers_in.content_length_n);
|
||||
|
||||
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
|
||||
|| u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED)
|
||||
{
|
||||
u->pipe->length = 0;
|
||||
u->length = 0;
|
||||
|
||||
} else if (r->method == NGX_HTTP_HEAD) {
|
||||
u->pipe->length = -1;
|
||||
u->length = -1;
|
||||
|
||||
} else {
|
||||
u->pipe->length = u->headers_in.content_length_n;
|
||||
u->length = u->headers_in.content_length_n;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
|
||||
{
|
||||
|
|
@ -1463,6 +1513,7 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
|
|||
conf->upstream.ssl_verify = NGX_CONF_UNSET;
|
||||
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
|
||||
conf->ssl_passwords = NGX_CONF_UNSET_PTR;
|
||||
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
|
||||
#endif
|
||||
|
||||
/* "uwsgi_cyclic_temp_file" is disabled */
|
||||
|
|
@ -1793,6 +1844,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
prev->ssl_certificate_key, "");
|
||||
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
|
||||
prev->ssl_conf_commands, NULL);
|
||||
|
||||
if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
|
@ -2339,6 +2393,17 @@ ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_uwsgi_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
|
||||
{
|
||||
|
|
@ -2416,6 +2481,12 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_ssl_conf_commands(cf, uwcf->upstream.ssl, uwcf->ssl_conf_commands)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ ngx_http_xslt_header_filter(ngx_http_request_t *r)
|
|||
ngx_http_set_ctx(r, ctx, ngx_http_xslt_filter_module);
|
||||
|
||||
r->main_filter_need_in_memory = 1;
|
||||
r->allow_ranges = 0;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1469,14 +1469,14 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||
NGX_HASH_WILDCARD_KEY);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"invalid server name or wildcard \"%V\" on %V",
|
||||
&name[n].name, &addr->opt.addr_text);
|
||||
return NGX_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (rc == NGX_BUSY) {
|
||||
|
|
@ -1714,7 +1714,6 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
|
|||
|
||||
cscf = addr->default_server;
|
||||
ls->pool_size = cscf->connection_pool_size;
|
||||
ls->post_accept_timeout = cscf->client_header_timeout;
|
||||
|
||||
clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ struct ngx_http_cache_s {
|
|||
ngx_str_t vary;
|
||||
u_char variant[NGX_HTTP_CACHE_KEY_LEN];
|
||||
|
||||
size_t buffer_size;
|
||||
size_t header_start;
|
||||
size_t body_start;
|
||||
off_t length;
|
||||
|
|
@ -116,6 +117,7 @@ struct ngx_http_cache_s {
|
|||
unsigned purged:1;
|
||||
unsigned reading:1;
|
||||
unsigned secondary:1;
|
||||
unsigned update_variant:1;
|
||||
unsigned background:1;
|
||||
|
||||
unsigned stale_updating:1;
|
||||
|
|
@ -160,6 +162,7 @@ struct ngx_http_file_cache_s {
|
|||
|
||||
ngx_path_t *path;
|
||||
|
||||
off_t min_free;
|
||||
off_t max_size;
|
||||
size_t bsize;
|
||||
|
||||
|
|
|
|||
|
|
@ -495,6 +495,13 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||
offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("keepalive_time"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_loc_conf_t, keepalive_time),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("keepalive_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
|
||||
ngx_http_core_keepalive,
|
||||
|
|
@ -1190,8 +1197,13 @@ ngx_http_core_auth_delay(ngx_http_request_t *r)
|
|||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"delaying unauthorized request");
|
||||
|
||||
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
if (r->connection->read->ready) {
|
||||
ngx_post_event(r->connection->read, &ngx_posted_events);
|
||||
|
||||
} else {
|
||||
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
r->read_event_handler = ngx_http_test_reading;
|
||||
|
|
@ -1330,6 +1342,11 @@ ngx_http_update_location_config(ngx_http_request_t *r)
|
|||
} else if (r->connection->requests >= clcf->keepalive_requests) {
|
||||
r->keepalive = 0;
|
||||
|
||||
} else if (ngx_current_msec - r->connection->start_time
|
||||
> clcf->keepalive_time)
|
||||
{
|
||||
r->keepalive = 0;
|
||||
|
||||
} else if (r->headers_in.msie6
|
||||
&& r->method == NGX_HTTP_POST
|
||||
&& (clcf->keepalive_disable
|
||||
|
|
@ -1782,7 +1799,7 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
|
|||
}
|
||||
}
|
||||
|
||||
if (r->method == NGX_HTTP_HEAD || (r != r->main && val.len == 0)) {
|
||||
if (r != r->main && val.len == 0) {
|
||||
return ngx_http_send_header(r);
|
||||
}
|
||||
|
||||
|
|
@ -3495,6 +3512,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
|
|||
clcf->send_timeout = NGX_CONF_UNSET_MSEC;
|
||||
clcf->send_lowat = NGX_CONF_UNSET_SIZE;
|
||||
clcf->postpone_output = NGX_CONF_UNSET_SIZE;
|
||||
clcf->keepalive_time = NGX_CONF_UNSET_MSEC;
|
||||
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
|
||||
clcf->keepalive_header = NGX_CONF_UNSET;
|
||||
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
|
||||
|
|
@ -3733,12 +3751,14 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
conf->limit_rate_after = prev->limit_rate_after;
|
||||
}
|
||||
|
||||
ngx_conf_merge_msec_value(conf->keepalive_time,
|
||||
prev->keepalive_time, 3600000);
|
||||
ngx_conf_merge_msec_value(conf->keepalive_timeout,
|
||||
prev->keepalive_timeout, 75000);
|
||||
ngx_conf_merge_sec_value(conf->keepalive_header,
|
||||
prev->keepalive_header, 0);
|
||||
ngx_conf_merge_uint_value(conf->keepalive_requests,
|
||||
prev->keepalive_requests, 100);
|
||||
prev->keepalive_requests, 1000);
|
||||
ngx_conf_merge_uint_value(conf->lingering_close,
|
||||
prev->lingering_close, NGX_HTTP_LINGERING_ON);
|
||||
ngx_conf_merge_msec_value(conf->lingering_time,
|
||||
|
|
@ -4078,14 +4098,6 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[n].data, "spdy") == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"invalid parameter \"spdy\": "
|
||||
"ngx_http_spdy_module was superseded "
|
||||
"by ngx_http_v2_module");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[n].data, "so_keepalive=", 13) == 0) {
|
||||
|
||||
if (ngx_strcmp(&value[n].data[13], "on") == 0) {
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ struct ngx_http_core_loc_conf_s {
|
|||
|
||||
ngx_msec_t client_body_timeout; /* client_body_timeout */
|
||||
ngx_msec_t send_timeout; /* send_timeout */
|
||||
ngx_msec_t keepalive_time; /* keepalive_time */
|
||||
ngx_msec_t keepalive_timeout; /* keepalive_timeout */
|
||||
ngx_msec_t lingering_time; /* lingering_time */
|
||||
ngx_msec_t lingering_timeout; /* lingering_timeout */
|
||||
|
|
|
|||
|
|
@ -294,6 +294,8 @@ ngx_http_file_cache_open(ngx_http_request_t *r)
|
|||
cln->data = c;
|
||||
}
|
||||
|
||||
c->buffer_size = c->body_start;
|
||||
|
||||
rc = ngx_http_file_cache_exists(cache, c);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
|
@ -852,7 +854,7 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
|
|||
if (fcn->exists || fcn->uses >= c->min_uses) {
|
||||
|
||||
c->exists = fcn->exists;
|
||||
if (fcn->body_start) {
|
||||
if (fcn->body_start && !c->update_variant) {
|
||||
c->body_start = fcn->body_start;
|
||||
}
|
||||
|
||||
|
|
@ -1230,7 +1232,7 @@ ngx_http_file_cache_reopen(ngx_http_request_t *r, ngx_http_cache_t *c)
|
|||
|
||||
c->secondary = 1;
|
||||
c->file.name.len = 0;
|
||||
c->body_start = c->buf->end - c->buf->start;
|
||||
c->body_start = c->buffer_size;
|
||||
|
||||
ngx_memcpy(c->key, c->variant, NGX_HTTP_CACHE_KEY_LEN);
|
||||
|
||||
|
|
@ -1337,6 +1339,7 @@ ngx_http_file_cache_update_variant(ngx_http_request_t *r, ngx_http_cache_t *c)
|
|||
ngx_shmtx_unlock(&cache->shpool->mutex);
|
||||
|
||||
c->file.name.len = 0;
|
||||
c->update_variant = 1;
|
||||
|
||||
ngx_memcpy(c->key, c->main, NGX_HTTP_CACHE_KEY_LEN);
|
||||
|
||||
|
|
@ -1959,7 +1962,7 @@ ngx_http_file_cache_manager(void *data)
|
|||
{
|
||||
ngx_http_file_cache_t *cache = data;
|
||||
|
||||
off_t size;
|
||||
off_t size, free;
|
||||
time_t wait;
|
||||
ngx_msec_t elapsed, next;
|
||||
ngx_uint_t count, watermark;
|
||||
|
|
@ -1988,7 +1991,19 @@ ngx_http_file_cache_manager(void *data)
|
|||
size, count, (ngx_int_t) watermark);
|
||||
|
||||
if (size < cache->max_size && count < watermark) {
|
||||
break;
|
||||
|
||||
if (!cache->min_free) {
|
||||
break;
|
||||
}
|
||||
|
||||
free = ngx_fs_available(cache->path->name.data);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
|
||||
"http file cache free: %O", free);
|
||||
|
||||
if (free > cache->min_free) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wait = ngx_http_file_cache_forced_expire(cache);
|
||||
|
|
@ -2304,7 +2319,7 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
{
|
||||
char *confp = conf;
|
||||
|
||||
off_t max_size;
|
||||
off_t max_size, min_free;
|
||||
u_char *last, *p;
|
||||
time_t inactive;
|
||||
ssize_t size;
|
||||
|
|
@ -2341,6 +2356,7 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
name.len = 0;
|
||||
size = 0;
|
||||
max_size = NGX_MAX_OFF_T_VALUE;
|
||||
min_free = 0;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
|
|
@ -2476,6 +2492,29 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "min_free=", 9) == 0) {
|
||||
|
||||
#if (NGX_WIN32 || NGX_HAVE_STATFS || NGX_HAVE_STATVFS)
|
||||
|
||||
s.len = value[i].len - 9;
|
||||
s.data = value[i].data + 9;
|
||||
|
||||
min_free = ngx_parse_offset(&s);
|
||||
if (min_free < 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid min_free value \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#else
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"min_free is not supported "
|
||||
"on this platform, ignored");
|
||||
#endif
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "loader_files=", 13) == 0) {
|
||||
|
||||
loader_files = ngx_atoi(value[i].data + 13, value[i].len - 13);
|
||||
|
|
@ -2607,6 +2646,7 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
cache->inactive = inactive;
|
||||
cache->max_size = max_size;
|
||||
cache->min_free = min_free;
|
||||
|
||||
caches = (ngx_array_t *) (confp + cmd->offset);
|
||||
|
||||
|
|
|
|||
|
|
@ -380,6 +380,12 @@ 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->uri_start = p;
|
||||
r->args_start = p + 1;
|
||||
r->empty_path_in_uri = 1;
|
||||
state = sw_uri;
|
||||
break;
|
||||
case ' ':
|
||||
/*
|
||||
* use single "/" from request line to preserve pointers,
|
||||
|
|
@ -446,6 +452,13 @@ 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;
|
||||
r->uri_start = p;
|
||||
r->args_start = p + 1;
|
||||
r->empty_path_in_uri = 1;
|
||||
state = sw_uri;
|
||||
break;
|
||||
case ' ':
|
||||
r->port_end = p;
|
||||
/*
|
||||
|
|
@ -1287,6 +1300,10 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
|
|||
r->uri_ext = NULL;
|
||||
r->args_start = NULL;
|
||||
|
||||
if (r->empty_path_in_uri) {
|
||||
*u++ = '/';
|
||||
}
|
||||
|
||||
ch = *p++;
|
||||
|
||||
while (p <= r->uri_end) {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ static void ngx_http_request_finalizer(ngx_http_request_t *r);
|
|||
|
||||
static void ngx_http_set_keepalive(ngx_http_request_t *r);
|
||||
static void ngx_http_keepalive_handler(ngx_event_t *ev);
|
||||
static void ngx_http_set_lingering_close(ngx_http_request_t *r);
|
||||
static void ngx_http_set_lingering_close(ngx_connection_t *c);
|
||||
static void ngx_http_lingering_close_handler(ngx_event_t *ev);
|
||||
static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
|
||||
static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
|
||||
|
|
@ -206,16 +206,17 @@ ngx_http_header_t ngx_http_headers_in[] = {
|
|||
void
|
||||
ngx_http_init_connection(ngx_connection_t *c)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_event_t *rev;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_http_port_t *port;
|
||||
ngx_http_in_addr_t *addr;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_uint_t i;
|
||||
ngx_event_t *rev;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_http_port_t *port;
|
||||
ngx_http_in_addr_t *addr;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
#if (NGX_HAVE_INET6)
|
||||
struct sockaddr_in6 *sin6;
|
||||
ngx_http_in6_addr_t *addr6;
|
||||
struct sockaddr_in6 *sin6;
|
||||
ngx_http_in6_addr_t *addr6;
|
||||
#endif
|
||||
|
||||
hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
|
||||
|
|
@ -361,7 +362,9 @@ ngx_http_init_connection(ngx_connection_t *c)
|
|||
return;
|
||||
}
|
||||
|
||||
ngx_add_timer(rev, c->listening->post_accept_timeout);
|
||||
cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
|
||||
|
||||
ngx_add_timer(rev, cscf->client_header_timeout);
|
||||
ngx_reusable_connection(c, 1);
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
|
|
@ -431,7 +434,7 @@ ngx_http_wait_request_handler(ngx_event_t *rev)
|
|||
if (n == NGX_AGAIN) {
|
||||
|
||||
if (!rev->timer_set) {
|
||||
ngx_add_timer(rev, c->listening->post_accept_timeout);
|
||||
ngx_add_timer(rev, cscf->client_header_timeout);
|
||||
ngx_reusable_connection(c, 1);
|
||||
}
|
||||
|
||||
|
|
@ -649,6 +652,7 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
|
|||
ngx_http_connection_t *hc;
|
||||
ngx_http_ssl_srv_conf_t *sscf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
c = rev->data;
|
||||
hc = c->data;
|
||||
|
|
@ -680,7 +684,9 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
|
|||
rev->ready = 0;
|
||||
|
||||
if (!rev->timer_set) {
|
||||
ngx_add_timer(rev, c->listening->post_accept_timeout);
|
||||
cscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
ngx_add_timer(rev, cscf->client_header_timeout);
|
||||
ngx_reusable_connection(c, 1);
|
||||
}
|
||||
|
||||
|
|
@ -755,7 +761,9 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
|
|||
if (rc == NGX_AGAIN) {
|
||||
|
||||
if (!rev->timer_set) {
|
||||
ngx_add_timer(rev, c->listening->post_accept_timeout);
|
||||
cscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
ngx_add_timer(rev, cscf->client_header_timeout);
|
||||
}
|
||||
|
||||
c->ssl->handler = ngx_http_ssl_handshake_handler;
|
||||
|
|
@ -871,10 +879,14 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
|||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
}
|
||||
|
||||
hc = c->data;
|
||||
|
||||
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
||||
|
||||
if (servername == NULL) {
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"SSL server name: null");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
|
|
@ -883,7 +895,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
|||
host.len = ngx_strlen(servername);
|
||||
|
||||
if (host.len == 0) {
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
host.data = (u_char *) servername;
|
||||
|
|
@ -891,32 +903,27 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
|||
rc = ngx_http_validate_host(&host, c->pool, 1);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
*ad = SSL_AD_INTERNAL_ERROR;
|
||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hc = c->data;
|
||||
|
||||
rc = ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
|
||||
NULL, &cscf);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
*ad = SSL_AD_INTERNAL_ERROR;
|
||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
|
||||
if (hc->ssl_servername == NULL) {
|
||||
*ad = SSL_AD_INTERNAL_ERROR;
|
||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
*hc->ssl_servername = host;
|
||||
|
|
@ -932,7 +939,9 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
|||
c->ssl->buffer_size = sscf->buffer_size;
|
||||
|
||||
if (sscf->ssl.ctx) {
|
||||
SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
|
||||
if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* SSL_set_SSL_CTX() only changes certs as of 1.0.0d
|
||||
|
|
@ -957,7 +966,22 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
|||
#endif
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
|
||||
|
||||
if (sscf->reject_handshake) {
|
||||
c->ssl->handshake_rejected = 1;
|
||||
*ad = SSL_AD_UNRECOGNIZED_NAME;
|
||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
}
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
|
||||
error:
|
||||
|
||||
*ad = SSL_AD_INTERNAL_ERROR;
|
||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1208,9 +1232,13 @@ ngx_http_process_request_uri(ngx_http_request_t *r)
|
|||
r->uri.len = r->uri_end - r->uri_start;
|
||||
}
|
||||
|
||||
if (r->complex_uri || r->quoted_uri) {
|
||||
if (r->complex_uri || r->quoted_uri || r->empty_path_in_uri) {
|
||||
|
||||
r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
|
||||
if (r->empty_path_in_uri) {
|
||||
r->uri.len++;
|
||||
}
|
||||
|
||||
r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
|
||||
if (r->uri.data == NULL) {
|
||||
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return NGX_ERROR;
|
||||
|
|
@ -1234,7 +1262,7 @@ ngx_http_process_request_uri(ngx_http_request_t *r)
|
|||
r->unparsed_uri.len = r->uri_end - r->uri_start;
|
||||
r->unparsed_uri.data = r->uri_start;
|
||||
|
||||
r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;
|
||||
r->valid_unparsed_uri = (r->space_in_uri || r->empty_path_in_uri) ? 0 : 1;
|
||||
|
||||
if (r->uri_ext) {
|
||||
if (r->args_start) {
|
||||
|
|
@ -1647,6 +1675,12 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
|||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http large header copy: %uz", r->header_in->pos - old);
|
||||
|
||||
if (r->header_in->pos - old > b->end - b->start) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"too large header to copy");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
new = b->start;
|
||||
|
||||
ngx_memcpy(new, old, r->header_in->pos - old);
|
||||
|
|
@ -1993,6 +2027,7 @@ ngx_http_process_request(ngx_http_request_t *r)
|
|||
if (r->http_connection->ssl) {
|
||||
long rc;
|
||||
X509 *cert;
|
||||
const char *s;
|
||||
ngx_http_ssl_srv_conf_t *sscf;
|
||||
|
||||
if (c->ssl == NULL) {
|
||||
|
|
@ -2037,6 +2072,17 @@ ngx_http_process_request(ngx_http_request_t *r)
|
|||
|
||||
X509_free(cert);
|
||||
}
|
||||
|
||||
if (ngx_ssl_ocsp_get_status(c, &s) != NGX_OK) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||
"client SSL certificate verify error: %s", s);
|
||||
|
||||
ngx_ssl_remove_cached_session(c->ssl->session_ctx,
|
||||
(SSL_get0_session(c->ssl->connection)));
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2597,11 +2643,6 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
|||
ngx_del_timer(c->write);
|
||||
}
|
||||
|
||||
if (c->read->eof) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_http_finalize_connection(r);
|
||||
}
|
||||
|
||||
|
|
@ -2700,6 +2741,11 @@ ngx_http_finalize_connection(ngx_http_request_t *r)
|
|||
|
||||
r = r->main;
|
||||
|
||||
if (r->connection->read->eof) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (r->reading_body) {
|
||||
r->keepalive = 0;
|
||||
r->lingering_close = 1;
|
||||
|
|
@ -2720,7 +2766,7 @@ ngx_http_finalize_connection(ngx_http_request_t *r)
|
|||
|| r->header_in->pos < r->header_in->last
|
||||
|| r->connection->read->ready)))
|
||||
{
|
||||
ngx_http_set_lingering_close(r);
|
||||
ngx_http_set_lingering_close(r->connection);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2974,6 +3020,12 @@ closed:
|
|||
rev->error = 1;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
if (c->ssl) {
|
||||
c->ssl->no_send_shutdown = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, err,
|
||||
"client prematurely closed connection");
|
||||
|
||||
|
|
@ -2999,13 +3051,6 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
|||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");
|
||||
|
||||
if (r->discard_body) {
|
||||
r->write_event_handler = ngx_http_request_empty_handler;
|
||||
r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
|
||||
ngx_add_timer(rev, clcf->lingering_timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
c->log->action = "closing request";
|
||||
|
||||
hc = r->http_connection;
|
||||
|
|
@ -3335,22 +3380,43 @@ ngx_http_keepalive_handler(ngx_event_t *rev)
|
|||
|
||||
|
||||
static void
|
||||
ngx_http_set_lingering_close(ngx_http_request_t *r)
|
||||
ngx_http_set_lingering_close(ngx_connection_t *c)
|
||||
{
|
||||
ngx_event_t *rev, *wev;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
c = r->connection;
|
||||
r = c->data;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (r->lingering_time == 0) {
|
||||
r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
if (c->ssl) {
|
||||
ngx_int_t rc;
|
||||
|
||||
c->ssl->shutdown_without_free = 1;
|
||||
|
||||
rc = ngx_ssl_shutdown(c);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
c->ssl->handler = ngx_http_set_lingering_close;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rev = c->read;
|
||||
rev->handler = ngx_http_lingering_close_handler;
|
||||
|
||||
r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
|
||||
ngx_add_timer(rev, clcf->lingering_timeout);
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
|
|
@ -3373,6 +3439,11 @@ ngx_http_set_lingering_close(ngx_http_request_t *r)
|
|||
return;
|
||||
}
|
||||
|
||||
c->close = 0;
|
||||
ngx_reusable_connection(c, 1);
|
||||
|
||||
ngx_add_timer(rev, clcf->lingering_timeout);
|
||||
|
||||
if (rev->ready) {
|
||||
ngx_http_lingering_close_handler(rev);
|
||||
}
|
||||
|
|
@ -3395,7 +3466,7 @@ ngx_http_lingering_close_handler(ngx_event_t *rev)
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http lingering close handler");
|
||||
|
||||
if (rev->timedout) {
|
||||
if (rev->timedout || c->close) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -470,6 +470,9 @@ struct ngx_http_request_s {
|
|||
/* URI with " " */
|
||||
unsigned space_in_uri:1;
|
||||
|
||||
/* URI with empty path */
|
||||
unsigned empty_path_in_uri:1;
|
||||
|
||||
unsigned invalid_header:1;
|
||||
|
||||
unsigned add_uri_to_alias:1;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_copy_pipelined_header(ngx_http_request_t *r,
|
||||
ngx_buf_t *buf);
|
||||
static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_discard_request_body_filter(ngx_http_request_t *r,
|
||||
|
|
@ -135,8 +137,9 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
|
|||
} else {
|
||||
/* set rb->rest */
|
||||
|
||||
if (ngx_http_request_body_filter(r, NULL) != NGX_OK) {
|
||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
rc = ngx_http_request_body_filter(r, NULL);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
|
@ -282,28 +285,12 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||
for ( ;; ) {
|
||||
if (rb->buf->last == rb->buf->end) {
|
||||
|
||||
if (rb->buf->pos != rb->buf->last) {
|
||||
/* update chains */
|
||||
|
||||
/* pass buffer to request body filter chain */
|
||||
rc = ngx_http_request_body_filter(r, NULL);
|
||||
|
||||
out.buf = rb->buf;
|
||||
out.next = NULL;
|
||||
|
||||
rc = ngx_http_request_body_filter(r, &out);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* update chains */
|
||||
|
||||
rc = ngx_http_request_body_filter(r, NULL);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (rb->busy != NULL) {
|
||||
|
|
@ -319,6 +306,9 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, 0,
|
||||
"busy buffers after request body flush");
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -355,17 +345,15 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||
rb->buf->last += n;
|
||||
r->request_length += n;
|
||||
|
||||
if (n == rest) {
|
||||
/* pass buffer to request body filter chain */
|
||||
/* pass buffer to request body filter chain */
|
||||
|
||||
out.buf = rb->buf;
|
||||
out.next = NULL;
|
||||
out.buf = rb->buf;
|
||||
out.next = NULL;
|
||||
|
||||
rc = ngx_http_request_body_filter(r, &out);
|
||||
rc = ngx_http_request_body_filter(r, &out);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (rb->rest == 0) {
|
||||
|
|
@ -386,21 +374,6 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||
|
||||
if (!c->read->ready) {
|
||||
|
||||
if (r->request_body_no_buffering
|
||||
&& rb->buf->pos != rb->buf->last)
|
||||
{
|
||||
/* pass buffer to request body filter chain */
|
||||
|
||||
out.buf = rb->buf;
|
||||
out.next = NULL;
|
||||
|
||||
rc = ngx_http_request_body_filter(r, &out);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
ngx_add_timer(c->read, clcf->client_body_timeout);
|
||||
|
||||
|
|
@ -412,6 +385,10 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||
}
|
||||
}
|
||||
|
||||
if (ngx_http_copy_pipelined_header(r, rb->buf) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
if (c->read->timer_set) {
|
||||
ngx_del_timer(c->read);
|
||||
}
|
||||
|
|
@ -425,6 +402,88 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_copy_pipelined_header(ngx_http_request_t *r, ngx_buf_t *buf)
|
||||
{
|
||||
size_t n;
|
||||
ngx_buf_t *b;
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
b = r->header_in;
|
||||
n = buf->last - buf->pos;
|
||||
|
||||
if (buf == b || n == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http body pipelined header: %uz", n);
|
||||
|
||||
/*
|
||||
* if there is a pipelined request in the client body buffer,
|
||||
* copy it to the r->header_in buffer if there is enough room,
|
||||
* or allocate a large client header buffer
|
||||
*/
|
||||
|
||||
if (n > (size_t) (b->end - b->last)) {
|
||||
|
||||
hc = r->http_connection;
|
||||
|
||||
if (hc->free) {
|
||||
cl = hc->free;
|
||||
hc->free = cl->next;
|
||||
|
||||
b = cl->buf;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http large header free: %p %uz",
|
||||
b->pos, b->end - b->last);
|
||||
|
||||
} else {
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
b = ngx_create_temp_buf(r->connection->pool,
|
||||
cscf->large_client_header_buffers.size);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl = ngx_alloc_chain_link(r->connection->pool);
|
||||
if (cl == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl->buf = b;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http large header alloc: %p %uz",
|
||||
b->pos, b->end - b->last);
|
||||
}
|
||||
|
||||
cl->next = hc->busy;
|
||||
hc->busy = cl;
|
||||
hc->nbusy++;
|
||||
|
||||
r->header_in = b;
|
||||
|
||||
if (n > (size_t) (b->end - b->last)) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"too large pipelined header after reading body");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_memcpy(b->last, buf->pos, n);
|
||||
|
||||
b->last += n;
|
||||
r->request_length -= n;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_write_request_body(ngx_http_request_t *r)
|
||||
{
|
||||
|
|
@ -619,6 +678,7 @@ ngx_http_discarded_request_body_handler(ngx_http_request_t *r)
|
|||
if (rc == NGX_OK) {
|
||||
r->discard_body = 0;
|
||||
r->lingering_close = 0;
|
||||
r->lingering_time = 0;
|
||||
ngx_http_finalize_request(r, NGX_DONE);
|
||||
return;
|
||||
}
|
||||
|
|
@ -670,8 +730,7 @@ ngx_http_read_discarded_request_body(ngx_http_request_t *r)
|
|||
|
||||
for ( ;; ) {
|
||||
if (r->headers_in.content_length_n == 0) {
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
return NGX_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!r->connection->read->ready) {
|
||||
|
|
@ -705,15 +764,24 @@ ngx_http_read_discarded_request_body(ngx_http_request_t *r)
|
|||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_http_copy_pipelined_header(r, &b) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
|
||||
{
|
||||
size_t size;
|
||||
ngx_int_t rc;
|
||||
ngx_http_request_body_t *rb;
|
||||
size_t size;
|
||||
ngx_int_t rc;
|
||||
ngx_http_request_body_t *rb;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
if (r->headers_in.chunked) {
|
||||
|
||||
|
|
@ -768,7 +836,10 @@ ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
|
||||
/* set amount of data we want to see next time */
|
||||
|
||||
r->headers_in.content_length_n = rb->chunked->length;
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
r->headers_in.content_length_n = ngx_max(rb->chunked->length,
|
||||
(off_t) cscf->large_client_header_buffers.size);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -936,6 +1007,7 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
ngx_chain_t *cl, *out, *tl, **ll;
|
||||
ngx_http_request_body_t *rb;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
rb = r->request_body;
|
||||
|
||||
|
|
@ -949,8 +1021,10 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
r->headers_in.content_length_n = 0;
|
||||
rb->rest = 3;
|
||||
rb->rest = cscf->large_client_header_buffers.size;
|
||||
}
|
||||
|
||||
out = NULL;
|
||||
|
|
@ -958,6 +1032,8 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
|
||||
for (cl = in; cl; cl = cl->next) {
|
||||
|
||||
b = NULL;
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
|
||||
|
|
@ -992,6 +1068,29 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||
}
|
||||
|
||||
if (b
|
||||
&& rb->chunked->size <= 128
|
||||
&& cl->buf->last - cl->buf->pos >= rb->chunked->size)
|
||||
{
|
||||
r->headers_in.content_length_n += rb->chunked->size;
|
||||
|
||||
if (rb->chunked->size < 8) {
|
||||
|
||||
while (rb->chunked->size) {
|
||||
*b->last++ = *cl->buf->pos++;
|
||||
rb->chunked->size--;
|
||||
}
|
||||
|
||||
} else {
|
||||
ngx_memmove(b->last, cl->buf->pos, rb->chunked->size);
|
||||
b->last += rb->chunked->size;
|
||||
cl->buf->pos += rb->chunked->size;
|
||||
rb->chunked->size = 0;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tl = ngx_chain_get_free_buf(r->pool, &rb->free);
|
||||
if (tl == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
|
|
@ -1057,7 +1156,10 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
|
||||
/* set rb->rest, amount of data we want to see next time */
|
||||
|
||||
rb->rest = rb->chunked->length;
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
rb->rest = ngx_max(rb->chunked->length,
|
||||
(off_t) cscf->large_client_header_buffers.size);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -575,6 +575,10 @@ ngx_http_clean_header(ngx_http_request_t *r)
|
|||
r->headers_out.headers.part.next = NULL;
|
||||
r->headers_out.headers.last = &r->headers_out.headers.part;
|
||||
|
||||
r->headers_out.trailers.part.nelts = 0;
|
||||
r->headers_out.trailers.part.next = NULL;
|
||||
r->headers_out.trailers.last = &r->headers_out.trailers.part;
|
||||
|
||||
r->headers_out.content_length_n = -1;
|
||||
r->headers_out.last_modified_time = -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,9 +77,6 @@ static void
|
|||
static void
|
||||
ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
|
||||
ngx_uint_t do_write);
|
||||
static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
|
||||
static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
|
||||
ssize_t bytes);
|
||||
#if (NGX_THREADS)
|
||||
static ngx_int_t ngx_http_upstream_thread_handler(ngx_thread_task_t *task,
|
||||
ngx_file_t *file);
|
||||
|
|
@ -610,6 +607,17 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
|
|||
u->store = u->conf->store;
|
||||
|
||||
if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
|
||||
|
||||
if (r->connection->read->ready) {
|
||||
ngx_post_event(r->connection->read, &ngx_posted_events);
|
||||
|
||||
} else {
|
||||
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
|
||||
r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
|
||||
}
|
||||
|
|
@ -1919,6 +1927,7 @@ ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
|
||||
u->keepalive = 0;
|
||||
u->upgrade = 0;
|
||||
u->error = 0;
|
||||
|
||||
ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
|
||||
u->headers_in.content_length_n = -1;
|
||||
|
|
@ -2053,6 +2062,10 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
|||
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
|
||||
}
|
||||
|
||||
if (c->read->ready) {
|
||||
ngx_post_event(c->read, &ngx_posted_events);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2475,7 +2488,7 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
|
||||
&& ((u->conf->cache_use_stale & un->mask) || r->cache->stale_error))
|
||||
&& (u->conf->cache_use_stale & un->mask))
|
||||
{
|
||||
ngx_int_t rc;
|
||||
|
||||
|
|
@ -2502,6 +2515,8 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
|
@ -3011,9 +3026,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
return;
|
||||
}
|
||||
|
||||
if (u->peer.connection->read->ready || u->length == 0) {
|
||||
ngx_http_upstream_process_non_buffered_upstream(r, u);
|
||||
}
|
||||
ngx_http_upstream_process_non_buffered_upstream(r, u);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -3625,7 +3638,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
|
|||
return;
|
||||
}
|
||||
|
||||
if (upstream->read->error) {
|
||||
if (upstream->read->error || u->error) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_BAD_GATEWAY);
|
||||
return;
|
||||
|
|
@ -3703,14 +3716,14 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_int_t
|
||||
ngx_http_upstream_non_buffered_filter_init(void *data)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_int_t
|
||||
ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
|
||||
{
|
||||
ngx_http_request_t *r = data;
|
||||
|
|
@ -3721,6 +3734,13 @@ ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
|
|||
|
||||
u = r->upstream;
|
||||
|
||||
if (u->length == 0) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent more data than specified in "
|
||||
"\"Content-Length\" header");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) {
|
||||
ll = &cl->next;
|
||||
}
|
||||
|
|
@ -3746,6 +3766,18 @@ ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (bytes > u->length) {
|
||||
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent more data than specified in "
|
||||
"\"Content-Length\" header");
|
||||
|
||||
cl->buf->last = cl->buf->pos + u->length;
|
||||
u->length = 0;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
u->length -= bytes;
|
||||
|
||||
return NGX_OK;
|
||||
|
|
|
|||
|
|
@ -391,6 +391,7 @@ struct ngx_http_upstream_s {
|
|||
unsigned buffering:1;
|
||||
unsigned keepalive:1;
|
||||
unsigned upgrade:1;
|
||||
unsigned error:1;
|
||||
|
||||
unsigned request_sent:1;
|
||||
unsigned request_body_sent:1;
|
||||
|
|
@ -414,6 +415,8 @@ typedef struct {
|
|||
|
||||
ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r);
|
||||
void ngx_http_upstream_init(ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
|
||||
ngx_int_t ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes);
|
||||
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
|
||||
ngx_url_t *u, ngx_uint_t flags);
|
||||
char *ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
#define ngx_http_upstream_tries(p) ((p)->number \
|
||||
+ ((p)->next ? (p)->next->number : 0))
|
||||
#define ngx_http_upstream_tries(p) ((p)->tries \
|
||||
+ ((p)->next ? (p)->next->tries : 0))
|
||||
|
||||
|
||||
static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer(
|
||||
|
|
@ -32,7 +32,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
ngx_http_upstream_srv_conf_t *us)
|
||||
{
|
||||
ngx_url_t u;
|
||||
ngx_uint_t i, j, n, w;
|
||||
ngx_uint_t i, j, n, w, t;
|
||||
ngx_http_upstream_server_t *server;
|
||||
ngx_http_upstream_rr_peer_t *peer, **peerp;
|
||||
ngx_http_upstream_rr_peers_t *peers, *backup;
|
||||
|
|
@ -44,6 +44,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
|
||||
n = 0;
|
||||
w = 0;
|
||||
t = 0;
|
||||
|
||||
for (i = 0; i < us->servers->nelts; i++) {
|
||||
if (server[i].backup) {
|
||||
|
|
@ -52,6 +53,10 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
|
||||
n += server[i].naddrs;
|
||||
w += server[i].naddrs * server[i].weight;
|
||||
|
||||
if (!server[i].down) {
|
||||
t += server[i].naddrs;
|
||||
}
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
|
|
@ -75,6 +80,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
peers->number = n;
|
||||
peers->weighted = (w != n);
|
||||
peers->total_weight = w;
|
||||
peers->tries = t;
|
||||
peers->name = &us->host;
|
||||
|
||||
n = 0;
|
||||
|
|
@ -110,6 +116,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
|
||||
n = 0;
|
||||
w = 0;
|
||||
t = 0;
|
||||
|
||||
for (i = 0; i < us->servers->nelts; i++) {
|
||||
if (!server[i].backup) {
|
||||
|
|
@ -118,6 +125,10 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
|
||||
n += server[i].naddrs;
|
||||
w += server[i].naddrs * server[i].weight;
|
||||
|
||||
if (!server[i].down) {
|
||||
t += server[i].naddrs;
|
||||
}
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
|
|
@ -139,6 +150,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
backup->number = n;
|
||||
backup->weighted = (w != n);
|
||||
backup->total_weight = w;
|
||||
backup->tries = t;
|
||||
backup->name = &us->host;
|
||||
|
||||
n = 0;
|
||||
|
|
@ -214,6 +226,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
peers->number = n;
|
||||
peers->weighted = 0;
|
||||
peers->total_weight = n;
|
||||
peers->tries = n;
|
||||
peers->name = &us->host;
|
||||
|
||||
peerp = &peers->peer;
|
||||
|
|
@ -332,6 +345,7 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
|
|||
|
||||
peers->single = (ur->naddrs == 1);
|
||||
peers->number = ur->naddrs;
|
||||
peers->tries = ur->naddrs;
|
||||
peers->name = &ur->host;
|
||||
|
||||
if (ur->sockaddr) {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ struct ngx_http_upstream_rr_peers_s {
|
|||
#endif
|
||||
|
||||
ngx_uint_t total_weight;
|
||||
ngx_uint_t tries;
|
||||
|
||||
unsigned single:1;
|
||||
unsigned weighted:1;
|
||||
|
|
|
|||
|
|
@ -129,6 +129,8 @@ static ngx_int_t ngx_http_variable_connection(ngx_http_request_t *r,
|
|||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_connection_requests(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_connection_time(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
static ngx_int_t ngx_http_variable_nginx_version(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
|
@ -342,6 +344,9 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
|||
{ ngx_string("connection_requests"), NULL,
|
||||
ngx_http_variable_connection_requests, 0, 0, 0 },
|
||||
|
||||
{ ngx_string("connection_time"), NULL, ngx_http_variable_connection_time,
|
||||
0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version,
|
||||
0, 0, 0 },
|
||||
|
||||
|
|
@ -1075,7 +1080,7 @@ ngx_http_variable_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
|||
len = name->len - (sizeof("arg_") - 1);
|
||||
arg = name->data + sizeof("arg_") - 1;
|
||||
|
||||
if (ngx_http_arg(r, arg, len, &value) != NGX_OK) {
|
||||
if (len == 0 || ngx_http_arg(r, arg, len, &value) != NGX_OK) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
@ -1174,6 +1179,10 @@ ngx_http_variable_content_length(ngx_http_request_t *r,
|
|||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
} else if (r->headers_in.chunked) {
|
||||
v->not_found = 1;
|
||||
v->no_cacheable = 1;
|
||||
|
||||
} else {
|
||||
v->not_found = 1;
|
||||
}
|
||||
|
|
@ -2252,6 +2261,31 @@ ngx_http_variable_connection_requests(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_connection_time(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
u_char *p;
|
||||
ngx_msec_int_t ms;
|
||||
|
||||
p = ngx_pnalloc(r->pool, NGX_TIME_T_LEN + 4);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ms = ngx_current_msec - r->connection->start_time;
|
||||
ms = ngx_max(ms, 0);
|
||||
|
||||
v->len = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000) - p;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = p;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_nginx_version(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ typedef struct {
|
|||
static void ngx_http_v2_read_handler(ngx_event_t *rev);
|
||||
static void ngx_http_v2_write_handler(ngx_event_t *wev);
|
||||
static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c);
|
||||
static void ngx_http_v2_lingering_close(ngx_connection_t *c);
|
||||
static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev);
|
||||
|
||||
static u_char *ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c,
|
||||
u_char *pos, u_char *end);
|
||||
|
|
@ -236,6 +238,7 @@ ngx_http_v2_init(ngx_event_t *rev)
|
|||
ngx_http_v2_srv_conf_t *h2scf;
|
||||
ngx_http_v2_main_conf_t *h2mcf;
|
||||
ngx_http_v2_connection_t *h2c;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
c = rev->data;
|
||||
hc = c->data;
|
||||
|
|
@ -274,7 +277,7 @@ ngx_http_v2_init(ngx_event_t *rev)
|
|||
h2scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v2_module);
|
||||
|
||||
h2c->concurrent_pushes = h2scf->concurrent_pushes;
|
||||
h2c->priority_limit = h2scf->concurrent_streams;
|
||||
h2c->priority_limit = ngx_max(h2scf->concurrent_streams, 100);
|
||||
|
||||
h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log);
|
||||
if (h2c->pool == NULL) {
|
||||
|
|
@ -323,7 +326,14 @@ ngx_http_v2_init(ngx_event_t *rev)
|
|||
rev->handler = ngx_http_v2_read_handler;
|
||||
c->write->handler = ngx_http_v2_write_handler;
|
||||
|
||||
if (!rev->timer_set) {
|
||||
cscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
ngx_add_timer(rev, cscf->client_header_timeout);
|
||||
}
|
||||
|
||||
c->idle = 1;
|
||||
ngx_reusable_connection(c, 0);
|
||||
|
||||
ngx_http_v2_read_handler(rev);
|
||||
}
|
||||
|
|
@ -360,6 +370,11 @@ ngx_http_v2_read_handler(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!h2c->processing && !h2c->pushing) {
|
||||
ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!h2c->goaway) {
|
||||
h2c->goaway = 1;
|
||||
|
||||
|
|
@ -447,14 +462,6 @@ ngx_http_v2_read_handler(ngx_event_t *rev)
|
|||
|
||||
h2c->blocked = 0;
|
||||
|
||||
if (h2c->processing || h2c->pushing) {
|
||||
if (rev->timer_set) {
|
||||
ngx_del_timer(rev);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_http_v2_handle_connection(h2c);
|
||||
}
|
||||
|
||||
|
|
@ -473,6 +480,7 @@ ngx_http_v2_write_handler(ngx_event_t *wev)
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http2 write event timed out");
|
||||
c->error = 1;
|
||||
c->timedout = 1;
|
||||
ngx_http_v2_finalize_connection(h2c, 0);
|
||||
return;
|
||||
}
|
||||
|
|
@ -626,9 +634,9 @@ error:
|
|||
static void
|
||||
ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_v2_srv_conf_t *h2scf;
|
||||
ngx_int_t rc;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
if (h2c->last_out || h2c->processing || h2c->pushing) {
|
||||
return;
|
||||
|
|
@ -661,14 +669,20 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
|
|||
}
|
||||
|
||||
if (h2c->goaway) {
|
||||
ngx_http_close_connection(c);
|
||||
ngx_http_v2_lingering_close(c);
|
||||
return;
|
||||
}
|
||||
|
||||
h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_v2_module);
|
||||
clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
|
||||
if (!c->read->timer_set) {
|
||||
ngx_add_timer(c->read, clcf->keepalive_timeout);
|
||||
}
|
||||
|
||||
ngx_reusable_connection(c, 1);
|
||||
|
||||
if (h2c->state.incomplete) {
|
||||
ngx_add_timer(c->read, h2scf->recv_timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -686,7 +700,6 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
|
|||
#endif
|
||||
|
||||
c->destroyed = 1;
|
||||
ngx_reusable_connection(c, 1);
|
||||
|
||||
c->write->handler = ngx_http_empty_handler;
|
||||
c->read->handler = ngx_http_v2_idle_handler;
|
||||
|
|
@ -694,8 +707,142 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
|
|||
if (c->write->timer_set) {
|
||||
ngx_del_timer(c->write);
|
||||
}
|
||||
}
|
||||
|
||||
ngx_add_timer(c->read, h2scf->idle_timeout);
|
||||
|
||||
static void
|
||||
ngx_http_v2_lingering_close(ngx_connection_t *c)
|
||||
{
|
||||
ngx_event_t *rev, *wev;
|
||||
ngx_http_v2_connection_t *h2c;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
h2c = c->data;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
|
||||
if (clcf->lingering_close == NGX_HTTP_LINGERING_OFF) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (h2c->lingering_time == 0) {
|
||||
h2c->lingering_time = ngx_time()
|
||||
+ (time_t) (clcf->lingering_time / 1000);
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
if (c->ssl) {
|
||||
ngx_int_t rc;
|
||||
|
||||
rc = ngx_ssl_shutdown(c);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
c->ssl->handler = ngx_http_v2_lingering_close;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rev = c->read;
|
||||
rev->handler = ngx_http_v2_lingering_close_handler;
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
wev = c->write;
|
||||
wev->handler = ngx_http_empty_handler;
|
||||
|
||||
if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
ngx_shutdown_socket_n " failed");
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
c->close = 0;
|
||||
ngx_reusable_connection(c, 1);
|
||||
|
||||
ngx_add_timer(rev, clcf->lingering_timeout);
|
||||
|
||||
if (rev->ready) {
|
||||
ngx_http_v2_lingering_close_handler(rev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_v2_lingering_close_handler(ngx_event_t *rev)
|
||||
{
|
||||
ssize_t n;
|
||||
ngx_msec_t timer;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_v2_connection_t *h2c;
|
||||
u_char buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];
|
||||
|
||||
c = rev->data;
|
||||
h2c = c->data;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http2 lingering close handler");
|
||||
|
||||
if (rev->timedout || c->close) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
timer = (ngx_msec_t) h2c->lingering_time - (ngx_msec_t) ngx_time();
|
||||
if ((ngx_msec_int_t) timer <= 0) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %z", n);
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == NGX_ERROR || n == 0) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
} while (rev->ready);
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
timer *= 1000;
|
||||
|
||||
if (timer > clcf->lingering_timeout) {
|
||||
timer = clcf->lingering_timeout;
|
||||
}
|
||||
|
||||
ngx_add_timer(rev, timer);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -731,9 +878,8 @@ ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
}
|
||||
|
||||
if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"invalid http2 connection preface \"%*s\"",
|
||||
sizeof(preface) - 1, pos);
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"invalid connection preface");
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
|
||||
}
|
||||
|
|
@ -754,9 +900,8 @@ ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
}
|
||||
|
||||
if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"invalid http2 connection preface \"%*s\"",
|
||||
sizeof(preface) - 1, pos);
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"invalid connection preface");
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
|
||||
}
|
||||
|
|
@ -845,6 +990,13 @@ ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"http2 DATA frame");
|
||||
|
||||
if (h2c->state.sid == 0) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client sent DATA frame with incorrect identifier");
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
|
||||
}
|
||||
|
||||
if (size > h2c->recv_window) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client violated connection flow control: "
|
||||
|
|
@ -943,6 +1095,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
size_t size;
|
||||
ngx_buf_t *buf;
|
||||
ngx_int_t rc;
|
||||
ngx_connection_t *fc;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_v2_stream_t *stream;
|
||||
ngx_http_v2_srv_conf_t *h2scf;
|
||||
|
|
@ -961,6 +1114,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
}
|
||||
|
||||
r = stream->request;
|
||||
fc = r->connection;
|
||||
|
||||
if (r->reading_body && !r->request_body_no_buffering) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
|
|
@ -969,6 +1123,13 @@ ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
return ngx_http_v2_state_skip_padded(h2c, pos, end);
|
||||
}
|
||||
|
||||
if (r->headers_in.content_length_n < 0 && !r->headers_in.chunked) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"skipping http2 DATA frame");
|
||||
|
||||
return ngx_http_v2_state_skip_padded(h2c, pos, end);
|
||||
}
|
||||
|
||||
size = end - pos;
|
||||
|
||||
if (size >= h2c->state.length) {
|
||||
|
|
@ -986,6 +1147,8 @@ ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
ngx_http_finalize_request(r, rc);
|
||||
}
|
||||
|
||||
ngx_http_run_posted_requests(fc);
|
||||
|
||||
} else if (size) {
|
||||
buf = stream->preread;
|
||||
|
||||
|
|
@ -1031,12 +1194,15 @@ static u_char *
|
|||
ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||
u_char *end)
|
||||
{
|
||||
size_t size;
|
||||
ngx_uint_t padded, priority, depend, dependency, excl, weight;
|
||||
ngx_uint_t status;
|
||||
ngx_http_v2_node_t *node;
|
||||
ngx_http_v2_stream_t *stream;
|
||||
ngx_http_v2_srv_conf_t *h2scf;
|
||||
size_t size;
|
||||
ngx_uint_t padded, priority, depend, dependency, excl,
|
||||
weight;
|
||||
ngx_uint_t status;
|
||||
ngx_http_v2_node_t *node;
|
||||
ngx_http_v2_stream_t *stream;
|
||||
ngx_http_v2_srv_conf_t *h2scf;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
padded = h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG;
|
||||
priority = h2c->state.flags & NGX_HTTP_V2_PRIORITY_FLAG;
|
||||
|
|
@ -1137,11 +1303,15 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
cscf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
|
||||
h2c->state.header_limit = cscf->large_client_header_buffers.size
|
||||
* cscf->large_client_header_buffers.num;
|
||||
|
||||
h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_v2_module);
|
||||
|
||||
h2c->state.header_limit = h2scf->max_header_size;
|
||||
|
||||
if (h2c->processing >= h2scf->concurrent_streams) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"concurrent streams exceeded %ui", h2c->processing);
|
||||
|
|
@ -1195,7 +1365,14 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
ngx_http_v2_set_dependency(h2c, node, depend, excl);
|
||||
}
|
||||
|
||||
if (h2c->connection->requests >= h2scf->max_requests) {
|
||||
clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
|
||||
if (clcf->keepalive_timeout == 0
|
||||
|| h2c->connection->requests >= clcf->keepalive_requests
|
||||
|| ngx_current_msec - h2c->connection->start_time
|
||||
> clcf->keepalive_time)
|
||||
{
|
||||
h2c->goaway = 1;
|
||||
|
||||
if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) {
|
||||
|
|
@ -1320,10 +1497,10 @@ static u_char *
|
|||
ngx_http_v2_state_field_len(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||
u_char *end)
|
||||
{
|
||||
size_t alloc;
|
||||
ngx_int_t len;
|
||||
ngx_uint_t huff;
|
||||
ngx_http_v2_srv_conf_t *h2scf;
|
||||
size_t alloc;
|
||||
ngx_int_t len;
|
||||
ngx_uint_t huff;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG)
|
||||
&& h2c->state.length < NGX_HTTP_V2_INT_OCTETS)
|
||||
|
|
@ -1370,12 +1547,12 @@ ngx_http_v2_state_field_len(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
"http2 %s string, len:%i",
|
||||
huff ? "encoded" : "raw", len);
|
||||
|
||||
h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_v2_module);
|
||||
cscf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
|
||||
if ((size_t) len > h2scf->max_field_size) {
|
||||
if ((size_t) len > cscf->large_client_header_buffers.size) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client exceeded http2_max_field_size limit");
|
||||
"client sent too large header field");
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
|
||||
}
|
||||
|
|
@ -1590,7 +1767,7 @@ ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
|
||||
if (len > h2c->state.header_limit) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client exceeded http2_max_header_size limit");
|
||||
"client sent too large header");
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
|
||||
}
|
||||
|
|
@ -1987,6 +2164,16 @@ static u_char *
|
|||
ngx_http_v2_state_settings(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||
u_char *end)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"http2 SETTINGS frame");
|
||||
|
||||
if (h2c->state.sid) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client sent SETTINGS frame with incorrect identifier");
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
|
||||
}
|
||||
|
||||
if (h2c->state.flags == NGX_HTTP_V2_ACK_FLAG) {
|
||||
|
||||
if (h2c->state.length != 0) {
|
||||
|
|
@ -2010,9 +2197,6 @@ ngx_http_v2_state_settings(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"http2 SETTINGS frame");
|
||||
|
||||
return ngx_http_v2_state_settings_params(h2c, pos, end);
|
||||
}
|
||||
|
||||
|
|
@ -2161,6 +2345,13 @@ ngx_http_v2_state_ping(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"http2 PING frame");
|
||||
|
||||
if (h2c->state.sid) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client sent PING frame with incorrect identifier");
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
|
||||
}
|
||||
|
||||
if (h2c->state.flags & NGX_HTTP_V2_ACK_FLAG) {
|
||||
return ngx_http_v2_state_skip(h2c, pos, end);
|
||||
}
|
||||
|
|
@ -2202,6 +2393,13 @@ ngx_http_v2_state_goaway(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_goaway);
|
||||
}
|
||||
|
||||
if (h2c->state.sid) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client sent GOAWAY frame with incorrect identifier");
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
|
||||
}
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
h2c->state.length -= NGX_HTTP_V2_GOAWAY_SIZE;
|
||||
|
||||
|
|
@ -3103,6 +3301,10 @@ ngx_http_v2_create_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t push)
|
|||
|
||||
h2c->priority_limit += h2scf->concurrent_streams;
|
||||
|
||||
if (h2c->connection->read->timer_set) {
|
||||
ngx_del_timer(h2c->connection->read);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
|
@ -4469,6 +4671,7 @@ ngx_http_v2_idle_handler(ngx_event_t *rev)
|
|||
ngx_connection_t *c;
|
||||
ngx_http_v2_srv_conf_t *h2scf;
|
||||
ngx_http_v2_connection_t *h2c;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
c = rev->data;
|
||||
h2c = c->data;
|
||||
|
|
@ -4500,10 +4703,10 @@ ngx_http_v2_idle_handler(ngx_event_t *rev)
|
|||
|
||||
#endif
|
||||
|
||||
h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_v2_module);
|
||||
clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
|
||||
if (h2c->idle++ > 10 * h2scf->max_requests) {
|
||||
if (h2c->idle++ > 10 * clcf->keepalive_requests) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"http2 flood detected");
|
||||
ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
|
||||
|
|
@ -4513,6 +4716,9 @@ ngx_http_v2_idle_handler(ngx_event_t *rev)
|
|||
c->destroyed = 0;
|
||||
ngx_reusable_connection(c, 0);
|
||||
|
||||
h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
|
||||
ngx_http_v2_module);
|
||||
|
||||
h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log);
|
||||
if (h2c->pool == NULL) {
|
||||
ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
|
||||
|
|
@ -4543,16 +4749,15 @@ ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,
|
|||
h2c->blocked = 1;
|
||||
|
||||
if (!c->error && !h2c->goaway) {
|
||||
h2c->goaway = 1;
|
||||
|
||||
if (ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) {
|
||||
(void) ngx_http_v2_send_output_queue(h2c);
|
||||
}
|
||||
}
|
||||
|
||||
c->error = 1;
|
||||
|
||||
if (!h2c->processing && !h2c->pushing) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
c->read->handler = ngx_http_empty_handler;
|
||||
|
|
@ -4600,10 +4805,18 @@ ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,
|
|||
h2c->blocked = 0;
|
||||
|
||||
if (h2c->processing || h2c->pushing) {
|
||||
c->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_http_close_connection(c);
|
||||
done:
|
||||
|
||||
if (c->error) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_http_v2_lingering_close(c);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -157,6 +157,8 @@ struct ngx_http_v2_connection_s {
|
|||
ngx_uint_t last_sid;
|
||||
ngx_uint_t last_push;
|
||||
|
||||
time_t lingering_time;
|
||||
|
||||
unsigned closed_nodes:8;
|
||||
unsigned settings_ack:1;
|
||||
unsigned table_update:1;
|
||||
|
|
|
|||
|
|
@ -36,10 +36,31 @@ static char *ngx_http_v2_preread_size(ngx_conf_t *cf, void *post, void *data);
|
|||
static char *ngx_http_v2_streams_index_mask(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
static char *ngx_http_v2_chunk_size(ngx_conf_t *cf, void *post, void *data);
|
||||
static char *ngx_http_v2_spdy_deprecated(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
static char *ngx_http_v2_obsolete(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
|
||||
static ngx_conf_deprecated_t ngx_http_v2_recv_timeout_deprecated = {
|
||||
ngx_conf_deprecated, "http2_recv_timeout", "client_header_timeout"
|
||||
};
|
||||
|
||||
static ngx_conf_deprecated_t ngx_http_v2_idle_timeout_deprecated = {
|
||||
ngx_conf_deprecated, "http2_idle_timeout", "keepalive_timeout"
|
||||
};
|
||||
|
||||
static ngx_conf_deprecated_t ngx_http_v2_max_requests_deprecated = {
|
||||
ngx_conf_deprecated, "http2_max_requests", "keepalive_requests"
|
||||
};
|
||||
|
||||
static ngx_conf_deprecated_t ngx_http_v2_max_field_size_deprecated = {
|
||||
ngx_conf_deprecated, "http2_max_field_size", "large_client_header_buffers"
|
||||
};
|
||||
|
||||
static ngx_conf_deprecated_t ngx_http_v2_max_header_size_deprecated = {
|
||||
ngx_conf_deprecated, "http2_max_header_size", "large_client_header_buffers"
|
||||
};
|
||||
|
||||
|
||||
static ngx_conf_post_t ngx_http_v2_recv_buffer_size_post =
|
||||
{ ngx_http_v2_recv_buffer_size };
|
||||
static ngx_conf_post_t ngx_http_v2_pool_size_post =
|
||||
|
|
@ -84,24 +105,24 @@ static ngx_command_t ngx_http_v2_commands[] = {
|
|||
|
||||
{ ngx_string("http2_max_requests"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v2_srv_conf_t, max_requests),
|
||||
NULL },
|
||||
ngx_http_v2_obsolete,
|
||||
0,
|
||||
0,
|
||||
&ngx_http_v2_max_requests_deprecated },
|
||||
|
||||
{ ngx_string("http2_max_field_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v2_srv_conf_t, max_field_size),
|
||||
NULL },
|
||||
ngx_http_v2_obsolete,
|
||||
0,
|
||||
0,
|
||||
&ngx_http_v2_max_field_size_deprecated },
|
||||
|
||||
{ ngx_string("http2_max_header_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v2_srv_conf_t, max_header_size),
|
||||
NULL },
|
||||
ngx_http_v2_obsolete,
|
||||
0,
|
||||
0,
|
||||
&ngx_http_v2_max_header_size_deprecated },
|
||||
|
||||
{ ngx_string("http2_body_preread_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
|
|
@ -119,17 +140,17 @@ static ngx_command_t ngx_http_v2_commands[] = {
|
|||
|
||||
{ ngx_string("http2_recv_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v2_srv_conf_t, recv_timeout),
|
||||
NULL },
|
||||
ngx_http_v2_obsolete,
|
||||
0,
|
||||
0,
|
||||
&ngx_http_v2_recv_timeout_deprecated },
|
||||
|
||||
{ ngx_string("http2_idle_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v2_srv_conf_t, idle_timeout),
|
||||
NULL },
|
||||
ngx_http_v2_obsolete,
|
||||
0,
|
||||
0,
|
||||
&ngx_http_v2_idle_timeout_deprecated },
|
||||
|
||||
{ ngx_string("http2_chunk_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
|
|
@ -152,62 +173,6 @@ static ngx_command_t ngx_http_v2_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("spdy_recv_buffer_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_v2_spdy_deprecated,
|
||||
NGX_HTTP_MAIN_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("spdy_pool_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_v2_spdy_deprecated,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("spdy_max_concurrent_streams"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_v2_spdy_deprecated,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("spdy_streams_index_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_v2_spdy_deprecated,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("spdy_recv_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_v2_spdy_deprecated,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("spdy_keepalive_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_v2_spdy_deprecated,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("spdy_headers_comp"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_v2_spdy_deprecated,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("spdy_chunk_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_v2_spdy_deprecated,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
|
@ -353,18 +318,11 @@ ngx_http_v2_create_srv_conf(ngx_conf_t *cf)
|
|||
|
||||
h2scf->concurrent_streams = NGX_CONF_UNSET_UINT;
|
||||
h2scf->concurrent_pushes = NGX_CONF_UNSET_UINT;
|
||||
h2scf->max_requests = NGX_CONF_UNSET_UINT;
|
||||
|
||||
h2scf->max_field_size = NGX_CONF_UNSET_SIZE;
|
||||
h2scf->max_header_size = NGX_CONF_UNSET_SIZE;
|
||||
|
||||
h2scf->preread_size = NGX_CONF_UNSET_SIZE;
|
||||
|
||||
h2scf->streams_index_mask = NGX_CONF_UNSET_UINT;
|
||||
|
||||
h2scf->recv_timeout = NGX_CONF_UNSET_MSEC;
|
||||
h2scf->idle_timeout = NGX_CONF_UNSET_MSEC;
|
||||
|
||||
return h2scf;
|
||||
}
|
||||
|
||||
|
|
@ -381,23 +339,12 @@ ngx_http_v2_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
prev->concurrent_streams, 128);
|
||||
ngx_conf_merge_uint_value(conf->concurrent_pushes,
|
||||
prev->concurrent_pushes, 10);
|
||||
ngx_conf_merge_uint_value(conf->max_requests, prev->max_requests, 1000);
|
||||
|
||||
ngx_conf_merge_size_value(conf->max_field_size, prev->max_field_size,
|
||||
4096);
|
||||
ngx_conf_merge_size_value(conf->max_header_size, prev->max_header_size,
|
||||
16384);
|
||||
|
||||
ngx_conf_merge_size_value(conf->preread_size, prev->preread_size, 65536);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->streams_index_mask,
|
||||
prev->streams_index_mask, 32 - 1);
|
||||
|
||||
ngx_conf_merge_msec_value(conf->recv_timeout,
|
||||
prev->recv_timeout, 30000);
|
||||
ngx_conf_merge_msec_value(conf->idle_timeout,
|
||||
prev->idle_timeout, 180000);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
|
@ -600,11 +547,14 @@ ngx_http_v2_chunk_size(ngx_conf_t *cf, void *post, void *data)
|
|||
|
||||
|
||||
static char *
|
||||
ngx_http_v2_spdy_deprecated(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_http_v2_obsolete(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_conf_deprecated_t *d = cmd->post;
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"invalid directive \"%V\": ngx_http_spdy_module "
|
||||
"was superseded by ngx_http_v2_module", &cmd->name);
|
||||
"the \"%s\" directive is obsolete, "
|
||||
"use the \"%s\" directive instead",
|
||||
d->old_name, d->new_name);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,13 +24,8 @@ typedef struct {
|
|||
size_t pool_size;
|
||||
ngx_uint_t concurrent_streams;
|
||||
ngx_uint_t concurrent_pushes;
|
||||
ngx_uint_t max_requests;
|
||||
size_t max_field_size;
|
||||
size_t max_header_size;
|
||||
size_t preread_size;
|
||||
ngx_uint_t streams_index_mask;
|
||||
ngx_msec_t recv_timeout;
|
||||
ngx_msec_t idle_timeout;
|
||||
} ngx_http_v2_srv_conf_t;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -405,6 +405,7 @@ ngx_mail_add_addrs(ngx_conf_t *cf, ngx_mail_port_t *mport,
|
|||
#if (NGX_MAIL_SSL)
|
||||
addrs[i].conf.ssl = addr[i].opt.ssl;
|
||||
#endif
|
||||
addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||
addrs[i].conf.addr_text = addr[i].opt.addr_text;
|
||||
}
|
||||
|
||||
|
|
@ -439,6 +440,7 @@ ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_mail_port_t *mport,
|
|||
#if (NGX_MAIL_SSL)
|
||||
addrs6[i].conf.ssl = addr[i].opt.ssl;
|
||||
#endif
|
||||
addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||
addrs6[i].conf.addr_text = addr[i].opt.addr_text;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ typedef struct {
|
|||
unsigned ipv6only:1;
|
||||
#endif
|
||||
unsigned so_keepalive:2;
|
||||
unsigned proxy_protocol:1;
|
||||
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
|
||||
int tcp_keepidle;
|
||||
int tcp_keepintvl;
|
||||
|
|
@ -55,7 +56,8 @@ typedef struct {
|
|||
typedef struct {
|
||||
ngx_mail_conf_ctx_t *ctx;
|
||||
ngx_str_t addr_text;
|
||||
ngx_uint_t ssl; /* unsigned ssl:1; */
|
||||
unsigned ssl:1;
|
||||
unsigned proxy_protocol:1;
|
||||
} ngx_mail_addr_conf_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -162,10 +164,12 @@ typedef enum {
|
|||
ngx_smtp_auth_external,
|
||||
ngx_smtp_helo,
|
||||
ngx_smtp_helo_xclient,
|
||||
ngx_smtp_helo_auth,
|
||||
ngx_smtp_helo_from,
|
||||
ngx_smtp_xclient,
|
||||
ngx_smtp_xclient_from,
|
||||
ngx_smtp_xclient_helo,
|
||||
ngx_smtp_xclient_auth,
|
||||
ngx_smtp_from,
|
||||
ngx_smtp_to
|
||||
} ngx_smtp_state_e;
|
||||
|
|
@ -174,6 +178,7 @@ typedef enum {
|
|||
typedef struct {
|
||||
ngx_peer_connection_t upstream;
|
||||
ngx_buf_t *buffer;
|
||||
ngx_uint_t proxy_protocol; /* unsigned proxy_protocol:1; */
|
||||
} ngx_mail_proxy_ctx_t;
|
||||
|
||||
|
||||
|
|
@ -195,6 +200,7 @@ typedef struct {
|
|||
|
||||
ngx_uint_t mail_state;
|
||||
|
||||
unsigned ssl:1;
|
||||
unsigned protocol:3;
|
||||
unsigned blocked:1;
|
||||
unsigned quit:1;
|
||||
|
|
@ -403,6 +409,7 @@ char *ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
|||
/* STUB */
|
||||
void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer);
|
||||
void ngx_mail_auth_http_init(ngx_mail_session_t *s);
|
||||
ngx_int_t ngx_mail_realip_handler(ngx_mail_session_t *s);
|
||||
/**/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1135,10 +1135,10 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
|
|||
size_t len;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t login, passwd;
|
||||
ngx_connection_t *c;
|
||||
#if (NGX_MAIL_SSL)
|
||||
ngx_str_t verify, subject, issuer, serial, fingerprint,
|
||||
raw_cert, cert;
|
||||
ngx_connection_t *c;
|
||||
ngx_mail_ssl_conf_t *sslcf;
|
||||
#endif
|
||||
ngx_mail_core_srv_conf_t *cscf;
|
||||
|
|
@ -1151,9 +1151,10 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
c = s->connection;
|
||||
|
||||
#if (NGX_MAIL_SSL)
|
||||
|
||||
c = s->connection;
|
||||
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
||||
|
||||
if (c->ssl && sslcf->verify) {
|
||||
|
|
@ -1224,22 +1225,49 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
|
|||
+ sizeof("Client-IP: ") - 1 + s->connection->addr_text.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Client-Host: ") - 1 + s->host.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-Helo: ") - 1 + s->smtp_helo.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-From: ") - 1 + s->smtp_from.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-To: ") - 1 + s->smtp_to.len + sizeof(CRLF) - 1
|
||||
#if (NGX_MAIL_SSL)
|
||||
+ sizeof("Auth-SSL: on" CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Verify: ") - 1 + verify.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Subject: ") - 1 + subject.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Issuer: ") - 1 + issuer.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Serial: ") - 1 + serial.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Fingerprint: ") - 1 + fingerprint.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Cert: ") - 1 + cert.len + sizeof(CRLF) - 1
|
||||
#endif
|
||||
+ ahcf->header.len
|
||||
+ sizeof(CRLF) - 1;
|
||||
|
||||
if (c->proxy_protocol) {
|
||||
len += sizeof("Proxy-Protocol-Addr: ") - 1
|
||||
+ c->proxy_protocol->src_addr.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Proxy-Protocol-Port: ") - 1
|
||||
+ sizeof("65535") - 1 + sizeof(CRLF) - 1
|
||||
+ sizeof("Proxy-Protocol-Server-Addr: ") - 1
|
||||
+ c->proxy_protocol->dst_addr.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Proxy-Protocol-Server-Port: ") - 1
|
||||
+ sizeof("65535") - 1 + sizeof(CRLF) - 1;
|
||||
}
|
||||
|
||||
if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
||||
len += sizeof("Auth-SMTP-Helo: ") - 1 + s->smtp_helo.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-From: ") - 1 + s->smtp_from.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-To: ") - 1 + s->smtp_to.len
|
||||
+ sizeof(CRLF) - 1;
|
||||
}
|
||||
|
||||
#if (NGX_MAIL_SSL)
|
||||
|
||||
if (c->ssl) {
|
||||
len += sizeof("Auth-SSL: on" CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Verify: ") - 1 + verify.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Subject: ") - 1 + subject.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Issuer: ") - 1 + issuer.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Serial: ") - 1 + serial.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Fingerprint: ") - 1 + fingerprint.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Cert: ") - 1 + cert.len
|
||||
+ sizeof(CRLF) - 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
b = ngx_create_temp_buf(pool, len);
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
|
|
@ -1298,6 +1326,26 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
|
|||
*b->last++ = CR; *b->last++ = LF;
|
||||
}
|
||||
|
||||
if (c->proxy_protocol) {
|
||||
b->last = ngx_cpymem(b->last, "Proxy-Protocol-Addr: ",
|
||||
sizeof("Proxy-Protocol-Addr: ") - 1);
|
||||
b->last = ngx_copy(b->last, c->proxy_protocol->src_addr.data,
|
||||
c->proxy_protocol->src_addr.len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
b->last = ngx_sprintf(b->last, "Proxy-Protocol-Port: %d" CRLF,
|
||||
c->proxy_protocol->src_port);
|
||||
|
||||
b->last = ngx_cpymem(b->last, "Proxy-Protocol-Server-Addr: ",
|
||||
sizeof("Proxy-Protocol-Server-Addr: ") - 1);
|
||||
b->last = ngx_copy(b->last, c->proxy_protocol->dst_addr.data,
|
||||
c->proxy_protocol->dst_addr.len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
b->last = ngx_sprintf(b->last, "Proxy-Protocol-Server-Port: %d" CRLF,
|
||||
c->proxy_protocol->dst_port);
|
||||
}
|
||||
|
||||
if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
||||
|
||||
/* HELO, MAIL FROM, and RCPT TO can't contain CRLF, no need to escape */
|
||||
|
|
|
|||
|
|
@ -548,6 +548,11 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[i].data, "proxy_protocol") == 0) {
|
||||
ls->proxy_protocol = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the invalid \"%V\" parameter", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#include <ngx_mail.h>
|
||||
|
||||
|
||||
static void ngx_mail_proxy_protocol_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_init_session_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_init_session(ngx_connection_t *c);
|
||||
|
||||
#if (NGX_MAIL_SSL)
|
||||
|
|
@ -26,6 +28,7 @@ ngx_mail_init_connection(ngx_connection_t *c)
|
|||
{
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
ngx_event_t *rev;
|
||||
ngx_mail_port_t *port;
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_in *sin;
|
||||
|
|
@ -129,6 +132,10 @@ ngx_mail_init_connection(ngx_connection_t *c)
|
|||
s->main_conf = addr_conf->ctx->main_conf;
|
||||
s->srv_conf = addr_conf->ctx->srv_conf;
|
||||
|
||||
#if (NGX_MAIL_SSL)
|
||||
s->ssl = addr_conf->ssl;
|
||||
#endif
|
||||
|
||||
s->addr_text = &addr_conf->addr_text;
|
||||
|
||||
c->data = s;
|
||||
|
|
@ -159,13 +166,126 @@ ngx_mail_init_connection(ngx_connection_t *c)
|
|||
|
||||
c->log_error = NGX_ERROR_INFO;
|
||||
|
||||
rev = c->read;
|
||||
rev->handler = ngx_mail_init_session_handler;
|
||||
|
||||
if (addr_conf->proxy_protocol) {
|
||||
c->log->action = "reading PROXY protocol";
|
||||
|
||||
rev->handler = ngx_mail_proxy_protocol_handler;
|
||||
|
||||
if (!rev->ready) {
|
||||
ngx_add_timer(rev, cscf->timeout);
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_use_accept_mutex) {
|
||||
ngx_post_event(rev, &ngx_posted_events);
|
||||
return;
|
||||
}
|
||||
|
||||
rev->handler(rev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_mail_proxy_protocol_handler(ngx_event_t *rev)
|
||||
{
|
||||
u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
ngx_connection_t *c;
|
||||
ngx_mail_session_t *s;
|
||||
ngx_mail_core_srv_conf_t *cscf;
|
||||
|
||||
c = rev->data;
|
||||
s = c->data;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||
"mail PROXY protocol handler");
|
||||
|
||||
if (rev->timedout) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
|
||||
c->timedout = 1;
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK);
|
||||
|
||||
err = ngx_socket_errno;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "recv(): %z", n);
|
||||
|
||||
if (n == -1) {
|
||||
if (err == NGX_EAGAIN) {
|
||||
rev->ready = 0;
|
||||
|
||||
if (!rev->timer_set) {
|
||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||
ngx_add_timer(rev, cscf->timeout);
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_connection_error(c, err, "recv() failed");
|
||||
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
p = ngx_proxy_protocol_read(c, buf, buf + n);
|
||||
|
||||
if (p == NULL) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
size = p - buf;
|
||||
|
||||
if (c->recv(c, buf, size) != (ssize_t) size) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_mail_realip_handler(s) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_init_session_handler(rev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_mail_init_session_handler(ngx_event_t *rev)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
|
||||
c = rev->data;
|
||||
|
||||
#if (NGX_MAIL_SSL)
|
||||
{
|
||||
ngx_mail_session_t *s;
|
||||
ngx_mail_ssl_conf_t *sslcf;
|
||||
|
||||
s = c->data;
|
||||
|
||||
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
||||
|
||||
if (sslcf->enable || addr_conf->ssl) {
|
||||
if (sslcf->enable || s->ssl) {
|
||||
c->log->action = "SSL handshaking";
|
||||
|
||||
ngx_mail_ssl_init_connection(&sslcf->ssl, c);
|
||||
|
|
@ -215,9 +335,10 @@ ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
|
|||
|
||||
s = c->data;
|
||||
|
||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||
|
||||
ngx_add_timer(c->read, cscf->timeout);
|
||||
if (!c->read->timer_set) {
|
||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||
ngx_add_timer(c->read, cscf->timeout);
|
||||
}
|
||||
|
||||
c->ssl->handler = ngx_mail_ssl_handshake_handler;
|
||||
|
||||
|
|
@ -338,6 +459,8 @@ ngx_mail_init_session(ngx_connection_t *c)
|
|||
|
||||
s = c->data;
|
||||
|
||||
c->log->action = "sending client greeting line";
|
||||
|
||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||
|
||||
s->protocol = cscf->protocol->type;
|
||||
|
|
@ -722,11 +845,6 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
|
|||
}
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (s->buffer->pos == s->buffer->last) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,12 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
|
|||
if (s->out.len) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap send handler busy");
|
||||
s->blocked = 1;
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +136,16 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
|
|||
|
||||
rc = ngx_mail_read_command(s, c);
|
||||
|
||||
if (rc == NGX_AGAIN || rc == NGX_ERROR) {
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -293,6 +308,11 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
|
|||
}
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_send(c->write);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,12 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
|
|||
if (s->out.len) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "pop3 send handler busy");
|
||||
s->blocked = 1;
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +151,16 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
|
|||
|
||||
rc = ngx_mail_read_command(s, c);
|
||||
|
||||
if (rc == NGX_AGAIN || rc == NGX_ERROR) {
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -275,6 +290,11 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
|
|||
s->arg_start = s->buffer->start;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_send(c->write);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ typedef struct {
|
|||
ngx_flag_t enable;
|
||||
ngx_flag_t pass_error_message;
|
||||
ngx_flag_t xclient;
|
||||
ngx_flag_t smtp_auth;
|
||||
ngx_flag_t proxy_protocol;
|
||||
size_t buffer_size;
|
||||
ngx_msec_t timeout;
|
||||
} ngx_mail_proxy_conf_t;
|
||||
|
|
@ -25,7 +27,8 @@ static void ngx_mail_proxy_block_read(ngx_event_t *rev);
|
|||
static void ngx_mail_proxy_pop3_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_proxy_imap_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_proxy_smtp_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_proxy_dummy_handler(ngx_event_t *ev);
|
||||
static void ngx_mail_proxy_write_handler(ngx_event_t *wev);
|
||||
static ngx_int_t ngx_mail_proxy_send_proxy_protocol(ngx_mail_session_t *s);
|
||||
static ngx_int_t ngx_mail_proxy_read_response(ngx_mail_session_t *s,
|
||||
ngx_uint_t state);
|
||||
static void ngx_mail_proxy_handler(ngx_event_t *ev);
|
||||
|
|
@ -74,6 +77,20 @@ static ngx_command_t ngx_mail_proxy_commands[] = {
|
|||
offsetof(ngx_mail_proxy_conf_t, xclient),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_smtp_auth"),
|
||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_MAIL_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_mail_proxy_conf_t, smtp_auth),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_protocol"),
|
||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_MAIL_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_mail_proxy_conf_t, proxy_protocol),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
|
@ -148,7 +165,7 @@ ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer)
|
|||
p->upstream.connection->pool = s->connection->pool;
|
||||
|
||||
s->connection->read->handler = ngx_mail_proxy_block_read;
|
||||
p->upstream.connection->write->handler = ngx_mail_proxy_dummy_handler;
|
||||
p->upstream.connection->write->handler = ngx_mail_proxy_write_handler;
|
||||
|
||||
pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
|
||||
|
||||
|
|
@ -159,6 +176,8 @@ ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer)
|
|||
return;
|
||||
}
|
||||
|
||||
s->proxy->proxy_protocol = pcf->proxy_protocol;
|
||||
|
||||
s->out.len = 0;
|
||||
|
||||
switch (s->protocol) {
|
||||
|
|
@ -178,6 +197,12 @@ ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer)
|
|||
s->mail_state = ngx_smtp_start;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_proxy_write_handler(p->upstream.connection->write);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -222,9 +247,25 @@ ngx_mail_proxy_pop3_handler(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (s->proxy->proxy_protocol) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail proxy pop3 busy");
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rc = ngx_mail_proxy_read_response(s, 0);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -306,6 +347,11 @@ ngx_mail_proxy_pop3_handler(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->proxy->buffer->pos = s->proxy->buffer->start;
|
||||
s->proxy->buffer->last = s->proxy->buffer->start;
|
||||
}
|
||||
|
|
@ -335,9 +381,25 @@ ngx_mail_proxy_imap_handler(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (s->proxy->proxy_protocol) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail proxy imap busy");
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rc = ngx_mail_proxy_read_response(s, s->mail_state);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -440,6 +502,11 @@ ngx_mail_proxy_imap_handler(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->proxy->buffer->pos = s->proxy->buffer->start;
|
||||
s->proxy->buffer->last = s->proxy->buffer->start;
|
||||
}
|
||||
|
|
@ -450,7 +517,7 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
|||
{
|
||||
u_char *p;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t line;
|
||||
ngx_str_t line, auth, encoded;
|
||||
ngx_buf_t *b;
|
||||
ngx_connection_t *c;
|
||||
ngx_mail_session_t *s;
|
||||
|
|
@ -471,9 +538,25 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (s->proxy->proxy_protocol) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail proxy smtp busy");
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rc = ngx_mail_proxy_read_response(s, s->mail_state);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -513,6 +596,9 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
|||
} else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
||||
s->mail_state = ngx_smtp_helo_from;
|
||||
|
||||
} else if (pcf->smtp_auth) {
|
||||
s->mail_state = ngx_smtp_helo_auth;
|
||||
|
||||
} else {
|
||||
s->mail_state = ngx_smtp_helo;
|
||||
}
|
||||
|
|
@ -552,7 +638,9 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
|||
p = ngx_copy(p, s->connection->addr_text.data,
|
||||
s->connection->addr_text.len);
|
||||
|
||||
if (s->login.len) {
|
||||
pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
|
||||
|
||||
if (s->login.len && !pcf->smtp_auth) {
|
||||
p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1);
|
||||
p = ngx_copy(p, s->login.data, s->login.len);
|
||||
}
|
||||
|
|
@ -570,6 +658,9 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
|||
} else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
||||
s->mail_state = ngx_smtp_xclient_from;
|
||||
|
||||
} else if (pcf->smtp_auth) {
|
||||
s->mail_state = ngx_smtp_xclient_auth;
|
||||
|
||||
} else {
|
||||
s->mail_state = ngx_smtp_xclient;
|
||||
}
|
||||
|
|
@ -595,8 +686,62 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
|||
&s->smtp_helo)
|
||||
- line.data;
|
||||
|
||||
s->mail_state = (s->auth_method == NGX_MAIL_AUTH_NONE) ?
|
||||
ngx_smtp_helo_from : ngx_smtp_helo;
|
||||
pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
|
||||
|
||||
if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
||||
s->mail_state = ngx_smtp_helo_from;
|
||||
|
||||
} else if (pcf->smtp_auth) {
|
||||
s->mail_state = ngx_smtp_helo_auth;
|
||||
|
||||
} else {
|
||||
s->mail_state = ngx_smtp_helo;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ngx_smtp_helo_auth:
|
||||
case ngx_smtp_xclient_auth:
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
|
||||
"mail proxy send auth");
|
||||
|
||||
s->connection->log->action = "sending AUTH to upstream";
|
||||
|
||||
if (s->passwd.data == NULL) {
|
||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||
"no password available");
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
auth.len = 1 + s->login.len + 1 + s->passwd.len;
|
||||
auth.data = ngx_pnalloc(c->pool, auth.len);
|
||||
if (auth.data == NULL) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
auth.len = ngx_sprintf(auth.data, "%Z%V%Z%V", &s->login, &s->passwd)
|
||||
- auth.data;
|
||||
|
||||
line.len = sizeof("AUTH PLAIN " CRLF) - 1
|
||||
+ ngx_base64_encoded_length(auth.len);
|
||||
|
||||
line.data = ngx_pnalloc(c->pool, line.len);
|
||||
if (line.data == NULL) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
encoded.data = ngx_cpymem(line.data, "AUTH PLAIN ",
|
||||
sizeof("AUTH PLAIN ") - 1);
|
||||
|
||||
ngx_encode_base64(&encoded, &auth);
|
||||
|
||||
p = encoded.data + encoded.len;
|
||||
*p++ = CR; *p = LF;
|
||||
|
||||
s->mail_state = ngx_smtp_auth_plain;
|
||||
|
||||
break;
|
||||
|
||||
|
|
@ -643,6 +788,7 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
|||
|
||||
case ngx_smtp_helo:
|
||||
case ngx_smtp_xclient:
|
||||
case ngx_smtp_auth_plain:
|
||||
case ngx_smtp_to:
|
||||
|
||||
b = s->proxy->buffer;
|
||||
|
|
@ -692,25 +838,103 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->proxy->buffer->pos = s->proxy->buffer->start;
|
||||
s->proxy->buffer->last = s->proxy->buffer->start;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_mail_proxy_dummy_handler(ngx_event_t *wev)
|
||||
ngx_mail_proxy_write_handler(ngx_event_t *wev)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
ngx_mail_session_t *s;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy dummy handler");
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy write handler");
|
||||
|
||||
c = wev->data;
|
||||
s = c->data;
|
||||
|
||||
if (s->proxy->proxy_protocol) {
|
||||
if (ngx_mail_proxy_send_proxy_protocol(s) != NGX_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
s->proxy->proxy_protocol = 0;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(wev, 0) != NGX_OK) {
|
||||
c = wev->data;
|
||||
s = c->data;
|
||||
|
||||
ngx_mail_proxy_close_session(s);
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
}
|
||||
|
||||
if (c->read->ready) {
|
||||
ngx_post_event(c->read, &ngx_posted_events);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_mail_proxy_send_proxy_protocol(ngx_mail_session_t *s)
|
||||
{
|
||||
u_char *p;
|
||||
ssize_t n, size;
|
||||
ngx_connection_t *c;
|
||||
u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
|
||||
|
||||
s->connection->log->action = "sending PROXY protocol header to upstream";
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
|
||||
"mail proxy send PROXY protocol header");
|
||||
|
||||
p = ngx_proxy_protocol_write(s->connection, buf,
|
||||
buf + NGX_PROXY_PROTOCOL_MAX_HEADER);
|
||||
if (p == NULL) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
c = s->proxy->upstream.connection;
|
||||
|
||||
size = p - buf;
|
||||
|
||||
n = c->send(c, buf, size);
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (n != size) {
|
||||
|
||||
/*
|
||||
* PROXY protocol specification:
|
||||
* The sender must always ensure that the header
|
||||
* is sent at once, so that the transport layer
|
||||
* maintains atomicity along the path to the receiver.
|
||||
*/
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||
"could not send PROXY protocol header at once");
|
||||
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -824,6 +1048,7 @@ ngx_mail_proxy_read_response(ngx_mail_session_t *s, ngx_uint_t state)
|
|||
case ngx_smtp_helo:
|
||||
case ngx_smtp_helo_xclient:
|
||||
case ngx_smtp_helo_from:
|
||||
case ngx_smtp_helo_auth:
|
||||
case ngx_smtp_from:
|
||||
if (p[0] == '2' && p[1] == '5' && p[2] == '0') {
|
||||
return NGX_OK;
|
||||
|
|
@ -833,11 +1058,18 @@ ngx_mail_proxy_read_response(ngx_mail_session_t *s, ngx_uint_t state)
|
|||
case ngx_smtp_xclient:
|
||||
case ngx_smtp_xclient_from:
|
||||
case ngx_smtp_xclient_helo:
|
||||
case ngx_smtp_xclient_auth:
|
||||
if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') {
|
||||
return NGX_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case ngx_smtp_auth_plain:
|
||||
if (p[0] == '2' && p[1] == '3' && p[2] == '5') {
|
||||
return NGX_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case ngx_smtp_to:
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
@ -1102,6 +1334,8 @@ ngx_mail_proxy_create_conf(ngx_conf_t *cf)
|
|||
pcf->enable = NGX_CONF_UNSET;
|
||||
pcf->pass_error_message = NGX_CONF_UNSET;
|
||||
pcf->xclient = NGX_CONF_UNSET;
|
||||
pcf->smtp_auth = NGX_CONF_UNSET;
|
||||
pcf->proxy_protocol = NGX_CONF_UNSET;
|
||||
pcf->buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
pcf->timeout = NGX_CONF_UNSET_MSEC;
|
||||
|
||||
|
|
@ -1118,6 +1352,8 @@ ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_value(conf->enable, prev->enable, 0);
|
||||
ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0);
|
||||
ngx_conf_merge_value(conf->xclient, prev->xclient, 1);
|
||||
ngx_conf_merge_value(conf->smtp_auth, prev->smtp_auth, 0);
|
||||
ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0);
|
||||
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
|
||||
(size_t) ngx_pagesize);
|
||||
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000);
|
||||
|
|
|
|||
269
src/mail/ngx_mail_realip_module.c
Normal file
269
src/mail/ngx_mail_realip_module.c
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Igor Sysoev
|
||||
* Copyright (C) Nginx, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_mail.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *from; /* array of ngx_cidr_t */
|
||||
} ngx_mail_realip_srv_conf_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_mail_realip_set_addr(ngx_mail_session_t *s,
|
||||
ngx_addr_t *addr);
|
||||
static char *ngx_mail_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static void *ngx_mail_realip_create_srv_conf(ngx_conf_t *cf);
|
||||
static char *ngx_mail_realip_merge_srv_conf(ngx_conf_t *cf, void *parent,
|
||||
void *child);
|
||||
|
||||
|
||||
static ngx_command_t ngx_mail_realip_commands[] = {
|
||||
|
||||
{ ngx_string("set_real_ip_from"),
|
||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_mail_realip_from,
|
||||
NGX_MAIL_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_mail_module_t ngx_mail_realip_module_ctx = {
|
||||
NULL, /* protocol */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
ngx_mail_realip_create_srv_conf, /* create server configuration */
|
||||
ngx_mail_realip_merge_srv_conf /* merge server configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_mail_realip_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_mail_realip_module_ctx, /* module context */
|
||||
ngx_mail_realip_commands, /* module directives */
|
||||
NGX_MAIL_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_mail_realip_handler(ngx_mail_session_t *s)
|
||||
{
|
||||
ngx_addr_t addr;
|
||||
ngx_connection_t *c;
|
||||
ngx_mail_realip_srv_conf_t *rscf;
|
||||
|
||||
rscf = ngx_mail_get_module_srv_conf(s, ngx_mail_realip_module);
|
||||
|
||||
if (rscf->from == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
c = s->connection;
|
||||
|
||||
if (c->proxy_protocol == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_cidr_match(c->sockaddr, rscf->from) != NGX_OK) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_parse_addr(c->pool, &addr, c->proxy_protocol->src_addr.data,
|
||||
c->proxy_protocol->src_addr.len)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_inet_set_port(addr.sockaddr, c->proxy_protocol->src_port);
|
||||
|
||||
return ngx_mail_realip_set_addr(s, &addr);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_mail_realip_set_addr(ngx_mail_session_t *s, ngx_addr_t *addr)
|
||||
{
|
||||
size_t len;
|
||||
u_char *p;
|
||||
u_char text[NGX_SOCKADDR_STRLEN];
|
||||
ngx_connection_t *c;
|
||||
|
||||
c = s->connection;
|
||||
|
||||
len = ngx_sock_ntop(addr->sockaddr, addr->socklen, text,
|
||||
NGX_SOCKADDR_STRLEN, 0);
|
||||
if (len == 0) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p = ngx_pnalloc(c->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(p, text, len);
|
||||
|
||||
c->sockaddr = addr->sockaddr;
|
||||
c->socklen = addr->socklen;
|
||||
c->addr_text.len = len;
|
||||
c->addr_text.data = p;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_mail_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_mail_realip_srv_conf_t *rscf = conf;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_url_t u;
|
||||
ngx_cidr_t c, *cidr;
|
||||
ngx_uint_t i;
|
||||
struct sockaddr_in *sin;
|
||||
#if (NGX_HAVE_INET6)
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (rscf->from == NULL) {
|
||||
rscf->from = ngx_array_create(cf->pool, 2,
|
||||
sizeof(ngx_cidr_t));
|
||||
if (rscf->from == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
if (ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr = ngx_array_push(rscf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cidr->family = AF_UNIX;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
rc = ngx_ptocidr(&value[1], &c);
|
||||
|
||||
if (rc != NGX_ERROR) {
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless",
|
||||
&value[1]);
|
||||
}
|
||||
|
||||
cidr = ngx_array_push(rscf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*cidr = c;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
u.host = value[1];
|
||||
|
||||
if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in set_real_ip_from \"%V\"",
|
||||
u.err, &u.host);
|
||||
}
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cidr = ngx_array_push_n(rscf->from, u.naddrs);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
|
||||
|
||||
for (i = 0; i < u.naddrs; i++) {
|
||||
cidr[i].family = u.addrs[i].sockaddr->sa_family;
|
||||
|
||||
switch (cidr[i].family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in6.addr = sin6->sin6_addr;
|
||||
ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in.addr = sin->sin_addr.s_addr;
|
||||
cidr[i].u.in.mask = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_mail_realip_create_srv_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_mail_realip_srv_conf_t *conf;
|
||||
|
||||
conf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_realip_srv_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->from = NULL;
|
||||
*/
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_mail_realip_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
{
|
||||
ngx_mail_realip_srv_conf_t *prev = parent;
|
||||
ngx_mail_realip_srv_conf_t *conf = child;
|
||||
|
||||
if (conf->from == NULL) {
|
||||
conf->from = prev->from;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
|
@ -449,6 +449,12 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev)
|
|||
if (s->out.len) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp send handler busy");
|
||||
s->blocked = 1;
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -456,7 +462,16 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev)
|
|||
|
||||
rc = ngx_mail_read_command(s, c);
|
||||
|
||||
if (rc == NGX_AGAIN || rc == NGX_ERROR) {
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -568,6 +583,11 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev)
|
|||
s->arg_start = s->buffer->pos;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_send(c->write);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ static char *ngx_mail_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
static char *ngx_mail_ssl_conf_command_check(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
|
||||
|
||||
static ngx_conf_enum_t ngx_mail_starttls_state[] = {
|
||||
{ ngx_string("off"), NGX_MAIL_STARTTLS_OFF },
|
||||
|
|
@ -61,6 +64,10 @@ static ngx_conf_deprecated_t ngx_mail_ssl_deprecated = {
|
|||
};
|
||||
|
||||
|
||||
static ngx_conf_post_t ngx_mail_ssl_conf_command_post =
|
||||
{ ngx_mail_ssl_conf_command_check };
|
||||
|
||||
|
||||
static ngx_command_t ngx_mail_ssl_commands[] = {
|
||||
|
||||
{ ngx_string("ssl"),
|
||||
|
|
@ -196,6 +203,13 @@ static ngx_command_t ngx_mail_ssl_commands[] = {
|
|||
offsetof(ngx_mail_ssl_conf_t, crl),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("ssl_conf_command"),
|
||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE2,
|
||||
ngx_conf_set_keyval_slot,
|
||||
NGX_MAIL_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_mail_ssl_conf_t, conf_commands),
|
||||
&ngx_mail_ssl_conf_command_post },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
|
@ -259,6 +273,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
|
|||
scf->certificates = NGX_CONF_UNSET_PTR;
|
||||
scf->certificate_keys = NGX_CONF_UNSET_PTR;
|
||||
scf->passwords = NGX_CONF_UNSET_PTR;
|
||||
scf->conf_commands = NGX_CONF_UNSET_PTR;
|
||||
scf->prefer_server_ciphers = NGX_CONF_UNSET;
|
||||
scf->verify = NGX_CONF_UNSET_UINT;
|
||||
scf->verify_depth = NGX_CONF_UNSET_UINT;
|
||||
|
|
@ -316,6 +331,8 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL);
|
||||
|
||||
|
||||
conf->ssl.log = cf->log;
|
||||
|
||||
|
|
@ -461,6 +478,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
|
@ -654,3 +675,14 @@ invalid:
|
|||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_mail_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ typedef struct {
|
|||
ngx_str_t ciphers;
|
||||
|
||||
ngx_array_t *passwords;
|
||||
ngx_array_t *conf_commands;
|
||||
|
||||
ngx_shm_zone_t *shm_zone;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ extern "C" {
|
|||
#include <ngx_mail_pop3_module.h>
|
||||
#include <ngx_mail_imap_module.h>
|
||||
#include <ngx_mail_smtp_module.h>
|
||||
|
||||
#include <ngx_stream.h>
|
||||
}
|
||||
|
||||
// nginx header files should go before other, because they define 64-bit off_t
|
||||
|
|
|
|||
|
|
@ -9,6 +9,49 @@
|
|||
#include <ngx_core.h>
|
||||
|
||||
|
||||
static ngx_str_t ngx_unknown_error = ngx_string("Unknown error");
|
||||
|
||||
|
||||
#if (NGX_HAVE_STRERRORDESC_NP)
|
||||
|
||||
/*
|
||||
* The strerrordesc_np() function, introduced in glibc 2.32, is
|
||||
* async-signal-safe. This makes it possible to use it directly,
|
||||
* without copying error messages.
|
||||
*/
|
||||
|
||||
|
||||
u_char *
|
||||
ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
|
||||
{
|
||||
size_t len;
|
||||
const char *msg;
|
||||
|
||||
msg = strerrordesc_np(err);
|
||||
|
||||
if (msg == NULL) {
|
||||
msg = (char *) ngx_unknown_error.data;
|
||||
len = ngx_unknown_error.len;
|
||||
|
||||
} else {
|
||||
len = ngx_strlen(msg);
|
||||
}
|
||||
|
||||
size = ngx_min(size, len);
|
||||
|
||||
return ngx_cpymem(errstr, msg, size);
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_strerror_init(void)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* The strerror() messages are copied because:
|
||||
*
|
||||
|
|
@ -26,7 +69,8 @@
|
|||
|
||||
|
||||
static ngx_str_t *ngx_sys_errlist;
|
||||
static ngx_str_t ngx_unknown_error = ngx_string("Unknown error");
|
||||
static ngx_err_t ngx_first_error;
|
||||
static ngx_err_t ngx_last_error;
|
||||
|
||||
|
||||
u_char *
|
||||
|
|
@ -34,8 +78,13 @@ ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
|
|||
{
|
||||
ngx_str_t *msg;
|
||||
|
||||
msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
|
||||
&ngx_unknown_error;
|
||||
if (err >= ngx_first_error && err < ngx_last_error) {
|
||||
msg = &ngx_sys_errlist[err - ngx_first_error];
|
||||
|
||||
} else {
|
||||
msg = &ngx_unknown_error;
|
||||
}
|
||||
|
||||
size = ngx_min(size, msg->len);
|
||||
|
||||
return ngx_cpymem(errstr, msg->data, size);
|
||||
|
|
@ -50,20 +99,92 @@ ngx_strerror_init(void)
|
|||
size_t len;
|
||||
ngx_err_t err;
|
||||
|
||||
#if (NGX_SYS_NERR)
|
||||
ngx_first_error = 0;
|
||||
ngx_last_error = NGX_SYS_NERR;
|
||||
|
||||
#elif (EPERM > 1000 && EPERM < 0x7fffffff - 1000)
|
||||
|
||||
/*
|
||||
* If number of errors is not known, and EPERM error code has large
|
||||
* but reasonable value, guess possible error codes based on the error
|
||||
* messages returned by strerror(), starting from EPERM. Notably,
|
||||
* this covers GNU/Hurd, where errors start at 0x40000001.
|
||||
*/
|
||||
|
||||
for (err = EPERM; err > EPERM - 1000; err--) {
|
||||
ngx_set_errno(0);
|
||||
msg = strerror(err);
|
||||
|
||||
if (errno == EINVAL
|
||||
|| msg == NULL
|
||||
|| strncmp(msg, "Unknown error", 13) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_first_error = err;
|
||||
}
|
||||
|
||||
for (err = EPERM; err < EPERM + 1000; err++) {
|
||||
ngx_set_errno(0);
|
||||
msg = strerror(err);
|
||||
|
||||
if (errno == EINVAL
|
||||
|| msg == NULL
|
||||
|| strncmp(msg, "Unknown error", 13) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_last_error = err + 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* If number of errors is not known, guess it based on the error
|
||||
* messages returned by strerror().
|
||||
*/
|
||||
|
||||
ngx_first_error = 0;
|
||||
|
||||
for (err = 0; err < 1000; err++) {
|
||||
ngx_set_errno(0);
|
||||
msg = strerror(err);
|
||||
|
||||
if (errno == EINVAL
|
||||
|| msg == NULL
|
||||
|| strncmp(msg, "Unknown error", 13) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_last_error = err + 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ngx_strerror() is not ready to work at this stage, therefore,
|
||||
* malloc() is used and possible errors are logged using strerror().
|
||||
*/
|
||||
|
||||
len = NGX_SYS_NERR * sizeof(ngx_str_t);
|
||||
len = (ngx_last_error - ngx_first_error) * sizeof(ngx_str_t);
|
||||
|
||||
ngx_sys_errlist = malloc(len);
|
||||
if (ngx_sys_errlist == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (err = 0; err < NGX_SYS_NERR; err++) {
|
||||
for (err = ngx_first_error; err < ngx_last_error; err++) {
|
||||
msg = strerror(err);
|
||||
|
||||
if (msg == NULL) {
|
||||
ngx_sys_errlist[err - ngx_first_error] = ngx_unknown_error;
|
||||
continue;
|
||||
}
|
||||
|
||||
len = ngx_strlen(msg);
|
||||
|
||||
p = malloc(len);
|
||||
|
|
@ -72,8 +193,8 @@ ngx_strerror_init(void)
|
|||
}
|
||||
|
||||
ngx_memcpy(p, msg, len);
|
||||
ngx_sys_errlist[err].len = len;
|
||||
ngx_sys_errlist[err].data = p;
|
||||
ngx_sys_errlist[err - ngx_first_error].len = len;
|
||||
ngx_sys_errlist[err - ngx_first_error].data = p;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
|
@ -85,3 +206,5 @@ failed:
|
|||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -875,9 +875,28 @@ ngx_fs_bsize(u_char *name)
|
|||
return 512;
|
||||
}
|
||||
|
||||
#if (NGX_LINUX)
|
||||
if ((size_t) fs.f_bsize > ngx_pagesize) {
|
||||
return 512;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (size_t) fs.f_bsize;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
ngx_fs_available(u_char *name)
|
||||
{
|
||||
struct statfs fs;
|
||||
|
||||
if (statfs((char *) name, &fs) == -1) {
|
||||
return NGX_MAX_OFF_T_VALUE;
|
||||
}
|
||||
|
||||
return (off_t) fs.f_bavail * fs.f_bsize;
|
||||
}
|
||||
|
||||
#elif (NGX_HAVE_STATVFS)
|
||||
|
||||
size_t
|
||||
|
|
@ -893,9 +912,28 @@ ngx_fs_bsize(u_char *name)
|
|||
return 512;
|
||||
}
|
||||
|
||||
#if (NGX_LINUX)
|
||||
if ((size_t) fs.f_frsize > ngx_pagesize) {
|
||||
return 512;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (size_t) fs.f_frsize;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
ngx_fs_available(u_char *name)
|
||||
{
|
||||
struct statvfs fs;
|
||||
|
||||
if (statvfs((char *) name, &fs) == -1) {
|
||||
return NGX_MAX_OFF_T_VALUE;
|
||||
}
|
||||
|
||||
return (off_t) fs.f_bavail * fs.f_frsize;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
size_t
|
||||
|
|
@ -904,4 +942,11 @@ ngx_fs_bsize(u_char *name)
|
|||
return 512;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
ngx_fs_available(u_char *name)
|
||||
{
|
||||
return NGX_MAX_OFF_T_VALUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -185,7 +185,10 @@ ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s);
|
|||
#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_fs_size(sb) ngx_max((sb)->st_size, (sb)->st_blocks * 512)
|
||||
#define ngx_file_fs_size(sb) \
|
||||
(((sb)->st_blocks * 512 > (sb)->st_size \
|
||||
&& (sb)->st_blocks * 512 < (sb)->st_size + 8 * (sb)->st_blksize) \
|
||||
? (sb)->st_blocks * 512 : (sb)->st_size)
|
||||
#define ngx_file_mtime(sb) (sb)->st_mtime
|
||||
#define ngx_file_uniq(sb) (sb)->st_ino
|
||||
|
||||
|
|
@ -346,6 +349,7 @@ ngx_int_t ngx_directio_off(ngx_fd_t fd);
|
|||
#endif
|
||||
|
||||
size_t ngx_fs_bsize(u_char *name);
|
||||
off_t ngx_fs_available(u_char *name);
|
||||
|
||||
|
||||
#if (NGX_HAVE_OPENAT)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n,
|
|||
ngx_int_t type);
|
||||
static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle,
|
||||
ngx_uint_t respawn);
|
||||
static void ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch);
|
||||
static void ngx_pass_open_channel(ngx_cycle_t *cycle);
|
||||
static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);
|
||||
static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle);
|
||||
static void ngx_master_process_exit(ngx_cycle_t *cycle);
|
||||
|
|
@ -77,12 +77,11 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
|
|||
u_char *p;
|
||||
size_t size;
|
||||
ngx_int_t i;
|
||||
ngx_uint_t n, sigio;
|
||||
ngx_uint_t sigio;
|
||||
sigset_t set;
|
||||
struct itimerval itv;
|
||||
ngx_uint_t live;
|
||||
ngx_msec_t delay;
|
||||
ngx_listening_t *ls;
|
||||
ngx_core_conf_t *ccf;
|
||||
|
||||
sigemptyset(&set);
|
||||
|
|
@ -204,16 +203,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
|
|||
if (ngx_quit) {
|
||||
ngx_signal_worker_processes(cycle,
|
||||
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
|
||||
|
||||
ls = cycle->listening.elts;
|
||||
for (n = 0; n < cycle->listening.nelts; n++) {
|
||||
if (ngx_close_socket(ls[n].fd) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
|
||||
ngx_close_socket_n " %V failed",
|
||||
&ls[n].addr_text);
|
||||
}
|
||||
}
|
||||
cycle->listening.nelts = 0;
|
||||
ngx_close_listening_sockets(cycle);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
@ -345,25 +335,16 @@ ngx_single_process_cycle(ngx_cycle_t *cycle)
|
|||
static void
|
||||
ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
|
||||
{
|
||||
ngx_int_t i;
|
||||
ngx_channel_t ch;
|
||||
ngx_int_t i;
|
||||
|
||||
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
|
||||
|
||||
ngx_memzero(&ch, sizeof(ngx_channel_t));
|
||||
|
||||
ch.command = NGX_CMD_OPEN_CHANNEL;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
|
||||
ngx_spawn_process(cycle, ngx_worker_process_cycle,
|
||||
(void *) (intptr_t) i, "worker process", type);
|
||||
|
||||
ch.pid = ngx_processes[ngx_process_slot].pid;
|
||||
ch.slot = ngx_process_slot;
|
||||
ch.fd = ngx_processes[ngx_process_slot].channel[0];
|
||||
|
||||
ngx_pass_open_channel(cycle, &ch);
|
||||
ngx_pass_open_channel(cycle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -371,9 +352,8 @@ ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
|
|||
static void
|
||||
ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn)
|
||||
{
|
||||
ngx_uint_t i, manager, loader;
|
||||
ngx_path_t **path;
|
||||
ngx_channel_t ch;
|
||||
ngx_uint_t i, manager, loader;
|
||||
ngx_path_t **path;
|
||||
|
||||
manager = 0;
|
||||
loader = 0;
|
||||
|
|
@ -398,14 +378,7 @@ ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn)
|
|||
&ngx_cache_manager_ctx, "cache manager process",
|
||||
respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN);
|
||||
|
||||
ngx_memzero(&ch, sizeof(ngx_channel_t));
|
||||
|
||||
ch.command = NGX_CMD_OPEN_CHANNEL;
|
||||
ch.pid = ngx_processes[ngx_process_slot].pid;
|
||||
ch.slot = ngx_process_slot;
|
||||
ch.fd = ngx_processes[ngx_process_slot].channel[0];
|
||||
|
||||
ngx_pass_open_channel(cycle, &ch);
|
||||
ngx_pass_open_channel(cycle);
|
||||
|
||||
if (loader == 0) {
|
||||
return;
|
||||
|
|
@ -415,19 +388,20 @@ ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn)
|
|||
&ngx_cache_loader_ctx, "cache loader process",
|
||||
respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN);
|
||||
|
||||
ch.command = NGX_CMD_OPEN_CHANNEL;
|
||||
ch.pid = ngx_processes[ngx_process_slot].pid;
|
||||
ch.slot = ngx_process_slot;
|
||||
ch.fd = ngx_processes[ngx_process_slot].channel[0];
|
||||
|
||||
ngx_pass_open_channel(cycle, &ch);
|
||||
ngx_pass_open_channel(cycle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch)
|
||||
ngx_pass_open_channel(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_int_t i;
|
||||
ngx_int_t i;
|
||||
ngx_channel_t ch;
|
||||
|
||||
ch.command = NGX_CMD_OPEN_CHANNEL;
|
||||
ch.pid = ngx_processes[ngx_process_slot].pid;
|
||||
ch.slot = ngx_process_slot;
|
||||
ch.fd = ngx_processes[ngx_process_slot].channel[0];
|
||||
|
||||
for (i = 0; i < ngx_last_process; i++) {
|
||||
|
||||
|
|
@ -440,14 +414,14 @@ ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch)
|
|||
|
||||
ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0,
|
||||
"pass channel s:%i pid:%P fd:%d to s:%i pid:%P fd:%d",
|
||||
ch->slot, ch->pid, ch->fd,
|
||||
ch.slot, ch.pid, ch.fd,
|
||||
i, ngx_processes[i].pid,
|
||||
ngx_processes[i].channel[0]);
|
||||
|
||||
/* TODO: NGX_AGAIN */
|
||||
|
||||
ngx_write_channel(ngx_processes[i].channel[0],
|
||||
ch, sizeof(ngx_channel_t), cycle->log);
|
||||
&ch, sizeof(ngx_channel_t), cycle->log);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -631,12 +605,7 @@ ngx_reap_children(ngx_cycle_t *cycle)
|
|||
}
|
||||
|
||||
|
||||
ch.command = NGX_CMD_OPEN_CHANNEL;
|
||||
ch.pid = ngx_processes[ngx_process_slot].pid;
|
||||
ch.slot = ngx_process_slot;
|
||||
ch.fd = ngx_processes[ngx_process_slot].channel[0];
|
||||
|
||||
ngx_pass_open_channel(cycle, &ch);
|
||||
ngx_pass_open_channel(cycle);
|
||||
|
||||
live = 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -189,6 +189,13 @@ ngx_udp_output_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *in, ngx_log_t *log)
|
|||
return cl;
|
||||
}
|
||||
|
||||
/* zero-sized datagram; pretend to have at least 1 iov */
|
||||
if (n == 0) {
|
||||
iov = &vec->iovs[n++];
|
||||
iov->iov_base = NULL;
|
||||
iov->iov_len = 0;
|
||||
}
|
||||
|
||||
vec->count = n;
|
||||
vec->size = total;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ typedef struct {
|
|||
ngx_str_t ssl_certificate;
|
||||
ngx_str_t ssl_certificate_key;
|
||||
ngx_array_t *ssl_passwords;
|
||||
ngx_array_t *ssl_conf_commands;
|
||||
|
||||
ngx_ssl_t *ssl;
|
||||
#endif
|
||||
|
|
@ -94,6 +95,8 @@ static char *ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s);
|
||||
static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
|
||||
ngx_command_t *cmd, void *conf);
|
||||
static char *ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s);
|
||||
static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc);
|
||||
static void ngx_stream_proxy_ssl_save_session(ngx_connection_t *c);
|
||||
|
|
@ -112,6 +115,9 @@ static ngx_conf_bitmask_t ngx_stream_proxy_ssl_protocols[] = {
|
|||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
static ngx_conf_post_t ngx_stream_proxy_ssl_conf_command_post =
|
||||
{ ngx_stream_proxy_ssl_conf_command_check };
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -331,6 +337,13 @@ static ngx_command_t ngx_stream_proxy_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_ssl_conf_command"),
|
||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
|
||||
ngx_conf_set_keyval_slot,
|
||||
NGX_STREAM_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_stream_proxy_srv_conf_t, ssl_conf_commands),
|
||||
&ngx_stream_proxy_ssl_conf_command_post },
|
||||
|
||||
#endif
|
||||
|
||||
ngx_null_command
|
||||
|
|
@ -839,7 +852,7 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
|
|||
u->upstream_buf.last = p;
|
||||
}
|
||||
|
||||
if (c->buffer && c->buffer->pos < c->buffer->last) {
|
||||
if (c->buffer && c->buffer->pos <= c->buffer->last) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
||||
"stream proxy add preread buffer: %uz",
|
||||
c->buffer->last - c->buffer->pos);
|
||||
|
|
@ -853,6 +866,7 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
|
|||
*cl->buf = *c->buffer;
|
||||
|
||||
cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
|
||||
cl->buf->temporary = (cl->buf->pos == cl->buf->last) ? 0 : 1;
|
||||
cl->buf->flush = 1;
|
||||
|
||||
cl->next = u->upstream_out;
|
||||
|
|
@ -1007,6 +1021,17 @@ ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
|
||||
{
|
||||
|
|
@ -1984,6 +2009,7 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
|
|||
conf->ssl_verify = NGX_CONF_UNSET;
|
||||
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
|
||||
conf->ssl_passwords = NGX_CONF_UNSET_PTR;
|
||||
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
|
||||
#endif
|
||||
|
||||
return conf;
|
||||
|
|
@ -2071,6 +2097,9 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
|
||||
prev->ssl_conf_commands, NULL);
|
||||
|
||||
if (conf->ssl_enable && ngx_stream_proxy_set_ssl(cf, conf) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
|
@ -2155,6 +2184,12 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_ssl_conf_commands(cf, pscf->ssl, pscf->ssl_conf_commands)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
226
src/stream/ngx_stream_set_module.c
Normal file
226
src/stream/ngx_stream_set_module.c
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Pavel Pautov
|
||||
* Copyright (C) Nginx, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_stream.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_int_t index;
|
||||
ngx_stream_set_variable_pt set_handler;
|
||||
uintptr_t data;
|
||||
ngx_stream_complex_value_t value;
|
||||
} ngx_stream_set_cmd_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t commands;
|
||||
} ngx_stream_set_srv_conf_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_stream_set_handler(ngx_stream_session_t *s);
|
||||
static ngx_int_t ngx_stream_set_var(ngx_stream_session_t *s,
|
||||
ngx_stream_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_stream_set_init(ngx_conf_t *cf);
|
||||
static void *ngx_stream_set_create_srv_conf(ngx_conf_t *cf);
|
||||
static char *ngx_stream_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
||||
|
||||
static ngx_command_t ngx_stream_set_commands[] = {
|
||||
|
||||
{ ngx_string("set"),
|
||||
NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
|
||||
ngx_stream_set,
|
||||
NGX_STREAM_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_stream_module_t ngx_stream_set_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
ngx_stream_set_init, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
ngx_stream_set_create_srv_conf, /* create server configuration */
|
||||
NULL /* merge server configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_stream_set_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_stream_set_module_ctx, /* module context */
|
||||
ngx_stream_set_commands, /* module directives */
|
||||
NGX_STREAM_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_stream_set_handler(ngx_stream_session_t *s)
|
||||
{
|
||||
ngx_str_t str;
|
||||
ngx_uint_t i;
|
||||
ngx_stream_set_cmd_t *cmds;
|
||||
ngx_stream_set_srv_conf_t *scf;
|
||||
ngx_stream_variable_value_t vv;
|
||||
|
||||
scf = ngx_stream_get_module_srv_conf(s, ngx_stream_set_module);
|
||||
cmds = scf->commands.elts;
|
||||
vv = ngx_stream_variable_null_value;
|
||||
|
||||
for (i = 0; i < scf->commands.nelts; i++) {
|
||||
if (ngx_stream_complex_value(s, &cmds[i].value, &str) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (cmds[i].set_handler != NULL) {
|
||||
vv.len = str.len;
|
||||
vv.data = str.data;
|
||||
cmds[i].set_handler(s, &vv, cmds[i].data);
|
||||
|
||||
} else {
|
||||
s->variables[cmds[i].index].len = str.len;
|
||||
s->variables[cmds[i].index].valid = 1;
|
||||
s->variables[cmds[i].index].no_cacheable = 0;
|
||||
s->variables[cmds[i].index].not_found = 0;
|
||||
s->variables[cmds[i].index].data = str.data;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_stream_set_var(ngx_stream_session_t *s, ngx_stream_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
*v = ngx_stream_variable_null_value;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_stream_set_init(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_stream_handler_pt *h;
|
||||
ngx_stream_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
|
||||
|
||||
h = ngx_array_push(&cmcf->phases[NGX_STREAM_PREACCESS_PHASE].handlers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*h = ngx_stream_set_handler;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_stream_set_create_srv_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_stream_set_srv_conf_t *conf;
|
||||
|
||||
conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_set_srv_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->commands = { NULL };
|
||||
*/
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_stream_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_stream_set_srv_conf_t *scf = conf;
|
||||
|
||||
ngx_str_t *args;
|
||||
ngx_int_t index;
|
||||
ngx_stream_set_cmd_t *set_cmd;
|
||||
ngx_stream_variable_t *v;
|
||||
ngx_stream_compile_complex_value_t ccv;
|
||||
|
||||
args = cf->args->elts;
|
||||
|
||||
if (args[1].data[0] != '$') {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid variable name \"%V\"", &args[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
args[1].len--;
|
||||
args[1].data++;
|
||||
|
||||
v = ngx_stream_add_variable(cf, &args[1],
|
||||
NGX_STREAM_VAR_CHANGEABLE|NGX_STREAM_VAR_WEAK);
|
||||
if (v == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
index = ngx_stream_get_variable_index(cf, &args[1]);
|
||||
if (index == NGX_ERROR) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (v->get_handler == NULL) {
|
||||
v->get_handler = ngx_stream_set_var;
|
||||
}
|
||||
|
||||
if (scf->commands.elts == NULL) {
|
||||
if (ngx_array_init(&scf->commands, cf->pool, 1,
|
||||
sizeof(ngx_stream_set_cmd_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
set_cmd = ngx_array_push(&scf->commands);
|
||||
if (set_cmd == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
set_cmd->index = index;
|
||||
set_cmd->set_handler = v->set_handler;
|
||||
set_cmd->data = v->data;
|
||||
|
||||
ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
|
||||
|
||||
ccv.cf = cf;
|
||||
ccv.value = &args[2];
|
||||
ccv.complex_value = &set_cmd->value;
|
||||
|
||||
if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
|
@ -45,6 +45,10 @@ static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
void *conf);
|
||||
static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
static char *ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
|
||||
static ngx_int_t ngx_stream_ssl_init(ngx_conf_t *cf);
|
||||
|
||||
|
||||
|
|
@ -68,6 +72,10 @@ static ngx_conf_enum_t ngx_stream_ssl_verify[] = {
|
|||
};
|
||||
|
||||
|
||||
static ngx_conf_post_t ngx_stream_ssl_conf_command_post =
|
||||
{ ngx_stream_ssl_conf_command_check };
|
||||
|
||||
|
||||
static ngx_command_t ngx_stream_ssl_commands[] = {
|
||||
|
||||
{ ngx_string("ssl_handshake_timeout"),
|
||||
|
|
@ -196,6 +204,13 @@ static ngx_command_t ngx_stream_ssl_commands[] = {
|
|||
offsetof(ngx_stream_ssl_conf_t, crl),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("ssl_conf_command"),
|
||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
|
||||
ngx_conf_set_keyval_slot,
|
||||
NGX_STREAM_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_stream_ssl_conf_t, conf_commands),
|
||||
&ngx_stream_ssl_conf_command_post },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
|
@ -595,6 +610,7 @@ ngx_stream_ssl_create_conf(ngx_conf_t *cf)
|
|||
scf->certificates = NGX_CONF_UNSET_PTR;
|
||||
scf->certificate_keys = NGX_CONF_UNSET_PTR;
|
||||
scf->passwords = NGX_CONF_UNSET_PTR;
|
||||
scf->conf_commands = NGX_CONF_UNSET_PTR;
|
||||
scf->prefer_server_ciphers = NGX_CONF_UNSET;
|
||||
scf->verify = NGX_CONF_UNSET_UINT;
|
||||
scf->verify_depth = NGX_CONF_UNSET_UINT;
|
||||
|
|
@ -650,6 +666,8 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL);
|
||||
|
||||
|
||||
conf->ssl.log = cf->log;
|
||||
|
||||
|
|
@ -811,6 +829,10 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1034,6 +1056,17 @@ invalid:
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_stream_ssl_init(ngx_conf_t *cf)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ typedef struct {
|
|||
ngx_str_t ciphers;
|
||||
|
||||
ngx_array_t *passwords;
|
||||
ngx_array_t *conf_commands;
|
||||
|
||||
ngx_shm_zone_t *shm_zone;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <ngx_stream.h>
|
||||
|
||||
|
||||
#define ngx_stream_upstream_tries(p) ((p)->number \
|
||||
+ ((p)->next ? (p)->next->number : 0))
|
||||
#define ngx_stream_upstream_tries(p) ((p)->tries \
|
||||
+ ((p)->next ? (p)->next->tries : 0))
|
||||
|
||||
|
||||
static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer(
|
||||
|
|
@ -38,7 +38,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
ngx_stream_upstream_srv_conf_t *us)
|
||||
{
|
||||
ngx_url_t u;
|
||||
ngx_uint_t i, j, n, w;
|
||||
ngx_uint_t i, j, n, w, t;
|
||||
ngx_stream_upstream_server_t *server;
|
||||
ngx_stream_upstream_rr_peer_t *peer, **peerp;
|
||||
ngx_stream_upstream_rr_peers_t *peers, *backup;
|
||||
|
|
@ -50,6 +50,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
|
||||
n = 0;
|
||||
w = 0;
|
||||
t = 0;
|
||||
|
||||
for (i = 0; i < us->servers->nelts; i++) {
|
||||
if (server[i].backup) {
|
||||
|
|
@ -58,6 +59,10 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
|
||||
n += server[i].naddrs;
|
||||
w += server[i].naddrs * server[i].weight;
|
||||
|
||||
if (!server[i].down) {
|
||||
t += server[i].naddrs;
|
||||
}
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
|
|
@ -81,6 +86,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
peers->number = n;
|
||||
peers->weighted = (w != n);
|
||||
peers->total_weight = w;
|
||||
peers->tries = t;
|
||||
peers->name = &us->host;
|
||||
|
||||
n = 0;
|
||||
|
|
@ -116,6 +122,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
|
||||
n = 0;
|
||||
w = 0;
|
||||
t = 0;
|
||||
|
||||
for (i = 0; i < us->servers->nelts; i++) {
|
||||
if (!server[i].backup) {
|
||||
|
|
@ -124,6 +131,10 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
|
||||
n += server[i].naddrs;
|
||||
w += server[i].naddrs * server[i].weight;
|
||||
|
||||
if (!server[i].down) {
|
||||
t += server[i].naddrs;
|
||||
}
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
|
|
@ -145,6 +156,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
backup->number = n;
|
||||
backup->weighted = (w != n);
|
||||
backup->total_weight = w;
|
||||
backup->tries = t;
|
||||
backup->name = &us->host;
|
||||
|
||||
n = 0;
|
||||
|
|
@ -220,6 +232,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
|
|||
peers->number = n;
|
||||
peers->weighted = 0;
|
||||
peers->total_weight = n;
|
||||
peers->tries = n;
|
||||
peers->name = &us->host;
|
||||
|
||||
peerp = &peers->peer;
|
||||
|
|
@ -342,6 +355,7 @@ ngx_stream_upstream_create_round_robin_peer(ngx_stream_session_t *s,
|
|||
|
||||
peers->single = (ur->naddrs == 1);
|
||||
peers->number = ur->naddrs;
|
||||
peers->tries = ur->naddrs;
|
||||
peers->name = &ur->host;
|
||||
|
||||
if (ur->sockaddr) {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ struct ngx_stream_upstream_rr_peers_s {
|
|||
#endif
|
||||
|
||||
ngx_uint_t total_weight;
|
||||
ngx_uint_t tries;
|
||||
|
||||
unsigned single:1;
|
||||
unsigned weighted:1;
|
||||
|
|
|
|||
|
|
@ -234,7 +234,8 @@ ngx_stream_write_filter(ngx_stream_session_t *s, ngx_chain_t *in,
|
|||
|
||||
if (size == 0
|
||||
&& !(c->buffered & NGX_LOWLEVEL_BUFFERED)
|
||||
&& !(last && c->need_last_buf))
|
||||
&& !(last && c->need_last_buf)
|
||||
&& !(c->type == SOCK_DGRAM && flush))
|
||||
{
|
||||
if (last || flush || sync) {
|
||||
for (cl = *out; cl; /* void */) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue