Merged with the default branch.

This commit is contained in:
Sergey Kandaurov 2023-03-29 11:14:25 +04:00
commit e8fbc96747
36 changed files with 1105 additions and 180 deletions

View File

@ -471,3 +471,4 @@ d986378168fd4d70e0121cabac274c560cca9bdf release-1.21.5
a63d0a70afea96813ba6667997bc7d68b5863f0d release-1.23.1
aa901551a7ebad1e8b0f8c11cb44e3424ba29707 release-1.23.2
ff3afd1ce6a6b65057741df442adfaa71a0e2588 release-1.23.3
ac779115ed6ee4f3039e9aea414a54e560450ee2 release-1.23.4

View File

@ -117,7 +117,7 @@ else
. auto/cc/acc
;;
msvc*)
msvc)
# MSVC++ 6.0 SP2, MSVC++ Toolkit 2003
. auto/cc/msvc

View File

@ -11,8 +11,8 @@
# MSVC 2015 (14.0) cl 19.00
NGX_MSVC_VER=`$NGX_WINE $CC 2>&1 | grep 'Compiler Version' 2>&1 \
| sed -e 's/^.* Version \(.*\)/\1/'`
NGX_MSVC_VER=`$NGX_WINE $CC 2>&1 | grep 'C/C++.* [0-9][0-9]*\.[0-9]' 2>&1 \
| sed -e 's/^.* \([0-9][0-9]*\.[0-9].*\)/\1/'`
echo " + cl version: $NGX_MSVC_VER"
@ -22,6 +22,21 @@ have=NGX_COMPILER value="\"cl $NGX_MSVC_VER\"" . auto/define
ngx_msvc_ver=`echo $NGX_MSVC_VER | sed -e 's/^\([0-9]*\).*/\1/'`
# detect x64 builds
case "$NGX_MSVC_VER" in
*x64)
NGX_MACHINE=amd64
;;
*)
NGX_MACHINE=i386
;;
esac
# optimizations
# maximize speed, equivalent to -Og -Oi -Ot -Oy -Ob2 -Gs -GF -Gy

1
auto/configure vendored
View File

@ -44,6 +44,7 @@ if test -z "$NGX_PLATFORM"; then
else
echo "building for $NGX_PLATFORM"
NGX_SYSTEM=$NGX_PLATFORM
NGX_MACHINE=i386
fi
. auto/cc/conf

View File

@ -7,11 +7,24 @@ case "$CC" in
cl)
case "$NGX_MACHINE" in
amd64)
OPENSSL_TARGET=VC-WIN64A
;;
*)
OPENSSL_TARGET=VC-WIN32
;;
esac
cat << END >> $NGX_MAKEFILE
$OPENSSL/openssl/include/openssl/ssl.h: $NGX_MAKEFILE
\$(MAKE) -f auto/lib/openssl/makefile.msvc \
OPENSSL="$OPENSSL" OPENSSL_OPT="$OPENSSL_OPT"
OPENSSL="$OPENSSL" OPENSSL_OPT="$OPENSSL_OPT" \
OPENSSL_TARGET="$OPENSSL_TARGET"
END

View File

@ -6,7 +6,7 @@
all:
cd $(OPENSSL)
perl Configure VC-WIN32 no-shared no-threads \
perl Configure $(OPENSSL_TARGET) no-shared no-threads \
--prefix="%cd%/openssl" \
--openssldir="%cd%/openssl/ssl" \
$(OPENSSL_OPT)

View File

@ -282,7 +282,6 @@ ngx_feature="UDP_SEGMENT"
ngx_feature_name="NGX_HAVE_UDP_SEGMENT"
ngx_feature_run=no
ngx_feature_incs="#include <sys/socket.h>
#include <stdint.h>
#include <netinet/udp.h>"
ngx_feature_path=
ngx_feature_libs=

View File

@ -5,6 +5,163 @@
<change_log title="nginx">
<changes ver="1.23.4" date="2023-03-28">
<change type="change">
<para lang="ru">
теперь протокол TLSv1.3 разрешён по умолчанию.
</para>
<para lang="en">
now TLSv1.3 protocol is enabled by default.
</para>
</change>
<change type="change">
<para lang="ru">
теперь nginx выдаёт предупреждение
при переопределении параметров listen-сокета, задающих используемые протоколы.
</para>
<para lang="en">
now nginx issues a warning
if protocol parameters of a listening socket are redefined.
</para>
</change>
<change type="change">
<para lang="ru">
теперь, если клиент использует pipelining,
nginx закрывает соединения с ожиданием дополнительных данных (lingering close).
</para>
<para lang="en">
now nginx closes connections with lingering
if pipelining was used by the client.
</para>
</change>
<change type="feature">
<para lang="ru">
поддержка byte ranges для ответов модуля ngx_http_gzip_static_module.
</para>
<para lang="en">
byte ranges support in the ngx_http_gzip_static_module.
</para>
</change>
<change type="bugfix">
<para lang="ru">
диапазоны портов в директиве listen не работали;
ошибка появилась в 1.23.3.<br/>
Спасибо Валентину Бартеневу.
</para>
<para lang="en">
port ranges in the "listen" directive did not work;
the bug had appeared in 1.23.3.<br/>
Thanks to Valentin Bartenev.
</para>
</change>
<change type="bugfix">
<para lang="ru">
для обработки запроса мог быть выбран неверный location,
если в конфигурации использовался
префиксный location длиннее 255 символов.
</para>
<para lang="en">
incorrect location might be chosen to process a request
if a prefix location longer than 255 characters
was used in the configuration.
</para>
</change>
<change type="bugfix">
<para lang="ru">
не-ASCII символы в именах файлов на Windows
не поддерживались модулями ngx_http_autoindex_module и
ngx_http_dav_module, а также директивой include.
</para>
<para lang="en">
non-ASCII characters in file names on Windows were not supported
by the ngx_http_autoindex_module, the ngx_http_dav_module,
and the "include" directive.
</para>
</change>
<change type="change">
<para lang="ru">
уровень логгирования ошибок SSL
"data length too long", "length too short", "bad legacy version",
"no shared signature algorithms", "bad digest length",
"missing sigalgs extension", "encrypted length too long",
"bad length", "bad key update", "mixed handshake and non handshake data",
"ccs received early", "data between ccs and finished",
"packet length too long", "too many warn alerts", "record too small",
и "got a fin before a ccs"
понижен с уровня crit до info.
</para>
<para lang="en">
the logging level of the
"data length too long", "length too short", "bad legacy version",
"no shared signature algorithms", "bad digest length",
"missing sigalgs extension", "encrypted length too long",
"bad length", "bad key update", "mixed handshake and non handshake data",
"ccs received early", "data between ccs and finished",
"packet length too long", "too many warn alerts", "record too small",
and "got a fin before a ccs" SSL errors
has been lowered from "crit" to "info".
</para>
</change>
<change type="bugfix">
<para lang="ru">
при использовании HTTP/2 и директивы error_page
для перенаправления ошибок с кодом 400
могла происходить утечка сокетов.
</para>
<para lang="en">
a socket leak might occur
when using HTTP/2 and the "error_page" directive
to redirect errors with code 400.
</para>
</change>
<change type="bugfix">
<para lang="ru">
сообщения об ошибках записи в syslog
не содержали информации о том, что
ошибки происходили в процессе записи в syslog.<br/>
Спасибо Safar Safarly.
</para>
<para lang="en">
messages about logging to syslog errors
did not contain information
that the errors happened while logging to syslog.<br/>
Thanks to Safar Safarly.
</para>
</change>
<change type="workaround">
<para lang="ru">
при использовании zlib-ng
в логах появлялись сообщения "gzip filter failed to use preallocated memory".
</para>
<para lang="en">
"gzip filter failed to use preallocated memory" alerts appeared in logs
when using zlib-ng.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в почтовом прокси-сервере.
</para>
<para lang="en">
in the mail proxy server.
</para>
</change>
</changes>
<changes ver="1.23.3" date="2022-12-13">
<change type="bugfix">

