Latest update - 9066

This commit is contained in:
2023-03-29 16:36:39 +09:00
parent 092bbce122
commit 1034e434d8
30 changed files with 1085 additions and 167 deletions
+1
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;
+6 -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;
+42 -10
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;
}
+13 -7
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;
+2 -2
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);
+70 -1
View File
@@ -3432,29 +3432,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
@@ -3464,7 +3493,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
@@ -3474,6 +3509,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
@@ -3483,12 +3521,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 */
@@ -3496,6 +3544,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
@@ -3513,12 +3573,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
+1 -1
View File
@@ -576,7 +576,7 @@ ngx_quic_payload_size(ngx_quic_header_t *pkt, size_t pkt_len)
{
size_t len;
if ngx_quic_short_pkt(pkt->flags) {
if (ngx_quic_short_pkt(pkt->flags)) {
len = 1 + pkt->dcid.len + pkt->num_len + EVP_GCM_TLS_TAG_LEN;
if (len > pkt_len) {
+2 -1
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;
+12 -6
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;
}
@@ -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;
+1
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;
+3 -6
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;
+63 -2
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;
+1 -4
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;
+5 -1
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];
};
+3 -6
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;
+3 -1
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);
+5 -8
View File
@@ -1732,6 +1732,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;
@@ -1791,17 +1792,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;
}
@@ -1888,6 +1883,8 @@ error:
h2c->state.stream = NULL;
ngx_http_run_posted_requests(fc);
return ngx_http_v2_state_header_complete(h2c, pos, end);
}
+9 -3
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);
}
+628 -81
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);
}
+19 -19
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()"