View File

@ -6,7 +6,7 @@ TEMP = tmp
CC = cl
OBJS = objs.msvc8
OPENSSL = openssl-1.1.1s
OPENSSL = openssl-1.1.1t
ZLIB = zlib-1.2.13
PCRE = pcre2-10.39

View File

@ -177,6 +177,7 @@ struct ngx_connection_s {
unsigned timedout:1;
unsigned error:1;
unsigned destroyed:1;
unsigned pipeline:1;
unsigned idle:1;
unsigned reusable:1;

View File

@ -1364,7 +1364,12 @@ ngx_utf8_decode(u_char **p, size_t n)
u = **p;
if (u >= 0xf0) {
if (u >= 0xf8) {
(*p)++;
return 0xffffffff;
} else if (u >= 0xf0) {
u &= 0x07;
valid = 0xffff;

View File

@ -18,6 +18,7 @@
static char *ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer);
static ngx_int_t ngx_syslog_init_peer(ngx_syslog_peer_t *peer);
static void ngx_syslog_cleanup(void *data);
static u_char *ngx_syslog_log_error(ngx_log_t *log, u_char *buf, size_t len);
static char *facilities[] = {
@ -66,6 +67,9 @@ ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer)
ngx_str_set(&peer->tag, "nginx");
}
peer->hostname = &cf->cycle->hostname;
peer->logp = &cf->cycle->new_log;
peer->conn.fd = (ngx_socket_t) -1;
peer->conn.read = &ngx_syslog_dummy_event;
@ -243,7 +247,7 @@ ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf)
}
return ngx_sprintf(buf, "<%ui>%V %V %V: ", pri, &ngx_cached_syslog_time,
&ngx_cycle->hostname, &peer->tag);
peer->hostname, &peer->tag);
}
@ -286,15 +290,19 @@ ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len)
{
ssize_t n;
if (peer->log.handler == NULL) {
peer->log = *peer->logp;
peer->log.handler = ngx_syslog_log_error;
peer->log.data = peer;
peer->log.action = "logging to syslog";
}
if (peer->conn.fd == (ngx_socket_t) -1) {
if (ngx_syslog_init_peer(peer) != NGX_OK) {
return NGX_ERROR;
}
}
/* log syslog socket events with valid log */
peer->conn.log = ngx_cycle->log;
if (ngx_send) {
n = ngx_send(&peer->conn, buf, len);
@ -306,7 +314,7 @@ ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len)
if (n == NGX_ERROR) {
if (ngx_close_socket(peer->conn.fd) == -1) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
@ -324,24 +332,25 @@ ngx_syslog_init_peer(ngx_syslog_peer_t *peer)
fd = ngx_socket(peer->server.sockaddr->sa_family, SOCK_DGRAM, 0);
if (fd == (ngx_socket_t) -1) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
ngx_socket_n " failed");
return NGX_ERROR;
}
if (ngx_nonblocking(fd) == -1) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
ngx_nonblocking_n " failed");
goto failed;
}
if (connect(fd, peer->server.sockaddr, peer->server.socklen) == -1) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
"connect() failed");
goto failed;
}
peer->conn.fd = fd;
peer->conn.log = &peer->log;
/* UDP sockets are always ready to write */
peer->conn.write->ready = 1;
@ -351,7 +360,7 @@ ngx_syslog_init_peer(ngx_syslog_peer_t *peer)
failed:
if (ngx_close_socket(fd) == -1) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
@ -372,7 +381,30 @@ ngx_syslog_cleanup(void *data)
}
if (ngx_close_socket(peer->conn.fd) == -1) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
}
static u_char *
ngx_syslog_log_error(ngx_log_t *log, u_char *buf, size_t len)
{
u_char *p;
ngx_syslog_peer_t *peer;
p = buf;
if (log->action) {
p = ngx_snprintf(buf, len, " while %s", log->action);
len -= p - buf;
}
peer = log->data;
if (peer) {
p = ngx_snprintf(p, len, ", server: %V", &peer->server.name);
}
return p;
}

View File

@ -9,14 +9,20 @@
typedef struct {
ngx_uint_t facility;
ngx_uint_t severity;
ngx_str_t tag;
ngx_uint_t facility;
ngx_uint_t severity;
ngx_str_t tag;
ngx_addr_t server;
ngx_connection_t conn;
unsigned busy:1;
unsigned nohostname:1;
ngx_str_t *hostname;
ngx_addr_t server;
ngx_connection_t conn;
ngx_log_t log;
ngx_log_t *logp;
unsigned busy:1;
unsigned nohostname:1;
} ngx_syslog_peer_t;

View File

@ -127,8 +127,8 @@ void ngx_iocp_wait_events(int main)
conn[0] = NULL;
for ( ;; ) {
offset = (nevents == WSA_MAXIMUM_WAIT_EVENTS + 1) ? 1: 0;
timeout = (nevents == 1 && !first) ? 60000: INFINITE;
offset = (nevents == WSA_MAXIMUM_WAIT_EVENTS + 1) ? 1 : 0;
timeout = (nevents == 1 && !first) ? 60000 : INFINITE;
n = WSAWaitForMultipleEvents(nevents - offset, events[offset],
0, timeout, 0);

View File

@ -3393,29 +3393,58 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
} else if (sslerr == SSL_ERROR_SSL) {
n = ERR_GET_REASON(ERR_peek_error());
n = ERR_GET_REASON(ERR_peek_last_error());
/* handshake failures */
if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */
#ifdef SSL_R_NO_SUITABLE_KEY_SHARE
|| n == SSL_R_NO_SUITABLE_KEY_SHARE /* 101 */
#endif
#ifdef SSL_R_BAD_ALERT
|| n == SSL_R_BAD_ALERT /* 102 */
#endif
#ifdef SSL_R_BAD_KEY_SHARE
|| n == SSL_R_BAD_KEY_SHARE /* 108 */
#endif
#ifdef SSL_R_BAD_EXTENSION
|| n == SSL_R_BAD_EXTENSION /* 110 */
#endif
|| n == SSL_R_BAD_DIGEST_LENGTH /* 111 */
#ifdef SSL_R_MISSING_SIGALGS_EXTENSION
|| n == SSL_R_MISSING_SIGALGS_EXTENSION /* 112 */
#endif
|| n == SSL_R_BAD_PACKET_LENGTH /* 115 */
#ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM
|| n == SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM /* 118 */
#endif
#ifdef SSL_R_BAD_KEY_UPDATE
|| n == SSL_R_BAD_KEY_UPDATE /* 122 */
#endif
|| n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */
|| n == SSL_R_CCS_RECEIVED_EARLY /* 133 */
#ifdef SSL_R_DECODE_ERROR
|| n == SSL_R_DECODE_ERROR /* 137 */
#endif
#ifdef SSL_R_DATA_BETWEEN_CCS_AND_FINISHED
|| n == SSL_R_DATA_BETWEEN_CCS_AND_FINISHED /* 145 */
#endif
|| n == SSL_R_DATA_LENGTH_TOO_LONG /* 146 */
|| n == SSL_R_DIGEST_CHECK_FAILED /* 149 */
|| n == SSL_R_ENCRYPTED_LENGTH_TOO_LONG /* 150 */
|| n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */
|| n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */
#ifdef SSL_R_GOT_A_FIN_BEFORE_A_CCS
|| n == SSL_R_GOT_A_FIN_BEFORE_A_CCS /* 154 */
#endif
|| n == SSL_R_HTTPS_PROXY_REQUEST /* 155 */
|| n == SSL_R_HTTP_REQUEST /* 156 */
|| n == SSL_R_LENGTH_MISMATCH /* 159 */
#ifdef SSL_R_LENGTH_TOO_SHORT
|| n == SSL_R_LENGTH_TOO_SHORT /* 160 */
#endif
#ifdef SSL_R_NO_RENEGOTIATION
|| n == SSL_R_NO_RENEGOTIATION /* 182 */
#endif
#ifdef SSL_R_NO_CIPHERS_PASSED
|| n == SSL_R_NO_CIPHERS_PASSED /* 182 */
#endif
@ -3425,7 +3454,13 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
#endif
|| n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */
|| n == SSL_R_NO_SHARED_CIPHER /* 193 */
#ifdef SSL_R_PACKET_LENGTH_TOO_LONG
|| n == SSL_R_PACKET_LENGTH_TOO_LONG /* 198 */
#endif
|| n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */
#ifdef SSL_R_TOO_MANY_WARNING_ALERTS
|| n == SSL_R_TOO_MANY_WARNING_ALERTS /* 220 */
#endif
#ifdef SSL_R_CLIENTHELLO_TLSEXT
|| n == SSL_R_CLIENTHELLO_TLSEXT /* 226 */
#endif
@ -3435,6 +3470,9 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
#ifdef SSL_R_CALLBACK_FAILED
|| n == SSL_R_CALLBACK_FAILED /* 234 */
#endif
#ifdef SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
|| n == SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG /* 234 */
#endif
#ifdef SSL_R_NO_APPLICATION_PROTOCOL
|| n == SSL_R_NO_APPLICATION_PROTOCOL /* 235 */
#endif
@ -3444,12 +3482,22 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|| n == SSL_R_UNKNOWN_PROTOCOL /* 252 */
#ifdef SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS
|| n == SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS /* 253 */
#endif
#ifdef SSL_R_INVALID_COMPRESSION_LIST
|| n == SSL_R_INVALID_COMPRESSION_LIST /* 256 */
#endif
#ifdef SSL_R_MISSING_KEY_SHARE
|| n == SSL_R_MISSING_KEY_SHARE /* 258 */
#endif
|| n == SSL_R_UNSUPPORTED_PROTOCOL /* 258 */
#ifdef SSL_R_NO_SHARED_GROUP
|| n == SSL_R_NO_SHARED_GROUP /* 266 */
#endif
|| n == SSL_R_WRONG_VERSION_NUMBER /* 267 */
#ifdef SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA
|| n == SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA /* 270 */
#endif
|| n == SSL_R_BAD_LENGTH /* 271 */
|| n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */
#ifdef SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY
|| n == SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY /* 291 */
@ -3457,6 +3505,18 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
#ifdef SSL_R_APPLICATION_DATA_ON_SHUTDOWN
|| n == SSL_R_APPLICATION_DATA_ON_SHUTDOWN /* 291 */
#endif
#ifdef SSL_R_BAD_LEGACY_VERSION
|| n == SSL_R_BAD_LEGACY_VERSION /* 292 */
#endif
#ifdef SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA
|| n == SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA /* 293 */
#endif
#ifdef SSL_R_RECORD_TOO_SMALL
|| n == SSL_R_RECORD_TOO_SMALL /* 298 */
#endif
#ifdef SSL_R_SSL3_SESSION_ID_TOO_LONG
|| n == SSL_R_SSL3_SESSION_ID_TOO_LONG /* 300 */
#endif
#ifdef SSL_R_BAD_ECPOINT
|| n == SSL_R_BAD_ECPOINT /* 306 */
#endif
@ -3474,12 +3534,21 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
#ifdef SSL_R_INAPPROPRIATE_FALLBACK
|| n == SSL_R_INAPPROPRIATE_FALLBACK /* 373 */
#endif
#ifdef SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS
|| n == SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS /* 376 */
#endif
#ifdef SSL_R_NO_SHARED_SIGATURE_ALGORITHMS
|| n == SSL_R_NO_SHARED_SIGATURE_ALGORITHMS /* 376 */
#endif
#ifdef SSL_R_CERT_CB_ERROR
|| n == SSL_R_CERT_CB_ERROR /* 377 */
#endif
#ifdef SSL_R_VERSION_TOO_LOW
|| n == SSL_R_VERSION_TOO_LOW /* 396 */
#endif
#ifdef SSL_R_TOO_MANY_WARN_ALERTS
|| n == SSL_R_TOO_MANY_WARN_ALERTS /* 409 */
#endif
#ifdef SSL_R_BAD_RECORD_TYPE
|| n == SSL_R_BAD_RECORD_TYPE /* 443 */
#endif

View File

@ -232,9 +232,10 @@ ngx_http_flv_handler(ngx_http_request_t *r)
b->file_pos = start;
b->file_last = of.size;
b->in_file = b->file_last ? 1: 0;
b->in_file = b->file_last ? 1 : 0;
b->last_buf = (r == r->main) ? 1 : 0;
b->last_in_chain = 1;
b->sync = (b->last_buf || b->in_file) ? 0 : 1;
b->file->fd = of.fd;
b->file->name = path;

View File

@ -4473,8 +4473,9 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->upstream.ssl_session_reuse, 1);
ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
(NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
|NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
(NGX_CONF_BITMASK_SET
|NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
|NGX_SSL_TLSv1_2|NGX_SSL_TLSv1_3));
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
"DEFAULT");

View File

@ -57,6 +57,7 @@ typedef struct {
unsigned nomem:1;
unsigned buffering:1;
unsigned zlib_ng:1;
unsigned state_allocated:1;
size_t zin;
size_t zout;
@ -514,9 +515,10 @@ ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
} else {
/*
* 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.
* It used to force window bits to 13 for fast compression level,
* uses (64 + sizeof(void*)) additional space on all allocations
* for alignment, 16-byte padding in one of window-sized buffers,
* and 128K hash.
*/
if (conf->level == 1) {
@ -524,7 +526,8 @@ ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
}
ctx->allocated = 8192 + 16 + (1 << (wbits + 2))
+ 131072 + (1 << (memlevel + 8));
+ 131072 + (1 << (memlevel + 8))
+ 4 * (64 + sizeof(void*));
ctx->zlib_ng = 1;
}
}
@ -926,13 +929,16 @@ ngx_http_gzip_filter_alloc(void *opaque, u_int items, u_int size)
alloc = items * size;
if (items == 1 && alloc % 512 != 0 && alloc < 8192) {
if (items == 1 && alloc % 512 != 0 && alloc < 8192
&& !ctx->state_allocated)
{
/*
* The zlib deflate_state allocation, it takes about 6K,
* we allocate 8K. Other allocations are divisible by 512.
*/
ctx->state_allocated = 1;
alloc = 8192;
}

View File

@ -247,6 +247,8 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
ngx_str_set(&h->value, "gzip");
r->headers_out.content_encoding = h;
r->allow_ranges = 1;
/* we need to allocate all before the header would be sent */
b = ngx_calloc_buf(r->pool);
@ -271,6 +273,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
b->in_file = b->file_last ? 1 : 0;
b->last_buf = (r == r->main) ? 1 : 0;
b->last_in_chain = 1;
b->sync = (b->last_buf || b->in_file) ? 0 : 1;
b->file->fd = of.fd;
b->file->name = path;

View File

@ -714,6 +714,7 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
b->in_file = b->file_last ? 1 : 0;
b->last_buf = (r == r->main) ? 1 : 0;
b->last_in_chain = 1;
b->sync = (b->last_buf || b->in_file) ? 0 : 1;
b->file->fd = of.fd;
b->file->name = path;

View File

@ -3734,8 +3734,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->upstream.ssl_session_reuse, 1);
ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
(NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
|NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
(NGX_CONF_BITMASK_SET
|NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
|NGX_SSL_TLSv1_2|NGX_SSL_TLSv1_3));
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
"DEFAULT");

View File

@ -670,8 +670,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
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
|NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
(NGX_CONF_BITMASK_SET
|NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
|NGX_SSL_TLSv1_2|NGX_SSL_TLSv1_3));
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
NGX_SSL_BUFSIZE);

View File

@ -238,10 +238,6 @@ ngx_http_static_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
if (r != r->main && of.size == 0) {
return ngx_http_send_header(r);
}
r->allow_ranges = 1;
/* we need to allocate all before the header would be sent */
@ -265,9 +261,10 @@ ngx_http_static_handler(ngx_http_request_t *r)
b->file_pos = 0;
b->file_last = of.size;
b->in_file = b->file_last ? 1: 0;
b->last_buf = (r == r->main) ? 1: 0;
b->in_file = b->file_last ? 1 : 0;
b->last_buf = (r == r->main) ? 1 : 0;
b->last_in_chain = 1;
b->sync = (b->last_buf || b->in_file) ? 0 : 1;
b->file->fd = of.fd;
b->file->name = path;

View File

@ -1875,8 +1875,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->upstream.ssl_session_reuse, 1);
ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
(NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
|NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
(NGX_CONF_BITMASK_SET
|NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
|NGX_SSL_TLSv1_2|NGX_SSL_TLSv1_3));
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
"DEFAULT");

View File

@ -1130,7 +1130,7 @@ ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
node->auto_redirect = (u_char) ((lq->exact && lq->exact->auto_redirect)
|| (lq->inclusive && lq->inclusive->auto_redirect));
node->len = (u_char) len;
node->len = (u_short) len;
ngx_memcpy(node->name, &lq->name->data[prefix], len);
ngx_queue_split(locations, q, &tail);
@ -1232,7 +1232,8 @@ static ngx_int_t
ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt)
{
ngx_uint_t i, default_server, proxy_protocol;
ngx_uint_t i, default_server, proxy_protocol,
protocols, protocols_prev;
ngx_http_conf_addr_t *addr;
#if (NGX_HTTP_SSL)
ngx_uint_t ssl;
@ -1272,12 +1273,18 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
default_server = addr[i].opt.default_server;
proxy_protocol = lsopt->proxy_protocol || addr[i].opt.proxy_protocol;
protocols = lsopt->proxy_protocol;
protocols_prev = addr[i].opt.proxy_protocol;
#if (NGX_HTTP_SSL)
ssl = lsopt->ssl || addr[i].opt.ssl;
protocols |= lsopt->ssl << 1;
protocols_prev |= addr[i].opt.ssl << 1;
#endif
#if (NGX_HTTP_V2)
http2 = lsopt->http2 || addr[i].opt.http2;
protocols |= lsopt->http2 << 2;
protocols_prev |= addr[i].opt.http2 << 2;
#endif
#if (NGX_HTTP_V3)
http3 = lsopt->http3 || addr[i].opt.http3;
@ -1311,6 +1318,57 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
addr[i].default_server = cscf;
}
/* check for conflicting protocol options */
if ((protocols | protocols_prev) != protocols_prev) {
/* options added */
if ((addr[i].opt.set && !lsopt->set)
|| addr[i].protocols_changed
|| (protocols | protocols_prev) != protocols)
{
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"protocol options redefined for %V",
&addr[i].opt.addr_text);
}
addr[i].protocols = protocols_prev;
addr[i].protocols_set = 1;
addr[i].protocols_changed = 1;
} else if ((protocols_prev | protocols) != protocols) {
/* options removed */
if (lsopt->set
|| (addr[i].protocols_set && protocols != addr[i].protocols))
{
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"protocol options redefined for %V",
&addr[i].opt.addr_text);
}
addr[i].protocols = protocols;
addr[i].protocols_set = 1;
addr[i].protocols_changed = 1;
} else {
/* the same options */
if ((lsopt->set && addr[i].protocols_changed)
|| (addr[i].protocols_set && protocols != addr[i].protocols))
{
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"protocol options redefined for %V",
&addr[i].opt.addr_text);
}
addr[i].protocols = protocols;
addr[i].protocols_set = 1;
}
addr[i].opt.default_server = default_server;
addr[i].opt.proxy_protocol = proxy_protocol;
#if (NGX_HTTP_SSL)
@ -1371,6 +1429,9 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
}
addr->opt = *lsopt;
addr->protocols = 0;
addr->protocols_set = 0;
addr->protocols_changed = 0;
addr->hash.buckets = NULL;
addr->hash.size = 0;
addr->wc_head = NULL;

View File

@ -1803,10 +1803,6 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
}
}
if (r != r->main && val.len == 0) {
return ngx_http_send_header(r);
}
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@ -1817,6 +1813,7 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
b->memory = val.len ? 1 : 0;
b->last_buf = (r == r->main) ? 1 : 0;
b->last_in_chain = 1;
b->sync = (b->last_buf || b->memory) ? 0 : 1;
out.buf = b;
out.next = NULL;

View File

@ -280,6 +280,10 @@ typedef struct {
typedef struct {
ngx_http_listen_opt_t opt;
unsigned protocols:3;
unsigned protocols_set:1;
unsigned protocols_changed:1;
ngx_hash_t hash;
ngx_hash_wildcard_t *wc_head;
ngx_hash_wildcard_t *wc_tail;
@ -469,8 +473,8 @@ struct ngx_http_location_tree_node_s {
ngx_http_core_loc_conf_t *exact;
ngx_http_core_loc_conf_t *inclusive;
u_short len;
u_char auto_redirect;
u_char len;
u_char name[1];
};

View File

@ -1575,10 +1575,6 @@ ngx_http_cache_send(ngx_http_request_t *r)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http file cache send: %s", c->file.name.data);
if (r != r->main && c->length - c->body_start == 0) {
return ngx_http_send_header(r);
}
/* we need to allocate all before the header would be sent */
b = ngx_calloc_buf(r->pool);
@ -1600,9 +1596,10 @@ ngx_http_cache_send(ngx_http_request_t *r)
b->file_pos = c->body_start;
b->file_last = c->length;
b->in_file = (c->length - c->body_start) ? 1: 0;
b->last_buf = (r == r->main) ? 1: 0;
b->in_file = (c->length - c->body_start) ? 1 : 0;
b->last_buf = (r == r->main) ? 1 : 0;
b->last_in_chain = 1;
b->sync = (b->last_buf || b->in_file) ? 0 : 1;
b->file->fd = c->file.fd;
b->file->name = c->file.name;

View File

@ -2770,7 +2770,8 @@ ngx_http_finalize_connection(ngx_http_request_t *r)
|| (clcf->lingering_close == NGX_HTTP_LINGERING_ON
&& (r->lingering_close
|| r->header_in->pos < r->header_in->last
|| r->connection->read->ready)))
|| r->connection->read->ready
|| r->connection->pipeline)))
{
ngx_http_set_lingering_close(r->connection);
return;
@ -3154,6 +3155,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
c->sent = 0;
c->destroyed = 0;
c->pipeline = 1;
if (rev->timer_set) {
ngx_del_timer(rev);

View File

@ -1730,6 +1730,7 @@ ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c, u_char *pos,
size_t len;
ngx_int_t rc;
ngx_table_elt_t *h;
ngx_connection_t *fc;
ngx_http_header_t *hh;
ngx_http_request_t *r;
ngx_http_v2_header_t *header;
@ -1789,17 +1790,11 @@ ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c, u_char *pos,
}
r = h2c->state.stream->request;
fc = r->connection;
/* TODO Optimization: validate headers while parsing. */
if (ngx_http_v2_validate_header(r, header) != NGX_OK) {
if (ngx_http_v2_terminate_stream(h2c, h2c->state.stream,
NGX_HTTP_V2_PROTOCOL_ERROR)
== NGX_ERROR)
{
return ngx_http_v2_connection_error(h2c,
NGX_HTTP_V2_INTERNAL_ERROR);
}
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
goto error;
}
@ -1886,6 +1881,8 @@ error:
h2c->state.stream = NULL;
ngx_http_run_posted_requests(fc);
return ngx_http_v2_state_header_complete(h2c, pos, end);
}

View File

@ -327,7 +327,9 @@ ngx_mail_proxy_pop3_handler(ngx_event_t *rev)
c->log->action = NULL;
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
if (s->buffer->pos < s->buffer->last) {
if (s->buffer->pos < s->buffer->last
|| s->connection->read->ready)
{
ngx_post_event(c->write, &ngx_posted_events);
}
@ -486,7 +488,9 @@ ngx_mail_proxy_imap_handler(ngx_event_t *rev)
c->log->action = NULL;
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
if (s->buffer->pos < s->buffer->last) {
if (s->buffer->pos < s->buffer->last
|| s->connection->read->ready)
{
ngx_post_event(c->write, &ngx_posted_events);
}
@ -821,7 +825,9 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
c->log->action = NULL;
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
if (s->buffer->pos < s->buffer->last) {
if (s->buffer->pos < s->buffer->last
|| s->connection->read->ready)
{
ngx_post_event(c->write, &ngx_posted_events);
}

View File

@ -360,8 +360,9 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
prev->prefer_server_ciphers, 0);
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
(NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
|NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
(NGX_CONF_BITMASK_SET
|NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
|NGX_SSL_TLSv1_2|NGX_SSL_TLSv1_3));
ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);

View File

@ -10,10 +10,15 @@
#define NGX_UTF16_BUFLEN 256
#define NGX_UTF8_BUFLEN 512
static ngx_int_t ngx_win32_check_filename(u_char *name, u_short *u,
size_t len);
static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len);
static ngx_int_t ngx_win32_check_filename(u_short *u, size_t len,
ngx_uint_t dirname);
static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len,
size_t reserved);
static u_char *ngx_utf16_to_utf8(u_char *utf8, u_short *utf16, size_t *len,
size_t *allocated);
uint32_t ngx_utf16_decode(u_short **u, size_t n);
/* FILE_FLAG_BACKUP_SEMANTICS allows to obtain a handle to a directory */
@ -28,7 +33,7 @@ ngx_open_file(u_char *name, u_long mode, u_long create, u_long access)
u_short utf16[NGX_UTF16_BUFLEN];
len = NGX_UTF16_BUFLEN;
u = ngx_utf8_to_utf16(utf16, name, &len);
u = ngx_utf8_to_utf16(utf16, name, &len, 0);
if (u == NULL) {
return INVALID_HANDLE_VALUE;
@ -37,7 +42,7 @@ ngx_open_file(u_char *name, u_long mode, u_long create, u_long access)
fd = INVALID_HANDLE_VALUE;
if (create == NGX_FILE_OPEN
&& ngx_win32_check_filename(name, u, len) != NGX_OK)
&& ngx_win32_check_filename(u, len, 0) != NGX_OK)
{
goto failed;
}
@ -58,6 +63,41 @@ failed:
}
ngx_fd_t
ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
{
size_t len;
u_short *u;
ngx_fd_t fd;
ngx_err_t err;
u_short utf16[NGX_UTF16_BUFLEN];
len = NGX_UTF16_BUFLEN;
u = ngx_utf8_to_utf16(utf16, name, &len, 0);
if (u == NULL) {
return INVALID_HANDLE_VALUE;
}
fd = CreateFileW(u,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
CREATE_NEW,
persistent ? 0:
FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,
NULL);
if (u != utf16) {
err = ngx_errno;
ngx_free(u);
ngx_set_errno(err);
}
return fd;
}
ssize_t
ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
{
@ -202,6 +242,97 @@ ngx_write_console(ngx_fd_t fd, void *buf, size_t size)
}
ngx_int_t
ngx_delete_file(u_char *name)
{
long rc;
size_t len;
u_short *u;
ngx_err_t err;
u_short utf16[NGX_UTF16_BUFLEN];
len = NGX_UTF16_BUFLEN;
u = ngx_utf8_to_utf16(utf16, name, &len, 0);
if (u == NULL) {
return NGX_FILE_ERROR;
}
rc = NGX_FILE_ERROR;
if (ngx_win32_check_filename(u, len, 0) != NGX_OK) {
goto failed;
}
rc = DeleteFileW(u);
failed:
if (u != utf16) {
err = ngx_errno;
ngx_free(u);
ngx_set_errno(err);
}
return rc;
}
ngx_int_t
ngx_rename_file(u_char *from, u_char *to)
{
long rc;
size_t len;
u_short *fu, *tu;
ngx_err_t err;
u_short utf16f[NGX_UTF16_BUFLEN];
u_short utf16t[NGX_UTF16_BUFLEN];
len = NGX_UTF16_BUFLEN;
fu = ngx_utf8_to_utf16(utf16f, from, &len, 0);
if (fu == NULL) {
return NGX_FILE_ERROR;
}
rc = NGX_FILE_ERROR;
tu = NULL;
if (ngx_win32_check_filename(fu, len, 0) != NGX_OK) {
goto failed;
}
len = NGX_UTF16_BUFLEN;
tu = ngx_utf8_to_utf16(utf16t, to, &len, 0);
if (tu == NULL) {
goto failed;
}
if (ngx_win32_check_filename(tu, len, 1) != NGX_OK) {
goto failed;
}
rc = MoveFileW(fu, tu);
failed:
if (fu != utf16f) {
err = ngx_errno;
ngx_free(fu);
ngx_set_errno(err);
}
if (tu && tu != utf16t) {
err = ngx_errno;
ngx_free(tu);
ngx_set_errno(err);
}
return rc;
}
ngx_err_t
ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log)
{
@ -227,28 +358,36 @@ ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log)
ngx_sprintf(name + to->len, ".%0muA.DELETE%Z", num);
if (MoveFile((const char *) to->data, (const char *) name) != 0) {
if (ngx_rename_file(to->data, name) != NGX_FILE_ERROR) {
break;
}
collision = 1;
err = ngx_errno;
ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
if (err == NGX_EEXIST || err == NGX_EEXIST_FILE) {
collision = 1;
continue;
}
ngx_log_error(NGX_LOG_CRIT, log, err,
"MoveFile() \"%s\" to \"%s\" failed", to->data, name);
goto failed;
}
if (MoveFile((const char *) from->data, (const char *) to->data) == 0) {
if (ngx_rename_file(from->data, to->data) == NGX_FILE_ERROR) {
err = ngx_errno;
} else {
err = 0;
}
if (DeleteFile((const char *) name) == 0) {
if (ngx_delete_file(name) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
"DeleteFile() \"%s\" failed", name);
}
failed:
/* mutex_unlock() */
ngx_free(name);
@ -269,7 +408,7 @@ ngx_file_info(u_char *file, ngx_file_info_t *sb)
len = NGX_UTF16_BUFLEN;
u = ngx_utf8_to_utf16(utf16, file, &len);
u = ngx_utf8_to_utf16(utf16, file, &len, 0);
if (u == NULL) {
return NGX_FILE_ERROR;
@ -277,7 +416,7 @@ ngx_file_info(u_char *file, ngx_file_info_t *sb)
rc = NGX_FILE_ERROR;
if (ngx_win32_check_filename(file, u, len) != NGX_OK) {
if (ngx_win32_check_filename(u, len, 0) != NGX_OK) {
goto failed;
}
@ -424,61 +563,146 @@ ngx_realpath(u_char *path, u_char *resolved)
}
size_t
ngx_getcwd(u_char *buf, size_t size)
{
u_char *p;
size_t n;
u_short utf16[NGX_MAX_PATH];
n = GetCurrentDirectoryW(NGX_MAX_PATH, utf16);
if (n == 0) {
return 0;
}
if (n > NGX_MAX_PATH) {
ngx_set_errno(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
p = ngx_utf16_to_utf8(buf, utf16, &size, NULL);
if (p == NULL) {
return 0;
}
if (p != buf) {
ngx_free(p);
ngx_set_errno(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
return size - 1;
}
ngx_int_t
ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
{
u_char *pattern, *p;
size_t len;
u_short *u, *p;
ngx_err_t err;
u_short utf16[NGX_UTF16_BUFLEN];
pattern = malloc(name->len + 3);
if (pattern == NULL) {
len = NGX_UTF16_BUFLEN - 2;
u = ngx_utf8_to_utf16(utf16, name->data, &len, 2);
if (u == NULL) {
return NGX_ERROR;
}
p = ngx_cpymem(pattern, name->data, name->len);
if (ngx_win32_check_filename(u, len, 0) != NGX_OK) {
goto failed;
}
p = &u[len - 1];
*p++ = '/';
*p++ = '*';
*p = '\0';
dir->dir = FindFirstFile((const char *) pattern, &dir->finddata);
dir->dir = FindFirstFileW(u, &dir->finddata);
if (dir->dir == INVALID_HANDLE_VALUE) {
err = ngx_errno;
ngx_free(pattern);
ngx_set_errno(err);
return NGX_ERROR;
goto failed;
}
ngx_free(pattern);
if (u != utf16) {
ngx_free(u);
}
dir->valid_info = 1;
dir->ready = 1;
dir->name = NULL;
dir->allocated = 0;
return NGX_OK;
}
failed:
ngx_int_t
ngx_read_dir(ngx_dir_t *dir)
{
if (dir->ready) {
dir->ready = 0;
return NGX_OK;
}
if (FindNextFile(dir->dir, &dir->finddata) != 0) {
dir->type = 1;
return NGX_OK;
if (u != utf16) {
err = ngx_errno;
ngx_free(u);
ngx_set_errno(err);
}
return NGX_ERROR;
}
ngx_int_t
ngx_read_dir(ngx_dir_t *dir)
{
u_char *name;
size_t len, allocated;
if (dir->ready) {
dir->ready = 0;
goto convert;
}
if (FindNextFileW(dir->dir, &dir->finddata) != 0) {
dir->type = 1;
goto convert;
}
return NGX_ERROR;
convert:
name = dir->name;
len = dir->allocated;
name = ngx_utf16_to_utf8(name, dir->finddata.cFileName, &len, &allocated);
if (name == NULL) {
return NGX_ERROR;
}
if (name != dir->name) {
if (dir->name) {
ngx_free(dir->name);
}
dir->name = name;
dir->allocated = allocated;
}
dir->namelen = len - 1;
return NGX_OK;
}
ngx_int_t
ngx_close_dir(ngx_dir_t *dir)
{
if (dir->name) {
ngx_free(dir->name);
}
if (FindClose(dir->dir) == 0) {
return NGX_ERROR;
}
@ -487,19 +711,104 @@ ngx_close_dir(ngx_dir_t *dir)
}
ngx_int_t
ngx_create_dir(u_char *name, ngx_uint_t access)
{
long rc;
size_t len;
u_short *u;
ngx_err_t err;
u_short utf16[NGX_UTF16_BUFLEN];
len = NGX_UTF16_BUFLEN;
u = ngx_utf8_to_utf16(utf16, name, &len, 0);
if (u == NULL) {
return NGX_FILE_ERROR;
}
rc = NGX_FILE_ERROR;
if (ngx_win32_check_filename(u, len, 1) != NGX_OK) {
goto failed;
}
rc = CreateDirectoryW(u, NULL);
failed:
if (u != utf16) {
err = ngx_errno;
ngx_free(u);
ngx_set_errno(err);
}
return rc;
}
ngx_int_t
ngx_delete_dir(u_char *name)
{
long rc;
size_t len;
u_short *u;
ngx_err_t err;
u_short utf16[NGX_UTF16_BUFLEN];
len = NGX_UTF16_BUFLEN;
u = ngx_utf8_to_utf16(utf16, name, &len, 0);
if (u == NULL) {
return NGX_FILE_ERROR;
}
rc = NGX_FILE_ERROR;
if (ngx_win32_check_filename(u, len, 0) != NGX_OK) {
goto failed;
}
rc = RemoveDirectoryW(u);
failed:
if (u != utf16) {
err = ngx_errno;
ngx_free(u);
ngx_set_errno(err);
}
return rc;
}
ngx_int_t
ngx_open_glob(ngx_glob_t *gl)
{
u_char *p;
size_t len;
u_short *u;
ngx_err_t err;
u_short utf16[NGX_UTF16_BUFLEN];
gl->dir = FindFirstFile((const char *) gl->pattern, &gl->finddata);
len = NGX_UTF16_BUFLEN;
u = ngx_utf8_to_utf16(utf16, gl->pattern, &len, 0);
if (u == NULL) {
return NGX_ERROR;
}
gl->dir = FindFirstFileW(u, &gl->finddata);
if (gl->dir == INVALID_HANDLE_VALUE) {
err = ngx_errno;
if (u != utf16) {
ngx_free(u);
}
if ((err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
&& gl->test)
{
@ -507,6 +816,8 @@ ngx_open_glob(ngx_glob_t *gl)
return NGX_OK;
}
ngx_set_errno(err);
return NGX_ERROR;
}
@ -516,18 +827,10 @@ ngx_open_glob(ngx_glob_t *gl)
}
}
len = ngx_strlen(gl->finddata.cFileName);
gl->name.len = gl->last + len;
gl->name.data = ngx_alloc(gl->name.len + 1, gl->log);
if (gl->name.data == NULL) {
return NGX_ERROR;
if (u != utf16) {
ngx_free(u);
}
ngx_memcpy(gl->name.data, gl->pattern, gl->last);
ngx_cpystrn(gl->name.data + gl->last, (u_char *) gl->finddata.cFileName,
len + 1);
gl->ready = 1;
return NGX_OK;
@ -537,40 +840,25 @@ ngx_open_glob(ngx_glob_t *gl)
ngx_int_t
ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
{
size_t len;
ngx_err_t err;
u_char *p;
size_t len;
ngx_err_t err;
u_char utf8[NGX_UTF8_BUFLEN];
if (gl->no_match) {
return NGX_DONE;
}
if (gl->ready) {
*name = gl->name;
gl->ready = 0;
return NGX_OK;
goto convert;
}
ngx_free(gl->name.data);
gl->name.data = NULL;
if (FindNextFile(gl->dir, &gl->finddata) != 0) {
len = ngx_strlen(gl->finddata.cFileName);
gl->name.len = gl->last + len;
gl->name.data = ngx_alloc(gl->name.len + 1, gl->log);
if (gl->name.data == NULL) {
return NGX_ERROR;
}
ngx_memcpy(gl->name.data, gl->pattern, gl->last);
ngx_cpystrn(gl->name.data + gl->last, (u_char *) gl->finddata.cFileName,
len + 1);
*name = gl->name;
return NGX_OK;
if (FindNextFileW(gl->dir, &gl->finddata) != 0) {
goto convert;
}
err = ngx_errno;
@ -583,6 +871,43 @@ ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
"FindNextFile(%s) failed", gl->pattern);
return NGX_ERROR;
convert:
len = NGX_UTF8_BUFLEN;
p = ngx_utf16_to_utf8(utf8, gl->finddata.cFileName, &len, NULL);
if (p == NULL) {
return NGX_ERROR;
}
gl->name.len = gl->last + len - 1;
gl->name.data = ngx_alloc(gl->name.len + 1, gl->log);
if (gl->name.data == NULL) {
goto failed;
}
ngx_memcpy(gl->name.data, gl->pattern, gl->last);
ngx_cpystrn(gl->name.data + gl->last, p, len);
if (p != utf8) {
ngx_free(p);
}
*name = gl->name;
return NGX_OK;
failed:
if (p != utf8) {
err = ngx_errno;
ngx_free(p);
ngx_set_errno(err);
}
return NGX_ERROR;
}
@ -642,18 +967,31 @@ ngx_directio_off(ngx_fd_t fd)
size_t
ngx_fs_bsize(u_char *name)
{
u_char root[4];
u_long sc, bs, nfree, ncl;
u_long sc, bs, nfree, ncl;
size_t len;
u_short *u;
u_short utf16[NGX_UTF16_BUFLEN];
if (name[2] == ':') {
ngx_cpystrn(root, name, 4);
name = root;
len = NGX_UTF16_BUFLEN;
u = ngx_utf8_to_utf16(utf16, name, &len, 0);
if (u == NULL) {
return 512;
}
if (GetDiskFreeSpace((const char *) name, &sc, &bs, &nfree, &ncl) == 0) {
if (GetDiskFreeSpaceW(u, &sc, &bs, &nfree, &ncl) == 0) {
if (u != utf16) {
ngx_free(u);
}
return 512;
}
if (u != utf16) {
ngx_free(u);
}
return sc * bs;
}
@ -661,22 +999,40 @@ ngx_fs_bsize(u_char *name)
off_t
ngx_fs_available(u_char *name)
{
ULARGE_INTEGER navail;
size_t len;
u_short *u;
ULARGE_INTEGER navail;
u_short utf16[NGX_UTF16_BUFLEN];
if (GetDiskFreeSpaceEx((const char *) name, &navail, NULL, NULL) == 0) {
len = NGX_UTF16_BUFLEN;
u = ngx_utf8_to_utf16(utf16, name, &len, 0);
if (u == NULL) {
return NGX_MAX_OFF_T_VALUE;
}
if (GetDiskFreeSpaceExW(u, &navail, NULL, NULL) == 0) {
if (u != utf16) {
ngx_free(u);
}
return NGX_MAX_OFF_T_VALUE;
}
if (u != utf16) {
ngx_free(u);
}
return (off_t) navail.QuadPart;
}
static ngx_int_t
ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
ngx_win32_check_filename(u_short *u, size_t len, ngx_uint_t dirname)
{
u_char *p, ch;
u_long n;
u_short *lu;
u_short *lu, *p, *slash, ch;
ngx_err_t err;
enum {
sw_start = 0,
@ -689,9 +1045,14 @@ ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
/* check for NTFS streams (":"), trailing dots and spaces */
lu = NULL;
slash = NULL;
state = sw_start;
for (p = name; *p; p++) {
#if (NGX_SUPPRESS_WARN)
ch = 0;
#endif
for (p = u; *p; p++) {
ch = *p;
switch (state) {
@ -705,6 +1066,7 @@ ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
if (ch == '/' || ch == '\\') {
state = sw_after_slash;
slash = p;
}
break;
@ -723,6 +1085,7 @@ ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
if (ch == '/' || ch == '\\') {
state = sw_after_slash;
slash = p;
break;
}
@ -750,6 +1113,7 @@ ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
if (ch == '/' || ch == '\\') {
state = sw_after_slash;
slash = p;
break;
}
@ -778,6 +1142,12 @@ ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
goto invalid;
}
if (dirname && slash) {
ch = *slash;
*slash = '\0';
len = slash - u + 1;
}
/* check if long name match */
lu = malloc(len * 2);
@ -788,6 +1158,11 @@ ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
n = GetLongPathNameW(u, lu, len);
if (n == 0) {
if (dirname && slash && ngx_errno == NGX_ENOENT) {
ngx_set_errno(NGX_ENOPATH);
}
goto failed;
}
@ -795,6 +1170,10 @@ ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
goto invalid;
}
if (dirname && slash) {
*slash = ch;
}
ngx_free(lu);
return NGX_OK;
@ -805,6 +1184,10 @@ invalid:
failed:
if (dirname && slash) {
*slash = ch;
}
if (lu) {
err = ngx_errno;
ngx_free(lu);
@ -816,7 +1199,7 @@ failed:
static u_short *
ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len)
ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len, size_t reserved)
{
u_char *p;
u_short *u, *last;
@ -865,7 +1248,7 @@ ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len)
/* the given buffer is not enough, allocate a new one */
u = malloc(((p - utf8) + ngx_strlen(p) + 1) * sizeof(u_short));
u = malloc(((p - utf8) + ngx_strlen(p) + 1 + reserved) * sizeof(u_short));
if (u == NULL) {
return NULL;
}
@ -910,3 +1293,167 @@ ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len)
/* unreachable */
}
static u_char *
ngx_utf16_to_utf8(u_char *utf8, u_short *utf16, size_t *len, size_t *allocated)
{
u_char *p, *last;
u_short *u, *j;
uint32_t n;
u = utf16;
p = utf8;
last = utf8 + *len;
while (p < last) {
if (*u < 0x80) {
*p++ = (u_char) *u;
if (*u == 0) {
*len = p - utf8;
return utf8;
}
u++;
continue;
}
if (p >= last - 4) {
*len = p - utf8;
break;
}
n = ngx_utf16_decode(&u, 2);
if (n > 0x10ffff) {
ngx_set_errno(NGX_EILSEQ);
return NULL;
}
if (n >= 0x10000) {
*p++ = (u_char) (0xf0 + (n >> 18));
*p++ = (u_char) (0x80 + ((n >> 12) & 0x3f));
*p++ = (u_char) (0x80 + ((n >> 6) & 0x3f));
*p++ = (u_char) (0x80 + (n & 0x3f));
continue;
}
if (n >= 0x0800) {
*p++ = (u_char) (0xe0 + (n >> 12));
*p++ = (u_char) (0x80 + ((n >> 6) & 0x3f));
*p++ = (u_char) (0x80 + (n & 0x3f));
continue;
}
*p++ = (u_char) (0xc0 + (n >> 6));
*p++ = (u_char) (0x80 + (n & 0x3f));
}
/* the given buffer is not enough, allocate a new one */
for (j = u; *j; j++) { /* void */ }
p = malloc((j - utf16) * 4 + 1);
if (p == NULL) {
return NULL;
}
if (allocated) {
*allocated = (j - utf16) * 4 + 1;
}
ngx_memcpy(p, utf8, *len);
utf8 = p;
p += *len;
for ( ;; ) {
if (*u < 0x80) {
*p++ = (u_char) *u;
if (*u == 0) {
*len = p - utf8;
return utf8;
}
u++;
continue;
}
n = ngx_utf16_decode(&u, 2);
if (n > 0x10ffff) {
ngx_free(utf8);
ngx_set_errno(NGX_EILSEQ);
return NULL;
}
if (n >= 0x10000) {
*p++ = (u_char) (0xf0 + (n >> 18));
*p++ = (u_char) (0x80 + ((n >> 12) & 0x3f));
*p++ = (u_char) (0x80 + ((n >> 6) & 0x3f));
*p++ = (u_char) (0x80 + (n & 0x3f));
continue;
}
if (n >= 0x0800) {
*p++ = (u_char) (0xe0 + (n >> 12));
*p++ = (u_char) (0x80 + ((n >> 6) & 0x3f));
*p++ = (u_char) (0x80 + (n & 0x3f));
continue;
}
*p++ = (u_char) (0xc0 + (n >> 6));
*p++ = (u_char) (0x80 + (n & 0x3f));
}
/* unreachable */
}
/*
* ngx_utf16_decode() decodes one or two UTF-16 code units
* the return values:
* 0x80 - 0x10ffff valid character
* 0x110000 - 0xfffffffd invalid sequence
* 0xfffffffe incomplete sequence
* 0xffffffff error
*/
uint32_t
ngx_utf16_decode(u_short **u, size_t n)
{
uint32_t k, m;
k = **u;
if (k < 0xd800 || k > 0xdfff) {
(*u)++;
return k;
}
if (k > 0xdbff) {
(*u)++;
return 0xffffffff;
}
if (n < 2) {
return 0xfffffffe;
}
(*u)++;
m = *(*u)++;
if (m < 0xdc00 || m > 0xdfff) {
return 0xffffffff;
}
return 0x10000 + ((k - 0xd800) << 10) + (m - 0xdc00);
}

View File

@ -30,7 +30,11 @@ typedef struct {
typedef struct {
HANDLE dir;
WIN32_FIND_DATA finddata;
WIN32_FIND_DATAW finddata;
u_char *name;
size_t namelen;
size_t allocated;
unsigned valid_info:1;
unsigned type:1;
@ -40,7 +44,7 @@ typedef struct {
typedef struct {
HANDLE dir;
WIN32_FIND_DATA finddata;
WIN32_FIND_DATAW finddata;
unsigned ready:1;
unsigned test:1;
@ -86,16 +90,8 @@ ngx_fd_t ngx_open_file(u_char *name, u_long mode, u_long create, u_long access);
#define NGX_FILE_OWNER_ACCESS 0
#define ngx_open_tempfile(name, persistent, access) \
CreateFile((const char *) name, \
GENERIC_READ|GENERIC_WRITE, \
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, \
NULL, \
CREATE_NEW, \
persistent ? 0: \
FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, \
NULL);
ngx_fd_t ngx_open_tempfile(u_char *name, ngx_uint_t persistent,
ngx_uint_t access);
#define ngx_open_tempfile_n "CreateFile()"
@ -119,11 +115,11 @@ ssize_t ngx_write_console(ngx_fd_t fd, void *buf, size_t size);
#define NGX_LINEFEED CRLF
#define ngx_delete_file(name) DeleteFile((const char *) name)
ngx_int_t ngx_delete_file(u_char *name);
#define ngx_delete_file_n "DeleteFile()"
#define ngx_rename_file(o, n) MoveFile((const char *) o, (const char *) n)
ngx_int_t ngx_rename_file(u_char *from, u_char *to);
#define ngx_rename_file_n "MoveFile()"
ngx_err_t ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log);
@ -174,8 +170,12 @@ void ngx_close_file_mapping(ngx_file_mapping_t *fm);
u_char *ngx_realpath(u_char *path, u_char *resolved);
#define ngx_realpath_n ""
#define ngx_getcwd(buf, size) GetCurrentDirectory(size, (char *) buf)
size_t ngx_getcwd(u_char *buf, size_t size);
#define ngx_getcwd_n "GetCurrentDirectory()"
#define ngx_path_separator(c) ((c) == '/' || (c) == '\\')
#define NGX_HAVE_MAX_PATH 1
@ -194,19 +194,19 @@ ngx_int_t ngx_close_dir(ngx_dir_t *dir);
#define ngx_close_dir_n "FindClose()"
#define ngx_create_dir(name, access) CreateDirectory((const char *) name, NULL)
ngx_int_t ngx_create_dir(u_char *name, ngx_uint_t access);
#define ngx_create_dir_n "CreateDirectory()"
#define ngx_delete_dir(name) RemoveDirectory((const char *) name)
ngx_int_t ngx_delete_dir(u_char *name);
#define ngx_delete_dir_n "RemoveDirectory()"
#define ngx_dir_access(a) (a)
#define ngx_de_name(dir) ((u_char *) (dir)->finddata.cFileName)
#define ngx_de_namelen(dir) ngx_strlen((dir)->finddata.cFileName)
#define ngx_de_name(dir) (dir)->name
#define ngx_de_namelen(dir) (dir)->namelen
ngx_int_t ngx_de_info(u_char *name, ngx_dir_t *dir);
#define ngx_de_info_n "dummy()"

View File

@ -2178,8 +2178,9 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
prev->ssl_session_reuse, 1);
ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
(NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
|NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
(NGX_CONF_BITMASK_SET
|NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
|NGX_SSL_TLSv1_2|NGX_SSL_TLSv1_3));
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT");

View File

@ -707,8 +707,9 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
prev->prefer_server_ciphers, 0);
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
(NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
|NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
(NGX_CONF_BITMASK_SET
|NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
|NGX_SSL_TLSv1_2|NGX_SSL_TLSv1_3));
ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);