From vbart at nginx.com Tue Mar 1 12:18:48 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 01 Mar 2016 12:18:48 +0000 Subject: [nginx] Request body: moved handling of the last part in the save filter. Message-ID: details: http://hg.nginx.org/nginx/rev/3b9fe734a76c branches: changeset: 6420:3b9fe734a76c user: Valentin Bartenev date: Tue Mar 01 15:18:07 2016 +0300 description: Request body: moved handling of the last part in the save filter. No functional changes. diffstat: src/http/ngx_http_request_body.c | 109 ++++++++++++++------------------------ 1 files changed, 40 insertions(+), 69 deletions(-) diffs (167 lines): diff -r 39a806ccf21e -r 3b9fe734a76c src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c Fri Feb 26 14:27:04 2016 +0300 +++ b/src/http/ngx_http_request_body.c Tue Mar 01 15:18:07 2016 +0300 @@ -34,7 +34,7 @@ ngx_http_read_client_request_body(ngx_ht ssize_t size; ngx_int_t rc; ngx_buf_t *b; - ngx_chain_t out, *cl; + ngx_chain_t out; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; @@ -59,10 +59,6 @@ ngx_http_read_client_request_body(ngx_ht goto done; } - if (r->request_body_no_buffering) { - r->request_body_in_file_only = 0; - } - rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); if (rb == NULL) { rc = NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -148,37 +144,8 @@ ngx_http_read_client_request_body(ngx_ht if (rb->rest == 0) { /* the whole request body was pre-read */ - - if (r->request_body_in_file_only) { - if (ngx_http_write_request_body(r) != NGX_OK) { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; - goto done; - } - - if (rb->temp_file->file.offset != 0) { - - cl = ngx_chain_get_free_buf(r->pool, &rb->free); - if (cl == NULL) { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; - goto done; - } - - b = cl->buf; - - ngx_memzero(b, sizeof(ngx_buf_t)); - - b->in_file = 1; - b->file_last = rb->temp_file->file.offset; - b->file = &rb->temp_file->file; - - rb->bufs = cl; - } - } - r->request_body_no_buffering = 0; - post_handler(r); - return NGX_OK; } @@ -289,8 +256,7 @@ ngx_http_do_read_client_request_body(ngx size_t size; ssize_t n; ngx_int_t rc; - ngx_buf_t *b; - ngx_chain_t *cl, out; + ngx_chain_t out; ngx_connection_t *c; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; @@ -439,33 +405,6 @@ ngx_http_do_read_client_request_body(ngx ngx_del_timer(c->read); } - if (rb->temp_file || r->request_body_in_file_only) { - - /* save the last part */ - - if (ngx_http_write_request_body(r) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - if (rb->temp_file->file.offset != 0) { - - cl = ngx_chain_get_free_buf(r->pool, &rb->free); - if (cl == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - b = cl->buf; - - ngx_memzero(b, sizeof(ngx_buf_t)); - - b->in_file = 1; - b->file_last = rb->temp_file->file.offset; - b->file = &rb->temp_file->file; - - rb->bufs = cl; - } - } - if (!r->request_body_no_buffering) { r->read_event_handler = ngx_http_block_reading; rb->post_handler(r); @@ -1127,9 +1066,8 @@ ngx_http_request_body_chunked_filter(ngx ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) { -#if (NGX_DEBUG) + ngx_buf_t *b; ngx_chain_t *cl; -#endif ngx_http_request_body_t *rb; rb = r->request_body; @@ -1166,13 +1104,46 @@ ngx_http_request_body_save_filter(ngx_ht return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (rb->rest > 0 - && rb->buf && rb->buf->last == rb->buf->end - && !r->request_body_no_buffering) - { + if (r->request_body_no_buffering) { + return NGX_OK; + } + + if (rb->rest > 0) { + + if (rb->buf && rb->buf->last == rb->buf->end + && ngx_http_write_request_body(r) != NGX_OK) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + return NGX_OK; + } + + /* rb->rest == 0 */ + + if (rb->temp_file || r->request_body_in_file_only) { + if (ngx_http_write_request_body(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } + + if (rb->temp_file->file.offset != 0) { + + cl = ngx_chain_get_free_buf(r->pool, &rb->free); + if (cl == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + b = cl->buf; + + ngx_memzero(b, sizeof(ngx_buf_t)); + + b->in_file = 1; + b->file_last = rb->temp_file->file.offset; + b->file = &rb->temp_file->file; + + rb->bufs = cl; + } } return NGX_OK; From joel.cunningham at me.com Tue Mar 1 19:40:13 2016 From: joel.cunningham at me.com (Joel Cunningham) Date: Tue, 01 Mar 2016 13:40:13 -0600 Subject: [PATCH] Correct reference to GCC compiler macro Message-ID: <799188E3-3E8F-4D16-86E2-ECAA3613B437@me.com> # HG changeset patch # User Joel Cunningham # Date 1456860378 21600 # Tue Mar 01 13:26:18 2016 -0600 # Node ID cce5f2f6ed76ffa0f6890e90e7b1b68718ffa8a9 # Parent 3b9fe734a76ca0863ec87596369690831e9f4086 Correct reference to GCC compiler macro This commit corrects a small typo where __GNU__ was used in place of __GNUC__ This was identified on a GCC system that built with undefined macros treated as errors when used with #if diff -r 3b9fe734a76c -r cce5f2f6ed76 src/core/ngx_config.h --- a/src/core/ngx_config.h Tue Mar 01 15:18:07 2016 +0300 +++ b/src/core/ngx_config.h Tue Mar 01 13:26:18 2016 -0600 @@ -125,7 +125,7 @@ #endif -#if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8)) +#if ((__GNUC__ == 2) && (__GNUC_MINOR__ < 8)) #define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffffLL #else #define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffff From igor at sysoev.ru Wed Mar 2 12:35:49 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 02 Mar 2016 12:35:49 +0000 Subject: [njs] njs_vm_call() interface to call a function outside. Message-ID: details: http://hg.nginx.com/njs/rev/0dce9318807a branches: changeset: 82:0dce9318807a user: Igor Sysoev date: Wed Mar 02 15:10:28 2016 +0300 description: njs_vm_call() interface to call a function outside. nginx content and variable handlers interface is function name(request, response) { ... } Variable handler use a value returned by function as value of the variable. diffstat: nginx/ngx_http_js_module.c | 238 +++++++++++++++++++++++++++----------------- njs/njs_extern.c | 41 +++++++ njs/njs_generator.c | 3 + njs/njs_parser.c | 8 +- njs/njs_parser.h | 1 + njs/njs_vm.h | 11 +- njs/njscript.c | 55 ++++++++++- njs/njscript.h | 12 ++- njs/test/njs_unit_test.c | 30 ++++- 9 files changed, 292 insertions(+), 107 deletions(-) diffs (715 lines): diff -r 36541f3695b6 -r 0dce9318807a nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Thu Feb 25 16:32:47 2016 +0300 +++ b/nginx/ngx_http_js_module.c Wed Mar 02 15:10:28 2016 +0300 @@ -32,19 +32,28 @@ typedef struct { - njs_vm_t *vm; + njs_vm_t *vm; + njs_function_t *function; + njs_opaque_value_t args[2]; +} ngx_http_js_ctx_t; + + +typedef struct { + ngx_http_js_ctx_t js; } ngx_http_js_loc_conf_t; typedef struct { - ngx_list_part_t *part; - ngx_uint_t item; + ngx_list_part_t *part; + ngx_uint_t item; } ngx_http_js_table_entry_t; static ngx_int_t ngx_http_js_handler(ngx_http_request_t *r); static ngx_int_t ngx_http_js_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_js_vm_run(ngx_http_request_t *r, + ngx_http_js_ctx_t *js, nxt_str_t *value); static void ngx_http_js_cleanup_mem_cache_pool(void *data); static void *ngx_http_js_alloc(void *mem, size_t size); @@ -99,7 +108,8 @@ static njs_ret_t ngx_http_js_ext_next_ar static char *ngx_http_js_run(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_js_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static njs_vm_t *ngx_http_js_compile(ngx_conf_t *cf, ngx_str_t *script); +static char *ngx_http_js_compile(ngx_conf_t *cf, ngx_http_js_ctx_t *jctx, + ngx_str_t *script); static void *ngx_http_js_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_js_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); @@ -362,15 +372,70 @@ static njs_external_t ngx_http_js_exter static ngx_int_t ngx_http_js_handler(ngx_http_request_t *r) { - nxt_str_t value; - njs_vm_t *nvm; - ngx_pool_cleanup_t *cln; - nxt_mem_cache_pool_t *mcp; + ngx_int_t rc; ngx_http_js_loc_conf_t *jlcf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http js handler"); + jlcf = ngx_http_get_module_loc_conf(r, ngx_http_js_module); + + rc = ngx_http_js_vm_run(r, &jlcf->js, NULL); + + if (rc == NGX_OK) { + return rc; + } + + return NGX_ERROR; +} + + +static ngx_int_t +ngx_http_js_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, + uintptr_t data) +{ + ngx_http_js_ctx_t *js = (ngx_http_js_ctx_t *) data; + + ngx_int_t rc; + nxt_str_t value; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http js variable handler"); + + rc = ngx_http_js_vm_run(r, js, &value); + + if (rc == NXT_ERROR) { + return NGX_ERROR; + } + + if (rc == NGX_OK) { + v->len = value.len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = value.data; + + } else { + v->not_found = 1; + } + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http js variable done"); + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_js_vm_run(ngx_http_request_t *r, ngx_http_js_ctx_t *js, + nxt_str_t *value) +{ + njs_vm_t *nvm; + nxt_int_t ret; + nxt_str_t exception; + ngx_pool_cleanup_t *cln; + nxt_mem_cache_pool_t *mcp; + mcp = ngx_http_js_create_mem_cache_pool(); if (mcp == NULL) { return NGX_ERROR; @@ -384,85 +449,39 @@ ngx_http_js_handler(ngx_http_request_t * cln->handler = ngx_http_js_cleanup_mem_cache_pool; cln->data = mcp; - jlcf = ngx_http_get_module_loc_conf(r, ngx_http_js_module); - - nvm = njs_vm_clone(jlcf->vm, mcp, (void **) &r); + nvm = njs_vm_clone(js->vm, mcp, (void **) &r); if (nvm == NULL) { return NGX_ERROR; } - if (njs_vm_run(nvm) != NJS_OK) { - njs_vm_exception(nvm, &value); + if (js->function) { + ret = njs_vm_call(nvm, js->function, js->args, 2); + + } else { + ret = njs_vm_run(nvm); + } + + if (ret == NJS_OK) { + + if (value != NULL) { + if (njs_vm_retval(nvm, value) != NJS_OK) { + return NGX_ERROR; + } + } + + } else { + njs_vm_exception(nvm, &exception); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "js exception: %*s", value.len, value.data); + "js exception: %*s", exception.len, exception.data); - return NGX_ERROR; + return NGX_DECLINED; } return NGX_OK; } -static ngx_int_t -ngx_http_js_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, - uintptr_t data) -{ - njs_vm_t *vm = (njs_vm_t *) data; - - nxt_str_t value; - njs_vm_t *nvm; - ngx_pool_cleanup_t *cln; - nxt_mem_cache_pool_t *mcp; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http js variable handler"); - - mcp = ngx_http_js_create_mem_cache_pool(); - if (mcp == NULL) { - return NGX_ERROR; - } - - cln = ngx_pool_cleanup_add(r->pool, 0); - if (cln == NULL) { - return NGX_ERROR; - } - - cln->handler = ngx_http_js_cleanup_mem_cache_pool; - cln->data = mcp; - - nvm = njs_vm_clone(vm, mcp, (void **) &r); - if (nvm == NULL) { - return NGX_ERROR; - } - - if (njs_vm_run(nvm) == NJS_OK) { - if (njs_vm_retval(nvm, &value) != NJS_OK) { - return NGX_ERROR; - } - - v->len = value.len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = value.data; - - } else { - njs_vm_exception(nvm, &value); - - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "js exception: %*s", value.len, value.data); - - v->not_found = 1; - } - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http js variable done"); - - return NGX_OK; -} - - static void ngx_http_js_cleanup_mem_cache_pool(void *data) { @@ -1046,20 +1065,21 @@ ngx_http_js_run(ngx_conf_t *cf, ngx_comm { ngx_http_js_loc_conf_t *jlcf = conf; + char *ret; ngx_str_t *value; ngx_http_core_loc_conf_t *clcf; value = cf->args->elts; - if (jlcf->vm) { + if (jlcf->js.vm) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate js handler \"%V\"", &value[1]); return NGX_CONF_ERROR; } - jlcf->vm = ngx_http_js_compile(cf, &value[1]); - if (jlcf->vm == NULL) { - return NGX_CONF_ERROR; + ret = ngx_http_js_compile(cf, &jlcf->js, &value[1]); + if (ret != NGX_CONF_OK) { + return ret; } clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); @@ -1072,8 +1092,9 @@ ngx_http_js_run(ngx_conf_t *cf, ngx_comm static char * ngx_http_js_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - njs_vm_t *vm; + char *ret; ngx_str_t *value; + ngx_http_js_ctx_t *js; ngx_http_variable_t *v; value = cf->args->elts; @@ -1092,32 +1113,38 @@ ngx_http_js_set(ngx_conf_t *cf, ngx_comm return NGX_CONF_ERROR; } - vm = ngx_http_js_compile(cf, &value[2]); - if (vm == NULL) { + js = ngx_palloc(cf->pool, sizeof(ngx_http_js_ctx_t)); + if (js == NULL) { return NGX_CONF_ERROR; } + ret = ngx_http_js_compile(cf, js, &value[2]); + if (ret != NGX_CONF_OK) { + return ret; + } + v->get_handler = ngx_http_js_variable; - v->data = (uintptr_t) vm; + v->data = (uintptr_t) js; return NGX_CONF_OK; } -static njs_vm_t * -ngx_http_js_compile(ngx_conf_t *cf, ngx_str_t *script) +static char * +ngx_http_js_compile(ngx_conf_t *cf, ngx_http_js_ctx_t *js, ngx_str_t *script) { u_char *start, *end; nxt_int_t rc; - nxt_str_t s; + nxt_str_t s, name; njs_vm_t *vm; nxt_lvlhsh_t externals; + njs_function_t *function; njs_vm_shared_t *shared; nxt_mem_cache_pool_t *mcp; mcp = ngx_http_js_create_mem_cache_pool(); if (mcp == NULL) { - return NULL; + return NGX_CONF_ERROR; } shared = NULL; @@ -1129,35 +1156,58 @@ ngx_http_js_compile(ngx_conf_t *cf, ngx_ != NJS_OK) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "could not add js externals"); - return NULL; + return NGX_CONF_ERROR; } vm = njs_vm_create(mcp, &shared, &externals); if (vm == NULL) { - return NULL; + return NGX_CONF_ERROR; } start = script->data; end = start + script->len; - rc = njs_vm_compile(vm, &start, end); + rc = njs_vm_compile(vm, &start, end, &function); if (rc != NJS_OK) { njs_vm_exception(vm, &s); ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "js compilation error: \"%*s\"", s.len, s.data); - return NULL; + return NGX_CONF_ERROR; } if (start != end) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "extra characters in js script: \"%*s\"", end - start, start); - return NULL; + return NGX_CONF_ERROR; } - return vm; + js->vm = vm; + js->function = function; + + if (function) { + ngx_str_set(&name, "$r"); + + rc = njs_external_get(vm, NULL, &name, &js->args[0]); + if (rc != NXT_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "could not get $r external"); + return NGX_CONF_ERROR; + } + + ngx_str_set(&name, "response"); + + rc = njs_external_get(vm, &js->args[0], &name, &js->args[1]); + if (rc != NXT_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "could not get $r.response external"); + return NGX_CONF_ERROR; + } + } + + return NGX_CONF_OK; } @@ -1187,8 +1237,8 @@ ngx_http_js_merge_loc_conf(ngx_conf_t *c ngx_http_js_loc_conf_t *prev = parent; ngx_http_js_loc_conf_t *conf = child; - if (conf->vm == NULL) { - conf->vm = prev->vm; + if (conf->js.vm == NULL) { + conf->js = prev->js; } return NGX_CONF_OK; diff -r 36541f3695b6 -r 0dce9318807a njs/njs_extern.c --- a/njs/njs_extern.c Thu Feb 25 16:32:47 2016 +0300 +++ b/njs/njs_extern.c Wed Mar 02 15:10:28 2016 +0300 @@ -126,6 +126,47 @@ njs_add_external(nxt_lvlhsh_t *hash, nxt } +nxt_int_t +njs_external_get(njs_vm_t *vm, njs_opaque_value_t *obj, nxt_str_t *property, + njs_opaque_value_t *value) +{ + uint32_t (*key_hash)(const void *, size_t); + njs_value_t *object; + njs_extern_t *ext; + nxt_lvlhsh_t hash; + nxt_lvlhsh_query_t lhq; + + object = (njs_value_t *) obj; + + key_hash = nxt_djb_hash; + hash = vm->externals_hash; + + if (object != NULL) { + if (!njs_is_external(object)) { + return NXT_ERROR; + } + + ext = object->data.u.external; + hash = ext->hash; + + if (ext->type == NJS_EXTERN_CASELESS_OBJECT) { + key_hash = nxt_djb_hash_lowcase; + } + } + + lhq.key_hash = key_hash(property->data, property->len); + lhq.key = *property; + lhq.proto = &njs_extern_hash_proto; + + if (nxt_lvlhsh_find(&hash, &lhq) == NXT_OK) { + *value = *(njs_opaque_value_t *) lhq.value; + return NXT_OK; + } + + return NXT_ERROR; +} + + njs_extern_t * njs_parser_external(njs_vm_t *vm, njs_parser_t *parser) { diff -r 36541f3695b6 -r 0dce9318807a njs/njs_generator.c --- a/njs/njs_generator.c Thu Feb 25 16:32:47 2016 +0300 +++ b/njs/njs_generator.c Wed Mar 02 15:10:28 2016 +0300 @@ -163,6 +163,9 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_END: return njs_generate_stop_statement(vm, parser, node); + case NJS_TOKEN_CALL: + return njs_generate_children(vm, parser, node); + case NJS_TOKEN_COMMA: return njs_generate_comma_expression(vm, parser, node); diff -r 36541f3695b6 -r 0dce9318807a njs/njs_parser.c --- a/njs/njs_parser.c Thu Feb 25 16:32:47 2016 +0300 +++ b/njs/njs_parser.c Wed Mar 02 15:10:28 2016 +0300 @@ -99,7 +99,13 @@ njs_parser(njs_vm_t *vm, njs_parser_t *p node = parser->node; - if (node == NULL) { + if (node != NULL && node->right != NULL) { + if (node->right->token == NJS_TOKEN_FUNCTION) { + node->token = NJS_TOKEN_CALL; + return node; + } + + } else { /* Empty string, just semicolons or variables declarations. */ node = njs_parser_node_alloc(vm); diff -r 36541f3695b6 -r 0dce9318807a njs/njs_parser.h --- a/njs/njs_parser.h Thu Feb 25 16:32:47 2016 +0300 +++ b/njs/njs_parser.h Wed Mar 02 15:10:28 2016 +0300 @@ -14,6 +14,7 @@ typedef enum { NJS_TOKEN_ILLEGAL = 0, NJS_TOKEN_END, + NJS_TOKEN_CALL, NJS_TOKEN_SPACE, NJS_TOKEN_LINE_END, diff -r 36541f3695b6 -r 0dce9318807a njs/njs_vm.h --- a/njs/njs_vm.h Thu Feb 25 16:32:47 2016 +0300 +++ b/njs/njs_vm.h Wed Mar 02 15:10:28 2016 +0300 @@ -130,7 +130,7 @@ struct njs_object_s { #define NJS_ARGS_TYPES_MAX 3 -typedef struct { +struct njs_function_s { njs_object_t object; uint8_t args_types[NJS_ARGS_TYPES_MAX]; @@ -158,7 +158,7 @@ typedef struct { } u; njs_value_t *bound; -} njs_function_t; +}; typedef struct njs_continuation_s njs_continuation_t; @@ -684,10 +684,10 @@ enum njs_functions_e { #define njs_scope_index(value) \ - ((njs_index_t) (value << NJS_SCOPE_SHIFT)) + ((njs_index_t) ((value) << NJS_SCOPE_SHIFT)) #define njs_global_scope_index(value) \ - ((njs_index_t) ((value << NJS_SCOPE_SHIFT) | NJS_SCOPE_GLOBAL)) + ((njs_index_t) (((value) << NJS_SCOPE_SHIFT) | NJS_SCOPE_GLOBAL)) #define NJS_INDEX_OBJECT njs_global_scope_index(NJS_FUNCTION_OBJECT) @@ -699,7 +699,8 @@ enum njs_functions_e { #define NJS_INDEX_REGEXP njs_global_scope_index(NJS_FUNCTION_REGEXP) #define NJS_INDEX_EVAL njs_global_scope_index(NJS_FUNCTION_EVAL) -#define NJS_INDEX_GLOBAL_OFFSET njs_scope_index(NJS_FUNCTION_MAX) +#define NJS_INDEX_GLOBAL_RETVAL njs_global_scope_index(NJS_FUNCTION_MAX) +#define NJS_INDEX_GLOBAL_OFFSET njs_scope_index(NJS_FUNCTION_MAX + 1) #define njs_offset(index) \ diff -r 36541f3695b6 -r 0dce9318807a njs/njscript.c --- a/njs/njscript.c Thu Feb 25 16:32:47 2016 +0300 +++ b/njs/njscript.c Wed Mar 02 15:10:28 2016 +0300 @@ -167,10 +167,12 @@ njs_vm_destroy(njs_vm_t *vm) nxt_int_t -njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end) +njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end, + njs_function_t **function) { nxt_int_t ret; njs_lexer_t *lexer; + njs_value_t *value; njs_parser_t *parser; njs_parser_node_t *node; @@ -216,6 +218,16 @@ njs_vm_compile(njs_vm_t *vm, u_char **st return NJS_ERROR; } + if (function != NULL) { + if (node->token == NJS_TOKEN_CALL) { + value = njs_variable_value(parser, node->right->index); + *function = value->data.u.function; + + } else { + *function = NULL; + } + } + *start = parser->lexer->start; ret = njs_generate_scope(vm, parser, node); @@ -318,6 +330,47 @@ fail: nxt_int_t +njs_vm_call(njs_vm_t *vm, njs_function_t *function, njs_opaque_value_t *args, + nxt_uint_t nargs) +{ + u_char *current; + njs_ret_t ret; + njs_value_t *this; + + static const njs_vmcode_stop_t stop[] = { + { .code = { .operation = njs_vmcode_stop, + .operands = NJS_VMCODE_1OPERAND, + .retval = NJS_VMCODE_NO_RETVAL }, + .retval = NJS_INDEX_GLOBAL_RETVAL }, + }; + + this = (njs_value_t *) &njs_value_void; + + ret = njs_function_frame(vm, function, this, + (njs_value_t *) args, nargs, 0); + + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + + current = vm->current; + vm->current = (u_char *) stop; + + (void) njs_function_call(vm, NJS_INDEX_GLOBAL_RETVAL, 0); + + ret = njs_vmcode_interpreter(vm); + + vm->current = current; + + if (ret == NJS_STOP) { + ret = NXT_OK; + } + + return ret; +} + + +nxt_int_t njs_vm_run(njs_vm_t *vm) { nxt_str_t s; diff -r 36541f3695b6 -r 0dce9318807a njs/njscript.h --- a/njs/njscript.h Thu Feb 25 16:32:47 2016 +0300 +++ b/njs/njscript.h Wed Mar 02 15:10:28 2016 +0300 @@ -12,8 +12,13 @@ typedef intptr_t njs_ typedef uintptr_t njs_index_t; typedef struct njs_vm_s njs_vm_t; typedef union njs_value_s njs_value_t; +typedef struct njs_function_s njs_function_t; typedef struct njs_vm_shared_s njs_vm_shared_t; +typedef struct { + uint64_t filler[2]; +} njs_opaque_value_t; + /* sizeof(njs_value_t) is 16 bytes. */ #define njs_argument(args, n) \ @@ -71,14 +76,19 @@ struct njs_external_s { NXT_EXPORT nxt_int_t njs_add_external(nxt_lvlhsh_t *hash, nxt_mem_cache_pool_t *mcp, uintptr_t object, njs_external_t *external, nxt_uint_t n); +NXT_EXPORT nxt_int_t njs_external_get(njs_vm_t *vm, njs_opaque_value_t *object, + nxt_str_t *property, njs_opaque_value_t *value); NXT_EXPORT njs_vm_t *njs_vm_create(nxt_mem_cache_pool_t *mcp, njs_vm_shared_t **shared, nxt_lvlhsh_t *externals); NXT_EXPORT void njs_vm_destroy(njs_vm_t *vm); -NXT_EXPORT nxt_int_t njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end); +NXT_EXPORT nxt_int_t njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end, + njs_function_t **function); NXT_EXPORT njs_vm_t *njs_vm_clone(njs_vm_t *vm, nxt_mem_cache_pool_t *mcp, void **external); +NXT_EXPORT nxt_int_t njs_vm_call(njs_vm_t *vm, njs_function_t *function, + njs_opaque_value_t *args, nxt_uint_t nargs); NXT_EXPORT nxt_int_t njs_vm_run(njs_vm_t *vm); NXT_EXPORT njs_ret_t njs_vm_return_string(njs_vm_t *vm, u_char *start, diff -r 36541f3695b6 -r 0dce9318807a njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Feb 25 16:32:47 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Mar 02 15:10:28 2016 +0300 @@ -3899,6 +3899,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("eval()"), nxt_string("") }, + { nxt_string("function f(req) { return req.uri }"), + nxt_string("???") }, + /* Trick: number to boolean. */ { nxt_string("var a = 0; !!a"), @@ -4192,12 +4195,14 @@ njs_unit_test(nxt_bool_t disassemble) u_char *start; njs_vm_t *vm, *nvm; nxt_int_t ret; - nxt_str_t s; + nxt_str_t s, r_name; nxt_uint_t i; nxt_bool_t success; nxt_lvlhsh_t externals; + njs_function_t *function; njs_vm_shared_t *shared; njs_unit_test_req r; + njs_opaque_value_t value; nxt_mem_cache_pool_t *mcp; shared = NULL; @@ -4230,7 +4235,8 @@ njs_unit_test(nxt_bool_t disassemble) start = njs_test[i].script.data; - ret = njs_vm_compile(vm, &start, start + njs_test[i].script.len); + ret = njs_vm_compile(vm, &start, start + njs_test[i].script.len, + &function); if (ret == NXT_OK) { if (disassemble) { @@ -4245,8 +4251,22 @@ njs_unit_test(nxt_bool_t disassemble) r.uri.len = 6; r.uri.data = (u_char *) "???"; - if (njs_vm_run(nvm) == NXT_OK) { - + if (function != NULL) { + r_name.len = 2; + r_name.data = (u_char *) "$r"; + + ret = njs_external_get(vm, NULL, &r_name, &value); + if (ret != NXT_OK) { + return NXT_ERROR; + } + + ret = njs_vm_call(nvm, function, &value, 1); + + } else { + ret = njs_vm_run(nvm); + } + + if (ret == NXT_OK) { if (njs_vm_retval(nvm, &s) != NXT_OK) { return NXT_ERROR; } @@ -4329,7 +4349,7 @@ njs_unit_test_benchmark(nxt_str_t *scrip start = script->data; - ret = njs_vm_compile(vm, &start, start + script->len); + ret = njs_vm_compile(vm, &start, start + script->len, NULL); if (ret != NXT_OK) { return NXT_ERROR; } From evan at evan.cat Wed Mar 2 16:07:15 2016 From: evan at evan.cat (Evan Kinney) Date: Wed, 02 Mar 2016 11:07:15 -0500 Subject: [PATCH] move systemd/sysv dependencies into more generic logic Message-ID: <484ae92864c7881246fd.1456934835@rituximab.enterprise.lan> # HG changeset patch # User Evan Kinney # Date 1456933417 18000 # Wed Mar 02 10:43:37 2016 -0500 # Node ID 484ae92864c7881246fdcbd6c4a7197041050ac3 # Parent 748331201a69b0e7ac6938588b32da6f3e7be138 move systemd/sysv dependencies into more generic logic Without this, RPMs fail to build on Fedora 18 and above. diff -r 748331201a69 -r 484ae92864c7 rpm/SPECS/nginx.spec --- a/rpm/SPECS/nginx.spec Thu Feb 25 21:03:16 2016 +0300 +++ b/rpm/SPECS/nginx.spec Wed Mar 02 10:43:37 2016 -0500 @@ -10,8 +10,6 @@ %if 0%{?rhel} == 5 Group: System Environment/Daemons Requires(pre): shadow-utils -Requires: initscripts >= 8.36 -Requires(post): chkconfig Requires: openssl BuildRequires: openssl-devel %endif @@ -19,8 +17,6 @@ %if 0%{?rhel} == 6 Group: System Environment/Daemons Requires(pre): shadow-utils -Requires: initscripts >= 8.36 -Requires(post): chkconfig Requires: openssl >= 1.0.1 BuildRequires: openssl-devel >= 1.0.1 %define with_http2 1 @@ -29,9 +25,7 @@ %if 0%{?rhel} == 7 Group: System Environment/Daemons Requires(pre): shadow-utils -Requires: systemd Requires: openssl >= 1.0.1 -BuildRequires: systemd BuildRequires: openssl-devel >= 1.0.1 %define epoch 1 Epoch: %{epoch} @@ -41,13 +35,19 @@ %if 0%{?suse_version} == 1315 Group: Productivity/Networking/Web/Servers BuildRequires: libopenssl-devel -BuildRequires: systemd Requires(pre): shadow -Requires: systemd %define with_http2 1 %define nginx_loggroup trusted %endif +%if %{use_systemd} +BuildRequires: systemd +Requires: systemd +%else +Requires: initscripts >= 8.36 +Requires(post): chkconfig +%endif + # end of distribution specific definitions %define WITH_CC_OPT $(echo %{optflags} $(pcre-config --cflags)) @@ -399,6 +399,9 @@ fi %changelog +* Wed Mar 2 2016 Evan Kinney +- move systemd/sysv dependencies into more generic logic + * Wed Feb 24 2016 Sergey Budnevitch - common configure args are now in macros - xslt, image-filter and geoip dynamic modules added From othree at gmail.com Thu Mar 3 15:11:49 2016 From: othree at gmail.com (OOO) Date: Thu, 3 Mar 2016 23:11:49 +0800 Subject: [PATCH] Contrib: removed ngxBlock syntax group Message-ID: # HG changeset patch # User Kao, Wei-Ko(othree) # Date 1457016287 -28800 # Thu Mar 03 22:44:47 2016 +0800 # Node ID 078464d1da32d30b0edef6f441d750765c1a4110 # Parent 3b9fe734a76ca0863ec87596369690831e9f4086 Contrib: removed ngxBlock syntax group ngxBlock syntax group is not design well. If any directive's parameter have `{`, then the syntax highlight of that directive will incorrect. diff -r 3b9fe734a76c -r 078464d1da32 contrib/vim/syntax/nginx.vim --- a/contrib/vim/syntax/nginx.vim Tue Mar 01 15:18:07 2016 +0300 +++ b/contrib/vim/syntax/nginx.vim Thu Mar 03 22:44:47 2016 +0800 @@ -10,28 +10,26 @@ setlocal iskeyword+=: syn match ngxVariable '\$\(\w\+\|{\w\+}\)' -syn match ngxVariableBlock '\$\(\w\+\|{\w\+}\)' contained syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained -syn region ngxBlock start=+^+ end=+{+ skip=+\${+ contains=ngxComment,ngxDirectiveBlock,ngxVariableBlock,ngxString oneline syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString syn match ngxComment ' *#.*$' syn keyword ngxBoolean on syn keyword ngxBoolean off -syn keyword ngxDirectiveBlock http contained -syn keyword ngxDirectiveBlock mail contained -syn keyword ngxDirectiveBlock events contained -syn keyword ngxDirectiveBlock server contained -syn keyword ngxDirectiveBlock types contained -syn keyword ngxDirectiveBlock location contained -syn keyword ngxDirectiveBlock upstream contained -syn keyword ngxDirectiveBlock charset_map contained -syn keyword ngxDirectiveBlock limit_except contained -syn keyword ngxDirectiveBlock if contained -syn keyword ngxDirectiveBlock geo contained -syn keyword ngxDirectiveBlock map contained -syn keyword ngxDirectiveBlock split_clients contained +syn keyword ngxDirectiveBlock http +syn keyword ngxDirectiveBlock mail +syn keyword ngxDirectiveBlock events +syn keyword ngxDirectiveBlock server +syn keyword ngxDirectiveBlock types +syn keyword ngxDirectiveBlock location +syn keyword ngxDirectiveBlock upstream +syn keyword ngxDirectiveBlock charset_map +syn keyword ngxDirectiveBlock limit_except +syn keyword ngxDirectiveBlock if +syn keyword ngxDirectiveBlock geo +syn keyword ngxDirectiveBlock map +syn keyword ngxDirectiveBlock split_clients syn keyword ngxDirectiveImportant include syn keyword ngxDirectiveImportant root @@ -819,9 +817,7 @@ hi link ngxComment Comment hi link ngxVariable Identifier -hi link ngxVariableBlock Identifier hi link ngxVariableString PreProc -hi link ngxBlock Normal hi link ngxString String hi link ngxBoolean Boolean -- OOO -------------- next part -------------- An HTML attachment was scrubbed... URL: From othree at gmail.com Thu Mar 3 15:21:51 2016 From: othree at gmail.com (OOO) Date: Thu, 3 Mar 2016 23:21:51 +0800 Subject: [PATCH] Contrib: removed ngxBlock syntax group In-Reply-To: References: Message-ID: More info about this patch. Before the patch https://www.flickr.com/photos/othree/24844596133/ After the patch https://www.flickr.com/photos/othree/25471327825/ The major difference is the `rewrite ` directives are correct now. Old syntax had wrong syntax on rewrite if following regexp have character `{`. Which have special function in regexp. The easiest way to solve this issue is to remove the `ngxBlock` definition. Cons of this patch: Old syntax have some debug feature. (incorrect directive follow by `{}` block will not highlight) New syntax don't have this feature. If want to have both correct syntax and debug feature. Will lead to more complete syntax definition. And will be slower. 2016-03-03 23:11 GMT+08:00 OOO : > # HG changeset patch > # User Kao, Wei-Ko(othree) > # Date 1457016287 -28800 > # Thu Mar 03 22:44:47 2016 +0800 > # Node ID 078464d1da32d30b0edef6f441d750765c1a4110 > # Parent 3b9fe734a76ca0863ec87596369690831e9f4086 > Contrib: removed ngxBlock syntax group > > ngxBlock syntax group is not design well. If any directive's parameter > have `{`, then the syntax highlight of that directive will incorrect. > > diff -r 3b9fe734a76c -r 078464d1da32 contrib/vim/syntax/nginx.vim > --- a/contrib/vim/syntax/nginx.vim Tue Mar 01 15:18:07 2016 +0300 > +++ b/contrib/vim/syntax/nginx.vim Thu Mar 03 22:44:47 2016 +0800 > @@ -10,28 +10,26 @@ > setlocal iskeyword+=: > > syn match ngxVariable '\$\(\w\+\|{\w\+}\)' > -syn match ngxVariableBlock '\$\(\w\+\|{\w\+}\)' contained > syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained > -syn region ngxBlock start=+^+ end=+{+ skip=+\${+ > contains=ngxComment,ngxDirectiveBlock,ngxVariableBlock,ngxString oneline > syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ > contains=ngxVariableString > syn match ngxComment ' *#.*$' > > syn keyword ngxBoolean on > syn keyword ngxBoolean off > > -syn keyword ngxDirectiveBlock http contained > -syn keyword ngxDirectiveBlock mail contained > -syn keyword ngxDirectiveBlock events contained > -syn keyword ngxDirectiveBlock server contained > -syn keyword ngxDirectiveBlock types contained > -syn keyword ngxDirectiveBlock location contained > -syn keyword ngxDirectiveBlock upstream contained > -syn keyword ngxDirectiveBlock charset_map contained > -syn keyword ngxDirectiveBlock limit_except contained > -syn keyword ngxDirectiveBlock if contained > -syn keyword ngxDirectiveBlock geo contained > -syn keyword ngxDirectiveBlock map contained > -syn keyword ngxDirectiveBlock split_clients contained > +syn keyword ngxDirectiveBlock http > +syn keyword ngxDirectiveBlock mail > +syn keyword ngxDirectiveBlock events > +syn keyword ngxDirectiveBlock server > +syn keyword ngxDirectiveBlock types > +syn keyword ngxDirectiveBlock location > +syn keyword ngxDirectiveBlock upstream > +syn keyword ngxDirectiveBlock charset_map > +syn keyword ngxDirectiveBlock limit_except > +syn keyword ngxDirectiveBlock if > +syn keyword ngxDirectiveBlock geo > +syn keyword ngxDirectiveBlock map > +syn keyword ngxDirectiveBlock split_clients > > syn keyword ngxDirectiveImportant include > syn keyword ngxDirectiveImportant root > @@ -819,9 +817,7 @@ > > hi link ngxComment Comment > hi link ngxVariable Identifier > -hi link ngxVariableBlock Identifier > hi link ngxVariableString PreProc > -hi link ngxBlock Normal > hi link ngxString String > > hi link ngxBoolean Boolean > > > -- > OOO > -- OOO -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Thu Mar 3 15:41:50 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 03 Mar 2016 15:41:50 +0000 Subject: [nginx] Introduced the ngx_chain_to_iovec() function. Message-ID: details: http://hg.nginx.org/nginx/rev/3832b608dc8d branches: changeset: 6421:3832b608dc8d user: Valentin Bartenev date: Thu Mar 03 18:41:05 2016 +0300 description: Introduced the ngx_chain_to_iovec() function. It's similar to ngx_output_chain_to_iovec() and uses only preallocated memory. diffstat: src/os/unix/ngx_files.c | 110 ++++++++++++++++++++++++++--------------------- 1 files changed, 60 insertions(+), 50 deletions(-) diffs (195 lines): diff -r 3b9fe734a76c -r 3832b608dc8d src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c Tue Mar 01 15:18:07 2016 +0300 +++ b/src/os/unix/ngx_files.c Thu Mar 03 18:41:05 2016 +0300 @@ -14,7 +14,8 @@ static void ngx_thread_read_handler(void *data, ngx_log_t *log); #endif -static ssize_t ngx_writev_file(ngx_file_t *file, ngx_array_t *vec, size_t size, +static ngx_chain_t *ngx_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *cl); +static ssize_t ngx_writev_file(ngx_file_t *file, ngx_iovec_t *vec, off_t offset); @@ -276,17 +277,13 @@ ngx_open_tempfile(u_char *name, ngx_uint } -#define NGX_IOVS 8 - ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset, ngx_pool_t *pool) { - u_char *prev; - size_t size; ssize_t total, n; - ngx_array_t vec; - struct iovec *iov, iovs[NGX_IOVS]; + ngx_iovec_t vec; + struct iovec iovs[NGX_IOVS_PREALLOCATE]; /* use pwrite() if there is the only buf in a chain */ @@ -298,46 +295,18 @@ ngx_write_chain_to_file(ngx_file_t *file total = 0; - vec.elts = iovs; - vec.size = sizeof(struct iovec); - vec.nalloc = NGX_IOVS; - vec.pool = pool; + vec.iovs = iovs; + vec.nalloc = NGX_IOVS_PREALLOCATE; do { - prev = NULL; - iov = NULL; - size = 0; - - vec.nelts = 0; - /* create the iovec and coalesce the neighbouring bufs */ - - while (cl && vec.nelts < IOV_MAX) { - if (prev == cl->buf->pos) { - iov->iov_len += cl->buf->last - cl->buf->pos; - - } else { - iov = ngx_array_push(&vec); - if (iov == NULL) { - return NGX_ERROR; - } - - iov->iov_base = (void *) cl->buf->pos; - iov->iov_len = cl->buf->last - cl->buf->pos; - } - - size += cl->buf->last - cl->buf->pos; - prev = cl->buf->last; - cl = cl->next; - } + cl = ngx_chain_to_iovec(&vec, cl); /* use pwrite() if there is the only iovec buffer */ - if (vec.nelts == 1) { - iov = vec.elts; - - n = ngx_write_file(file, (u_char *) iov[0].iov_base, - iov[0].iov_len, offset); + if (vec.count == 1) { + n = ngx_write_file(file, (u_char *) iovs[0].iov_base, + iovs[0].iov_len, offset); if (n == NGX_ERROR) { return n; @@ -346,7 +315,7 @@ ngx_write_chain_to_file(ngx_file_t *file return total + n; } - n = ngx_writev_file(file, &vec, size, offset); + n = ngx_writev_file(file, &vec, offset); if (n == NGX_ERROR) { return n; @@ -361,20 +330,61 @@ ngx_write_chain_to_file(ngx_file_t *file } +static ngx_chain_t * +ngx_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *cl) +{ + size_t total, size; + u_char *prev; + ngx_uint_t n; + struct iovec *iov; + + iov = NULL; + prev = NULL; + total = 0; + n = 0; + + for ( /* void */ ; cl; cl = cl->next) { + size = cl->buf->last - cl->buf->pos; + + if (prev == cl->buf->pos) { + iov->iov_len += size; + + } else { + if (n == vec->nalloc) { + break; + } + + iov = &vec->iovs[n++]; + + iov->iov_base = (void *) cl->buf->pos; + iov->iov_len = size; + } + + prev = cl->buf->pos + size; + total += size; + } + + vec->count = n; + vec->size = total; + + return cl; +} + + static ssize_t -ngx_writev_file(ngx_file_t *file, ngx_array_t *vec, size_t size, off_t offset) +ngx_writev_file(ngx_file_t *file, ngx_iovec_t *vec, off_t offset) { ssize_t n; ngx_err_t err; ngx_log_debug3(NGX_LOG_DEBUG_CORE, file->log, 0, - "writev: %d, %uz, %O", file->fd, size, offset); + "writev: %d, %uz, %O", file->fd, vec->size, offset); #if (NGX_HAVE_PWRITEV) eintr: - n = pwritev(file->fd, vec->elts, vec->nelts, offset); + n = pwritev(file->fd, vec->iovs, vec->count, offset); if (n == -1) { err = ngx_errno; @@ -390,10 +400,10 @@ eintr: return NGX_ERROR; } - if ((size_t) n != size) { + if ((size_t) n != vec->size) { ngx_log_error(NGX_LOG_CRIT, file->log, 0, "pwritev() \"%s\" has written only %z of %uz", - file->name.data, n, size); + file->name.data, n, vec->size); return NGX_ERROR; } @@ -411,7 +421,7 @@ eintr: eintr: - n = writev(file->fd, vec->elts, vec->nelts); + n = writev(file->fd, vec->iovs, vec->count); if (n == -1) { err = ngx_errno; @@ -427,10 +437,10 @@ eintr: return NGX_ERROR; } - if ((size_t) n != size) { + if ((size_t) n != vec->size) { ngx_log_error(NGX_LOG_CRIT, file->log, 0, "writev() \"%s\" has written only %z of %uz", - file->name.data, n, size); + file->name.data, n, vec->size); return NGX_ERROR; } From mdounin at mdounin.ru Thu Mar 3 17:48:39 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 3 Mar 2016 20:48:39 +0300 Subject: [PATCH] Contrib: removed ngxBlock syntax group In-Reply-To: References: Message-ID: <20160303174839.GW31796@mdounin.ru> Hello! On Thu, Mar 03, 2016 at 11:21:51PM +0800, OOO wrote: > More info about this patch. > > Before the patch > https://www.flickr.com/photos/othree/24844596133/ > > After the patch > https://www.flickr.com/photos/othree/25471327825/ > > The major difference is the `rewrite ` directives are correct now. > Old syntax had wrong syntax on rewrite if following regexp have character > `{`. > Which have special function in regexp. Another difference is the "js" string now incorrectly highlited now in the regexp location. That's clearly a regression. > The easiest way to solve this issue is to remove the `ngxBlock` definition. > > Cons of this patch: > > Old syntax have some debug feature. (incorrect directive follow by `{}` > block will not highlight) > New syntax don't have this feature. > > If want to have both correct syntax and debug feature. > Will lead to more complete syntax definition. > And will be slower. I tend to think that explicit detection of blocks is a good feature, and it would be wrong to remove it. Especially as it causes other problems. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu Mar 3 19:55:17 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 03 Mar 2016 19:55:17 +0000 Subject: [nginx] Fixed sendfile in threads (or with aio preload) and subrequests. Message-ID: details: http://hg.nginx.org/nginx/rev/768e287a6f36 branches: changeset: 6422:768e287a6f36 user: Maxim Dounin date: Thu Mar 03 21:14:12 2016 +0300 description: Fixed sendfile in threads (or with aio preload) and subrequests. If sendfile in threads is used, it is possible that multiple subrequests will trigger multiple ngx_linux_sendfile_thread() calls, as operations are only serialized in output chain based on r->aio, that is, on subrequest level. This resulted in "task #N already active" alerts, in particular, when running proxy_store.t with "aio threads; sendfile on;". Fix is to tolerate duplicate calls, with an additional safety check that the file is the same as previously used. The same problem also affects "aio on; sendfile on;" on FreeBSD (previously known as "aio sendfile;"), where aio->preload_handler() could be called multiple times due to similar reasons, resulting in "second aio post" alerts. Fix is the same as well. It is also believed that similar problems can arise if a filter calls the next body filter multiple times for some reason. These are mostly theoretical though. diffstat: src/os/unix/ngx_freebsd_sendfile_chain.c | 13 +++++++++++++ src/os/unix/ngx_linux_sendfile_chain.c | 11 +++++++++++ 2 files changed, 24 insertions(+), 0 deletions(-) diffs (44 lines): diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -247,6 +247,19 @@ ngx_freebsd_sendfile_chain(ngx_connectio #if (NGX_HAVE_AIO_SENDFILE) if (ebusy) { + if (aio->event.active) { + /* + * tolerate duplicate calls; they can happen due to subrequests + * or multiple calls of the next body filter from a filter + */ + + if (sent) { + c->busy_count = 0; + } + + return in; + } + if (sent == 0) { c->busy_count++; diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -354,6 +354,17 @@ ngx_linux_sendfile_thread(ngx_connection return (ctx->sent == ctx->size) ? NGX_DONE : NGX_AGAIN; } + if (task->event.active && ctx->file == file) { + /* + * tolerate duplicate calls; they can happen due to subrequests + * or multiple calls of the next body filter from a filter + */ + + *sent = 0; + + return NGX_OK; + } + ctx->file = file; ctx->socket = c->fd; ctx->size = size; From mdounin at mdounin.ru Thu Mar 3 19:55:20 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 03 Mar 2016 19:55:20 +0000 Subject: [nginx] Copy filter: fixed sendfile aio handlers to set ctx->aio. Message-ID: details: http://hg.nginx.org/nginx/rev/c5f81dcf97a7 branches: changeset: 6423:c5f81dcf97a7 user: Maxim Dounin date: Thu Mar 03 21:14:19 2016 +0300 description: Copy filter: fixed sendfile aio handlers to set ctx->aio. Sendfile handlers (aio preload and thread handler) are called within ctx->output_filter() in ngx_output_chain(), and hence ctx->aio cannot be set directly in ngx_output_chain(). Meanwhile, it must be set to make sure loop within ngx_output_chain() will be properly terminated. There are no known cases that trigger the problem, though in theory something like aio + sub filter (something that needs body in memory, and can also free some memory buffers) + sendfile can result in "task already active" and "second aio post" alerts. The fix is to set ctx->aio in ngx_http_copy_aio_sendfile_preload() and ngx_http_copy_thread_handler(). For consistency, ctx->aio is no longer set explicitly in ngx_output_chain_copy_buf(), as it's now done in ngx_http_copy_thread_handler(). diffstat: src/core/ngx_output_chain.c | 1 - src/http/ngx_http_copy_filter_module.c | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diffs (58 lines): diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c --- a/src/core/ngx_output_chain.c +++ b/src/core/ngx_output_chain.c @@ -581,7 +581,6 @@ ngx_output_chain_copy_buf(ngx_output_cha n = ngx_thread_read(&ctx->thread_task, src->file, dst->pos, (size_t) size, src->file_pos, ctx->pool); if (n == NGX_AGAIN) { - ctx->aio = 1; return NGX_AGAIN; } diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c --- a/src/http/ngx_http_copy_filter_module.c +++ b/src/http/ngx_http_copy_filter_module.c @@ -204,10 +204,11 @@ ngx_http_copy_aio_event_handler(ngx_even static ssize_t ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file) { - ssize_t n; - static u_char buf[1]; - ngx_event_aio_t *aio; - ngx_http_request_t *r; + ssize_t n; + static u_char buf[1]; + ngx_event_aio_t *aio; + ngx_http_request_t *r; + ngx_output_chain_ctx_t *ctx; n = ngx_file_aio_read(file->file, buf, 1, file->file_pos, NULL); @@ -218,6 +219,9 @@ ngx_http_copy_aio_sendfile_preload(ngx_b r = aio->data; r->main->blocked++; r->aio = 1; + + ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module); + ctx->aio = 1; } return n; @@ -252,6 +256,7 @@ ngx_http_copy_thread_handler(ngx_thread_ ngx_str_t name; ngx_thread_pool_t *tp; ngx_http_request_t *r; + ngx_output_chain_ctx_t *ctx; ngx_http_core_loc_conf_t *clcf; r = file->thread_ctx; @@ -285,6 +290,9 @@ ngx_http_copy_thread_handler(ngx_thread_ r->main->blocked++; r->aio = 1; + ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module); + ctx->aio = 1; + return NGX_OK; } From othree at gmail.com Fri Mar 4 03:23:40 2016 From: othree at gmail.com (OOO) Date: Fri, 4 Mar 2016 11:23:40 +0800 Subject: [PATCH] Contrib: removed ngxBlock syntax group In-Reply-To: <20160303174839.GW31796@mdounin.ru> References: <20160303174839.GW31796@mdounin.ru> Message-ID: Hi Maxim The `js` issue is not new. It is an old issue. Here is an example, please look at line 53: https://www.flickr.com/photos/othree/25460998766/ Every keywords are highlighted. My change made `location` and other `ngxDirectiveBlock` are same as other directive. So the issue appear on `ngxDirectiveBlock` groups also. I think I can fix this by highlight regexp (plan to use same color as string). But will need more test. Do you know where I can get samples of complex nginx conf? The last part you talk about is to detect blocks explicitly. Actually, the old `ngxBloxk` is a fake block. It start at beginning of a line `^` and ends at `{` . So I decide to remove it. I don't think we really need to detect block. At lease I don't see real benefit for now. If we really do detect blocks. The major advantage is more strict directive definition. For example: * server block should not contain server directive * location block should not place on root level (I even can mark them as Error) But nginx conf can include other conf file anywhere(in any block). So conf files like uwsgi.conf[1] will not have correct syntax highlight. And last thing is I plan to support lua, brotli and maybe njs module. So I will send another patch. [1]:https://github.com/nginx/nginx/blob/master/conf/uwsgi_params 2016-03-04 1:48 GMT+08:00 Maxim Dounin : > Hello! > > On Thu, Mar 03, 2016 at 11:21:51PM +0800, OOO wrote: > > > More info about this patch. > > > > Before the patch > > https://www.flickr.com/photos/othree/24844596133/ > > > > After the patch > > https://www.flickr.com/photos/othree/25471327825/ > > > > The major difference is the `rewrite ` directives are correct now. > > Old syntax had wrong syntax on rewrite if following regexp have character > > `{`. > > Which have special function in regexp. > > Another difference is the "js" string now incorrectly highlited > now in the regexp location. That's clearly a regression. > > > The easiest way to solve this issue is to remove the `ngxBlock` > definition. > > > > Cons of this patch: > > > > Old syntax have some debug feature. (incorrect directive follow by `{}` > > block will not highlight) > > New syntax don't have this feature. > > > > If want to have both correct syntax and debug feature. > > Will lead to more complete syntax definition. > > And will be slower. > > I tend to think that explicit detection of blocks is a good > feature, and it would be wrong to remove it. Especially as it > causes other problems. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- OOO -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Fri Mar 4 04:05:11 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 4 Mar 2016 07:05:11 +0300 Subject: [PATCH] Contrib: removed ngxBlock syntax group In-Reply-To: References: <20160303174839.GW31796@mdounin.ru> Message-ID: <20160304040511.GG31796@mdounin.ru> Hello! On Fri, Mar 04, 2016 at 11:23:40AM +0800, OOO wrote: > My change made `location` and other `ngxDirectiveBlock` are same as other > directive. > So the issue appear on `ngxDirectiveBlock` groups also. So the problem started to manifest itself in locations in addition to other directives. Still looks like a regression to me. > I think I can fix this by highlight regexp (plan to use same color as > string). > But will need more test. > Do you know where I can get samples of complex nginx conf? Documentation at nginx.org can be a good starting point. -- Maxim Dounin http://nginx.org/ From othree at gmail.com Fri Mar 4 04:20:48 2016 From: othree at gmail.com (OOO) Date: Fri, 4 Mar 2016 12:20:48 +0800 Subject: [PATCH] Contrib: removed ngxBlock syntax group In-Reply-To: <20160304040511.GG31796@mdounin.ru> References: <20160303174839.GW31796@mdounin.ru> <20160304040511.GG31796@mdounin.ru> Message-ID: Hi Yes, every directive are top level keywords in vim syntax now. And they will be highlighted at everywhere except string. To solve this issue, I will add a group to match uri and regexp part. Then these groups will also be excepted part. 2016-03-04 12:05 GMT+08:00 Maxim Dounin : > Hello! > > On Fri, Mar 04, 2016 at 11:23:40AM +0800, OOO wrote: > > > My change made `location` and other `ngxDirectiveBlock` are same as other > > directive. > > So the issue appear on `ngxDirectiveBlock` groups also. > > So the problem started to manifest itself in locations in addition > to other directives. Still looks like a regression to me. > > > I think I can fix this by highlight regexp (plan to use same color as > > string). > > But will need more test. > > Do you know where I can get samples of complex nginx conf? > > Documentation at nginx.org can be a good starting point. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- OOO -------------- next part -------------- An HTML attachment was scrubbed... URL: From igor at sysoev.ru Fri Mar 4 11:58:53 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 04 Mar 2016 11:58:53 +0000 Subject: [njs] Fixed building by GCC 4.1. Message-ID: details: http://hg.nginx.org/njs/rev/480849ab9e96 branches: changeset: 83:480849ab9e96 user: Igor Sysoev date: Fri Mar 04 14:57:21 2016 +0300 description: Fixed building by GCC 4.1. diffstat: nginx/ngx_http_js_module.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 0dce9318807a -r 480849ab9e96 nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Wed Mar 02 15:10:28 2016 +0300 +++ b/nginx/ngx_http_js_module.c Fri Mar 04 14:57:21 2016 +0300 @@ -449,7 +449,8 @@ ngx_http_js_vm_run(ngx_http_request_t *r cln->handler = ngx_http_js_cleanup_mem_cache_pool; cln->data = mcp; - nvm = njs_vm_clone(js->vm, mcp, (void **) &r); + /* The double cast is required by GCC 4.1. */ + nvm = njs_vm_clone(js->vm, mcp, (void **) (void *) &r); if (nvm == NULL) { return NGX_ERROR; } From thresh at nginx.com Fri Mar 4 18:45:04 2016 From: thresh at nginx.com (Konstantin Pavlov) Date: Fri, 4 Mar 2016 21:45:04 +0300 Subject: [PATCH] move systemd/sysv dependencies into more generic logic In-Reply-To: <484ae92864c7881246fd.1456934835@rituximab.enterprise.lan> References: <484ae92864c7881246fd.1456934835@rituximab.enterprise.lan> Message-ID: <56D9D7B0.1010709@nginx.com> Hi Evan, Thanks for your contribution. On 02/03/2016 19:07, Evan Kinney wrote: > # HG changeset patch > # User Evan Kinney > # Date 1456933417 18000 > # Wed Mar 02 10:43:37 2016 -0500 > # Node ID 484ae92864c7881246fdcbd6c4a7197041050ac3 > # Parent 748331201a69b0e7ac6938588b32da6f3e7be138 > move systemd/sysv dependencies into more generic logic > > Without this, RPMs fail to build on Fedora 18 and above. I guess that is not the only patch you have to apply to build on Fedora - I would think some BuildRequires would be missing and http2 module would not be enabled. -- Konstantin Pavlov From othree at gmail.com Mon Mar 7 09:30:16 2016 From: othree at gmail.com (OOO) Date: Mon, 7 Mar 2016 17:30:16 +0800 Subject: [PATCH] Contrib: update vim syntax script Message-ID: # HG changeset patch # User Kao, Wei-Ko(othree) # Date 1457339778 -28800 # Mon Mar 07 16:36:18 2016 +0800 # Node ID e0cfa435fe182f1533ae8c7a4eb5ee398dc83c4e # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 Update vim syntax file Updates including: * Fix regexp in string might breaks location ngxBlock * Add lua, brotli, nginScript modules * Update uwsgi, fast_cgi, mp4 directives to latest version * Highlight rewrite flags diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim --- a/contrib/vim/syntax/nginx.vim +++ b/contrib/vim/syntax/nginx.vim @@ -5,57 +5,63 @@ if exists("b:current_syntax") finish end setlocal iskeyword+=. setlocal iskeyword+=/ setlocal iskeyword+=: syn match ngxVariable '\$\(\w\+\|{\w\+}\)' -syn match ngxVariableBlock '\$\(\w\+\|{\w\+}\)' contained syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained -syn region ngxBlock start=+^+ end=+{+ skip=+\${+ contains=ngxComment,ngxDirectiveBlock,ngxVariableBlock,ngxString oneline +syn match ngxComment ' *#.*$' +syn match ngxRewriteURI /\S\+/ contained contains=ngxVariableString nextgroup=ngxURI skipwhite +syn match ngxURI /\S\+/ contained contains=ngxVariableString skipwhite +syn match ngxLocationPath /[^ {]\+/ contained syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString -syn match ngxComment ' *#.*$' syn keyword ngxBoolean on syn keyword ngxBoolean off -syn keyword ngxDirectiveBlock http contained -syn keyword ngxDirectiveBlock mail contained -syn keyword ngxDirectiveBlock events contained -syn keyword ngxDirectiveBlock server contained -syn keyword ngxDirectiveBlock types contained -syn keyword ngxDirectiveBlock location contained -syn keyword ngxDirectiveBlock upstream contained -syn keyword ngxDirectiveBlock charset_map contained -syn keyword ngxDirectiveBlock limit_except contained -syn keyword ngxDirectiveBlock if contained -syn keyword ngxDirectiveBlock geo contained -syn keyword ngxDirectiveBlock map contained -syn keyword ngxDirectiveBlock split_clients contained + +syn keyword ngxDirectiveBlock http +syn keyword ngxDirectiveBlock mail +syn keyword ngxDirectiveBlock events +syn keyword ngxDirectiveBlock server +syn keyword ngxDirectiveBlock types +syn match ngxLocationOperator /\(=\|\~\*\|\^\~\|\~\)/ contained nextgroup=ngxLocationPath,ngxString skipwhite +syn match ngxLocationNamedLoc /@\w\+/ +syn keyword ngxDirectiveBlock location nextgroup=ngxLocationNamedLoc,ngxLocationOperator,ngxLocationPath,ngxString skipwhite +syn keyword ngxDirectiveBlock upstream +syn keyword ngxDirectiveBlock charset_map +syn keyword ngxDirectiveBlock limit_except +syn keyword ngxDirectiveBlock if +syn keyword ngxDirectiveBlock geo +syn keyword ngxDirectiveBlock map +syn keyword ngxDirectiveBlock split_clients syn keyword ngxDirectiveImportant include syn keyword ngxDirectiveImportant root syn keyword ngxDirectiveImportant server syn keyword ngxDirectiveImportant server_name syn keyword ngxDirectiveImportant listen syn keyword ngxDirectiveImportant internal syn keyword ngxDirectiveImportant proxy_pass syn keyword ngxDirectiveImportant memcached_pass syn keyword ngxDirectiveImportant fastcgi_pass syn keyword ngxDirectiveImportant scgi_pass syn keyword ngxDirectiveImportant uwsgi_pass syn keyword ngxDirectiveImportant try_files syn keyword ngxDirectiveControl break syn keyword ngxDirectiveControl return -syn keyword ngxDirectiveControl rewrite +syn keyword ngxDirectiveControl rewrite nextgroup=ngxRewriteURI skipwhite syn keyword ngxDirectiveControl set +syn keyword ngxRewriteFlag last break redirect permanent + syn keyword ngxDirectiveError error_page syn keyword ngxDirectiveError post_action syn keyword ngxDirectiveDeprecated connections syn keyword ngxDirectiveDeprecated imap syn keyword ngxDirectiveDeprecated limit_zone syn keyword ngxDirectiveDeprecated open_file_cache_retest syn keyword ngxDirectiveDeprecated optimize_server_names @@ -123,42 +129,46 @@ syn keyword ngxDirective fastcgi_bind syn keyword ngxDirective fastcgi_buffer_size syn keyword ngxDirective fastcgi_buffering syn keyword ngxDirective fastcgi_buffers syn keyword ngxDirective fastcgi_busy_buffers_size syn keyword ngxDirective fastcgi_cache syn keyword ngxDirective fastcgi_cache_bypass syn keyword ngxDirective fastcgi_cache_key syn keyword ngxDirective fastcgi_cache_lock +syn keyword ngxDirective fastcgi_cache_lock_age syn keyword ngxDirective fastcgi_cache_lock_timeout syn keyword ngxDirective fastcgi_cache_methods syn keyword ngxDirective fastcgi_cache_min_uses syn keyword ngxDirective fastcgi_cache_path +syn keyword ngxDirective fastcgi_cache_purge syn keyword ngxDirective fastcgi_cache_revalidate syn keyword ngxDirective fastcgi_cache_use_stale syn keyword ngxDirective fastcgi_cache_valid syn keyword ngxDirective fastcgi_catch_stderr syn keyword ngxDirective fastcgi_connect_timeout syn keyword ngxDirective fastcgi_force_ranges syn keyword ngxDirective fastcgi_hide_header syn keyword ngxDirective fastcgi_ignore_client_abort syn keyword ngxDirective fastcgi_ignore_headers syn keyword ngxDirective fastcgi_index syn keyword ngxDirective fastcgi_intercept_errors syn keyword ngxDirective fastcgi_keep_conn +syn keyword ngxDirective fastcgi_limit_rate syn keyword ngxDirective fastcgi_max_temp_file_size syn keyword ngxDirective fastcgi_next_upstream syn keyword ngxDirective fastcgi_next_upstream_timeout syn keyword ngxDirective fastcgi_next_upstream_tries syn keyword ngxDirective fastcgi_no_cache syn keyword ngxDirective fastcgi_param syn keyword ngxDirective fastcgi_pass_header syn keyword ngxDirective fastcgi_pass_request_body syn keyword ngxDirective fastcgi_pass_request_headers syn keyword ngxDirective fastcgi_read_timeout +syn keyword ngxDirective fastcgi_request_buffering syn keyword ngxDirective fastcgi_send_lowat syn keyword ngxDirective fastcgi_send_timeout syn keyword ngxDirective fastcgi_split_path_info syn keyword ngxDirective fastcgi_store syn keyword ngxDirective fastcgi_store_access syn keyword ngxDirective fastcgi_temp_file_write_size syn keyword ngxDirective fastcgi_temp_path syn keyword ngxDirective flv @@ -179,30 +189,33 @@ syn keyword ngxDirective gzip_http_versi syn keyword ngxDirective gzip_min_length syn keyword ngxDirective gzip_no_buffer syn keyword ngxDirective gzip_proxied syn keyword ngxDirective gzip_static syn keyword ngxDirective gzip_types syn keyword ngxDirective gzip_vary syn keyword ngxDirective gzip_window syn keyword ngxDirective hash +syn keyword ngxDirective http2 " Not a real directive syn keyword ngxDirective if_modified_since syn keyword ngxDirective ignore_invalid_headers syn keyword ngxDirective image_filter syn keyword ngxDirective image_filter_buffer syn keyword ngxDirective image_filter_interlace syn keyword ngxDirective image_filter_jpeg_quality syn keyword ngxDirective image_filter_sharpen syn keyword ngxDirective image_filter_transparency syn keyword ngxDirective imap_auth syn keyword ngxDirective imap_capabilities syn keyword ngxDirective imap_client_buffer syn keyword ngxDirective index syn keyword ngxDirective iocp_threads syn keyword ngxDirective ip_hash +syn keyword ngxDirective js_run +syn keyword ngxDirective js_set syn keyword ngxDirective keepalive syn keyword ngxDirective keepalive_disable syn keyword ngxDirective keepalive_requests syn keyword ngxDirective keepalive_timeout syn keyword ngxDirective kqueue_changes syn keyword ngxDirective kqueue_events syn keyword ngxDirective large_client_header_buffers syn keyword ngxDirective least_conn @@ -238,16 +251,18 @@ syn keyword ngxDirective memcached_read_ syn keyword ngxDirective memcached_send_timeout syn keyword ngxDirective merge_slashes syn keyword ngxDirective min_delete_depth syn keyword ngxDirective modern_browser syn keyword ngxDirective modern_browser_value syn keyword ngxDirective mp4 syn keyword ngxDirective mp4_buffer_size syn keyword ngxDirective mp4_max_buffer_size +syn keyword ngxDirective mp4_limit_rate +syn keyword ngxDirective mp4_limit_rate_after syn keyword ngxDirective msie_padding syn keyword ngxDirective msie_refresh syn keyword ngxDirective multi_accept syn keyword ngxDirective mysql_test syn keyword ngxDirective open_file_cache syn keyword ngxDirective open_file_cache_errors syn keyword ngxDirective open_file_cache_events syn keyword ngxDirective open_file_cache_min_uses @@ -262,17 +277,18 @@ syn keyword ngxDirective perl_require syn keyword ngxDirective perl_set syn keyword ngxDirective pid syn keyword ngxDirective pop3_auth syn keyword ngxDirective pop3_capabilities syn keyword ngxDirective port_in_redirect syn keyword ngxDirective post_acceptex syn keyword ngxDirective postpone_gzipping syn keyword ngxDirective postpone_output -syn keyword ngxDirective protocol +syn keyword ngxDirective protocol nextgroup=ngxMailProtocol skipwhite +syn keyword ngxMailProtocol imap pop3 smtp syn keyword ngxDirective proxy syn keyword ngxDirective proxy_bind syn keyword ngxDirective proxy_buffer syn keyword ngxDirective proxy_buffer_size syn keyword ngxDirective proxy_buffering syn keyword ngxDirective proxy_buffers syn keyword ngxDirective proxy_busy_buffers_size syn keyword ngxDirective proxy_cache @@ -466,16 +482,17 @@ syn keyword ngxDirective uwsgi_bind syn keyword ngxDirective uwsgi_buffer_size syn keyword ngxDirective uwsgi_buffering syn keyword ngxDirective uwsgi_buffers syn keyword ngxDirective uwsgi_busy_buffers_size syn keyword ngxDirective uwsgi_cache syn keyword ngxDirective uwsgi_cache_bypass syn keyword ngxDirective uwsgi_cache_key syn keyword ngxDirective uwsgi_cache_lock +syn keyword ngxDirective uwsgi_cache_lock_age syn keyword ngxDirective uwsgi_cache_lock_timeout syn keyword ngxDirective uwsgi_cache_methods syn keyword ngxDirective uwsgi_cache_min_uses syn keyword ngxDirective uwsgi_cache_path syn keyword ngxDirective uwsgi_cache_revalidate syn keyword ngxDirective uwsgi_cache_use_stale syn keyword ngxDirective uwsgi_cache_valid syn keyword ngxDirective uwsgi_connect_timeout @@ -487,24 +504,29 @@ syn keyword ngxDirective uwsgi_intercept syn keyword ngxDirective uwsgi_max_temp_file_size syn keyword ngxDirective uwsgi_modifier1 syn keyword ngxDirective uwsgi_modifier2 syn keyword ngxDirective uwsgi_next_upstream syn keyword ngxDirective uwsgi_next_upstream_timeout syn keyword ngxDirective uwsgi_next_upstream_tries syn keyword ngxDirective uwsgi_no_cache syn keyword ngxDirective uwsgi_param +syn keyword ngxDirective uwsgi_pass syn keyword ngxDirective uwsgi_pass_header syn keyword ngxDirective uwsgi_pass_request_body syn keyword ngxDirective uwsgi_pass_request_headers syn keyword ngxDirective uwsgi_read_timeout +syn keyword ngxDirective uwsgi_request_buffering syn keyword ngxDirective uwsgi_send_timeout +syn keyword ngxDirective uwsgi_ssl_certificate +syn keyword ngxDirective uwsgi_ssl_certificate_key syn keyword ngxDirective uwsgi_ssl_ciphers syn keyword ngxDirective uwsgi_ssl_crl syn keyword ngxDirective uwsgi_ssl_name +syn keyword ngxDirective uwsgi_ssl_password_file syn keyword ngxDirective uwsgi_ssl_protocols syn keyword ngxDirective uwsgi_ssl_server_name syn keyword ngxDirective uwsgi_ssl_session_reuse syn keyword ngxDirective uwsgi_ssl_trusted_certificate syn keyword ngxDirective uwsgi_ssl_verify syn keyword ngxDirective uwsgi_ssl_verify_depth syn keyword ngxDirective uwsgi_store syn keyword ngxDirective uwsgi_store_access @@ -546,16 +568,26 @@ syn keyword ngxDirectiveThirdParty acces syn keyword ngxDirectiveThirdParty accesskey_hashmethod syn keyword ngxDirectiveThirdParty accesskey_signature " Auth PAM Module " HTTP Basic Authentication using PAM. syn keyword ngxDirectiveThirdParty auth_pam syn keyword ngxDirectiveThirdParty auth_pam_service_name +" Brotli Module +" Nginx module for Brotli compression +syn keyword ngxDirectiveThirdParty brotli_static +syn keyword ngxDirectiveThirdParty brotli +syn keyword ngxDirectiveThirdParty brotli_types +syn keyword ngxDirectiveThirdParty brotli_buffers +syn keyword ngxDirectiveThirdParty brotli_comp_level +syn keyword ngxDirectiveThirdParty brotli_window +syn keyword ngxDirectiveThirdParty brotli_min_length + " Cache Purge Module " Module adding ability to purge content from FastCGI and proxy caches. syn keyword ngxDirectiveThirdParty fastcgi_cache_purge syn keyword ngxDirectiveThirdParty proxy_cache_purge " Chunkin Module " HTTP 1.1 chunked-encoding request body support for Nginx. syn keyword ngxDirectiveThirdParty chunkin @@ -664,16 +696,80 @@ syn keyword ngxDirectiveThirdParty js_re syn keyword ngxDirectiveThirdParty js_set syn keyword ngxDirectiveThirdParty js_utf8 " Log Request Speed " Log the time it took to process each request. syn keyword ngxDirectiveThirdParty log_request_speed_filter syn keyword ngxDirectiveThirdParty log_request_speed_filter_timeout + +" Lua Module +" Embed the Power of Lua into NGINX HTTP servers +syn keyword ngxDirectiveThirdParty lua_use_default_type +syn keyword ngxDirectiveThirdParty lua_code_cache +syn keyword ngxDirectiveThirdParty lua_regex_cache_max_entries +syn keyword ngxDirectiveThirdParty lua_regex_match_limit +syn keyword ngxDirectiveThirdParty lua_package_path +syn keyword ngxDirectiveThirdParty lua_package_cpath +syn keyword ngxDirectiveThirdParty init_by_lua +syn keyword ngxDirectiveThirdParty init_by_lua_block +syn keyword ngxDirectiveThirdParty init_by_lua_file +syn keyword ngxDirectiveThirdParty init_worker_by_lua +syn keyword ngxDirectiveThirdParty init_worker_by_lua_block +syn keyword ngxDirectiveThirdParty init_worker_by_lua_file +syn keyword ngxDirectiveThirdParty set_by_lua +syn keyword ngxDirectiveThirdParty set_by_lua_block +syn keyword ngxDirectiveThirdParty set_by_lua_file +syn keyword ngxDirectiveThirdParty content_by_lua +syn keyword ngxDirectiveThirdParty content_by_lua_block +syn keyword ngxDirectiveThirdParty content_by_lua_file +syn keyword ngxDirectiveThirdParty rewrite_by_lua +syn keyword ngxDirectiveThirdParty rewrite_by_lua_block +syn keyword ngxDirectiveThirdParty rewrite_by_lua_file +syn keyword ngxDirectiveThirdParty access_by_lua +syn keyword ngxDirectiveThirdParty access_by_lua_block +syn keyword ngxDirectiveThirdParty access_by_lua_file +syn keyword ngxDirectiveThirdParty header_filter_by_lua +syn keyword ngxDirectiveThirdParty header_filter_by_lua_block +syn keyword ngxDirectiveThirdParty header_filter_by_lua_file +syn keyword ngxDirectiveThirdParty body_filter_by_lua +syn keyword ngxDirectiveThirdParty body_filter_by_lua_block +syn keyword ngxDirectiveThirdParty body_filter_by_lua_file +syn keyword ngxDirectiveThirdParty log_by_lua +syn keyword ngxDirectiveThirdParty log_by_lua_block +syn keyword ngxDirectiveThirdParty log_by_lua_file +syn keyword ngxDirectiveThirdParty balancer_by_lua_block +syn keyword ngxDirectiveThirdParty balancer_by_lua_file +syn keyword ngxDirectiveThirdParty lua_need_request_body +syn keyword ngxDirectiveThirdParty ssl_certificate_by_lua_block +syn keyword ngxDirectiveThirdParty ssl_certificate_by_lua_file +syn keyword ngxDirectiveThirdParty lua_shared_dict +syn keyword ngxDirectiveThirdParty lua_socket_connect_timeout +syn keyword ngxDirectiveThirdParty lua_socket_send_timeout +syn keyword ngxDirectiveThirdParty lua_socket_send_lowat +syn keyword ngxDirectiveThirdParty lua_socket_read_timeout +syn keyword ngxDirectiveThirdParty lua_socket_buffer_size +syn keyword ngxDirectiveThirdParty lua_socket_pool_size +syn keyword ngxDirectiveThirdParty lua_socket_keepalive_timeout +syn keyword ngxDirectiveThirdParty lua_socket_log_errors +syn keyword ngxDirectiveThirdParty lua_ssl_ciphers +syn keyword ngxDirectiveThirdParty lua_ssl_crl +syn keyword ngxDirectiveThirdParty lua_ssl_protocols +syn keyword ngxDirectiveThirdParty lua_ssl_trusted_certificate +syn keyword ngxDirectiveThirdParty lua_ssl_verify_depth +syn keyword ngxDirectiveThirdParty lua_http10_buffering +syn keyword ngxDirectiveThirdParty rewrite_by_lua_no_postpone +syn keyword ngxDirectiveThirdParty access_by_lua_no_postpone +syn keyword ngxDirectiveThirdParty lua_transform_underscores_in_response_headers +syn keyword ngxDirectiveThirdParty lua_check_client_abort +syn keyword ngxDirectiveThirdParty lua_max_pending_timers +syn keyword ngxDirectiveThirdParty lua_max_running_timers + + " Memc Module " An extended version of the standard memcached module that supports set, add, delete, and many more memcached commands. syn keyword ngxDirectiveThirdParty memc_buffer_size syn keyword ngxDirectiveThirdParty memc_cmds_allowed syn keyword ngxDirectiveThirdParty memc_connect_timeout syn keyword ngxDirectiveThirdParty memc_flags_to_last_modified syn keyword ngxDirectiveThirdParty memc_next_upstream syn keyword ngxDirectiveThirdParty memc_pass @@ -814,22 +910,23 @@ syn keyword ngxDirectiveThirdParty xss_c syn keyword ngxDirectiveThirdParty xss_get syn keyword ngxDirectiveThirdParty xss_input_types syn keyword ngxDirectiveThirdParty xss_output_type " highlight hi link ngxComment Comment hi link ngxVariable Identifier -hi link ngxVariableBlock Identifier hi link ngxVariableString PreProc -hi link ngxBlock Normal hi link ngxString String +hi link ngxLocationPath String +hi link ngxLocationNamedLoc Identifier hi link ngxBoolean Boolean +hi link ngxRewriteFlag Boolean hi link ngxDirectiveBlock Statement hi link ngxDirectiveImportant Type hi link ngxDirectiveControl Keyword hi link ngxDirectiveError Constant hi link ngxDirectiveDeprecated Error hi link ngxDirective Identifier hi link ngxDirectiveThirdParty Special -------------- next part -------------- An HTML attachment was scrubbed... URL: From othree at gmail.com Mon Mar 7 09:31:09 2016 From: othree at gmail.com (OOO) Date: Mon, 7 Mar 2016 17:31:09 +0800 Subject: [PATCH] Contrib: update vim syntax script In-Reply-To: References: Message-ID: This new patch fixed the issues in previous patch. Now the string and regexp are recognized well. No keywords will highlight inside these two kind of sections. Besides bug fixing, I also add lua, brotli, nginScript support. Screenshots: https://www.flickr.com/photos/othree/25212844679/ https://www.flickr.com/photos/othree/25580381505/ https://www.flickr.com/photos/othree/25461861942/ 2016-03-07 17:30 GMT+08:00 OOO : > # HG changeset patch > # User Kao, Wei-Ko(othree) > # Date 1457339778 -28800 > # Mon Mar 07 16:36:18 2016 +0800 > # Node ID e0cfa435fe182f1533ae8c7a4eb5ee398dc83c4e > # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 > Update vim syntax file > > Updates including: > * Fix regexp in string might breaks location ngxBlock > * Add lua, brotli, nginScript modules > * Update uwsgi, fast_cgi, mp4 directives to latest version > * Highlight rewrite flags > > diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim > --- a/contrib/vim/syntax/nginx.vim > +++ b/contrib/vim/syntax/nginx.vim > @@ -5,57 +5,63 @@ if exists("b:current_syntax") > finish > end > > setlocal iskeyword+=. > setlocal iskeyword+=/ > setlocal iskeyword+=: > > syn match ngxVariable '\$\(\w\+\|{\w\+}\)' > -syn match ngxVariableBlock '\$\(\w\+\|{\w\+}\)' contained > syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained > -syn region ngxBlock start=+^+ end=+{+ skip=+\${+ > contains=ngxComment,ngxDirectiveBlock,ngxVariableBlock,ngxString oneline > +syn match ngxComment ' *#.*$' > +syn match ngxRewriteURI /\S\+/ contained contains=ngxVariableString > nextgroup=ngxURI skipwhite > +syn match ngxURI /\S\+/ contained contains=ngxVariableString skipwhite > +syn match ngxLocationPath /[^ {]\+/ contained > syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ > contains=ngxVariableString > -syn match ngxComment ' *#.*$' > > syn keyword ngxBoolean on > syn keyword ngxBoolean off > > -syn keyword ngxDirectiveBlock http contained > -syn keyword ngxDirectiveBlock mail contained > -syn keyword ngxDirectiveBlock events contained > -syn keyword ngxDirectiveBlock server contained > -syn keyword ngxDirectiveBlock types contained > -syn keyword ngxDirectiveBlock location contained > -syn keyword ngxDirectiveBlock upstream contained > -syn keyword ngxDirectiveBlock charset_map contained > -syn keyword ngxDirectiveBlock limit_except contained > -syn keyword ngxDirectiveBlock if contained > -syn keyword ngxDirectiveBlock geo contained > -syn keyword ngxDirectiveBlock map contained > -syn keyword ngxDirectiveBlock split_clients contained > + > +syn keyword ngxDirectiveBlock http > +syn keyword ngxDirectiveBlock mail > +syn keyword ngxDirectiveBlock events > +syn keyword ngxDirectiveBlock server > +syn keyword ngxDirectiveBlock types > +syn match ngxLocationOperator /\(=\|\~\*\|\^\~\|\~\)/ contained > nextgroup=ngxLocationPath,ngxString skipwhite > +syn match ngxLocationNamedLoc /@\w\+/ > +syn keyword ngxDirectiveBlock location > nextgroup=ngxLocationNamedLoc,ngxLocationOperator,ngxLocationPath,ngxString > skipwhite > +syn keyword ngxDirectiveBlock upstream > +syn keyword ngxDirectiveBlock charset_map > +syn keyword ngxDirectiveBlock limit_except > +syn keyword ngxDirectiveBlock if > +syn keyword ngxDirectiveBlock geo > +syn keyword ngxDirectiveBlock map > +syn keyword ngxDirectiveBlock split_clients > > syn keyword ngxDirectiveImportant include > syn keyword ngxDirectiveImportant root > syn keyword ngxDirectiveImportant server > syn keyword ngxDirectiveImportant server_name > syn keyword ngxDirectiveImportant listen > syn keyword ngxDirectiveImportant internal > syn keyword ngxDirectiveImportant proxy_pass > syn keyword ngxDirectiveImportant memcached_pass > syn keyword ngxDirectiveImportant fastcgi_pass > syn keyword ngxDirectiveImportant scgi_pass > syn keyword ngxDirectiveImportant uwsgi_pass > syn keyword ngxDirectiveImportant try_files > > syn keyword ngxDirectiveControl break > syn keyword ngxDirectiveControl return > -syn keyword ngxDirectiveControl rewrite > +syn keyword ngxDirectiveControl rewrite nextgroup=ngxRewriteURI skipwhite > syn keyword ngxDirectiveControl set > > +syn keyword ngxRewriteFlag last break redirect permanent > + > syn keyword ngxDirectiveError error_page > syn keyword ngxDirectiveError post_action > > syn keyword ngxDirectiveDeprecated connections > syn keyword ngxDirectiveDeprecated imap > syn keyword ngxDirectiveDeprecated limit_zone > syn keyword ngxDirectiveDeprecated open_file_cache_retest > syn keyword ngxDirectiveDeprecated optimize_server_names > @@ -123,42 +129,46 @@ syn keyword ngxDirective fastcgi_bind > syn keyword ngxDirective fastcgi_buffer_size > syn keyword ngxDirective fastcgi_buffering > syn keyword ngxDirective fastcgi_buffers > syn keyword ngxDirective fastcgi_busy_buffers_size > syn keyword ngxDirective fastcgi_cache > syn keyword ngxDirective fastcgi_cache_bypass > syn keyword ngxDirective fastcgi_cache_key > syn keyword ngxDirective fastcgi_cache_lock > +syn keyword ngxDirective fastcgi_cache_lock_age > syn keyword ngxDirective fastcgi_cache_lock_timeout > syn keyword ngxDirective fastcgi_cache_methods > syn keyword ngxDirective fastcgi_cache_min_uses > syn keyword ngxDirective fastcgi_cache_path > +syn keyword ngxDirective fastcgi_cache_purge > syn keyword ngxDirective fastcgi_cache_revalidate > syn keyword ngxDirective fastcgi_cache_use_stale > syn keyword ngxDirective fastcgi_cache_valid > syn keyword ngxDirective fastcgi_catch_stderr > syn keyword ngxDirective fastcgi_connect_timeout > syn keyword ngxDirective fastcgi_force_ranges > syn keyword ngxDirective fastcgi_hide_header > syn keyword ngxDirective fastcgi_ignore_client_abort > syn keyword ngxDirective fastcgi_ignore_headers > syn keyword ngxDirective fastcgi_index > syn keyword ngxDirective fastcgi_intercept_errors > syn keyword ngxDirective fastcgi_keep_conn > +syn keyword ngxDirective fastcgi_limit_rate > syn keyword ngxDirective fastcgi_max_temp_file_size > syn keyword ngxDirective fastcgi_next_upstream > syn keyword ngxDirective fastcgi_next_upstream_timeout > syn keyword ngxDirective fastcgi_next_upstream_tries > syn keyword ngxDirective fastcgi_no_cache > syn keyword ngxDirective fastcgi_param > syn keyword ngxDirective fastcgi_pass_header > syn keyword ngxDirective fastcgi_pass_request_body > syn keyword ngxDirective fastcgi_pass_request_headers > syn keyword ngxDirective fastcgi_read_timeout > +syn keyword ngxDirective fastcgi_request_buffering > syn keyword ngxDirective fastcgi_send_lowat > syn keyword ngxDirective fastcgi_send_timeout > syn keyword ngxDirective fastcgi_split_path_info > syn keyword ngxDirective fastcgi_store > syn keyword ngxDirective fastcgi_store_access > syn keyword ngxDirective fastcgi_temp_file_write_size > syn keyword ngxDirective fastcgi_temp_path > syn keyword ngxDirective flv > @@ -179,30 +189,33 @@ syn keyword ngxDirective gzip_http_versi > syn keyword ngxDirective gzip_min_length > syn keyword ngxDirective gzip_no_buffer > syn keyword ngxDirective gzip_proxied > syn keyword ngxDirective gzip_static > syn keyword ngxDirective gzip_types > syn keyword ngxDirective gzip_vary > syn keyword ngxDirective gzip_window > syn keyword ngxDirective hash > +syn keyword ngxDirective http2 " Not a real directive > syn keyword ngxDirective if_modified_since > syn keyword ngxDirective ignore_invalid_headers > syn keyword ngxDirective image_filter > syn keyword ngxDirective image_filter_buffer > syn keyword ngxDirective image_filter_interlace > syn keyword ngxDirective image_filter_jpeg_quality > syn keyword ngxDirective image_filter_sharpen > syn keyword ngxDirective image_filter_transparency > syn keyword ngxDirective imap_auth > syn keyword ngxDirective imap_capabilities > syn keyword ngxDirective imap_client_buffer > syn keyword ngxDirective index > syn keyword ngxDirective iocp_threads > syn keyword ngxDirective ip_hash > +syn keyword ngxDirective js_run > +syn keyword ngxDirective js_set > syn keyword ngxDirective keepalive > syn keyword ngxDirective keepalive_disable > syn keyword ngxDirective keepalive_requests > syn keyword ngxDirective keepalive_timeout > syn keyword ngxDirective kqueue_changes > syn keyword ngxDirective kqueue_events > syn keyword ngxDirective large_client_header_buffers > syn keyword ngxDirective least_conn > @@ -238,16 +251,18 @@ syn keyword ngxDirective memcached_read_ > syn keyword ngxDirective memcached_send_timeout > syn keyword ngxDirective merge_slashes > syn keyword ngxDirective min_delete_depth > syn keyword ngxDirective modern_browser > syn keyword ngxDirective modern_browser_value > syn keyword ngxDirective mp4 > syn keyword ngxDirective mp4_buffer_size > syn keyword ngxDirective mp4_max_buffer_size > +syn keyword ngxDirective mp4_limit_rate > +syn keyword ngxDirective mp4_limit_rate_after > syn keyword ngxDirective msie_padding > syn keyword ngxDirective msie_refresh > syn keyword ngxDirective multi_accept > syn keyword ngxDirective mysql_test > syn keyword ngxDirective open_file_cache > syn keyword ngxDirective open_file_cache_errors > syn keyword ngxDirective open_file_cache_events > syn keyword ngxDirective open_file_cache_min_uses > @@ -262,17 +277,18 @@ syn keyword ngxDirective perl_require > syn keyword ngxDirective perl_set > syn keyword ngxDirective pid > syn keyword ngxDirective pop3_auth > syn keyword ngxDirective pop3_capabilities > syn keyword ngxDirective port_in_redirect > syn keyword ngxDirective post_acceptex > syn keyword ngxDirective postpone_gzipping > syn keyword ngxDirective postpone_output > -syn keyword ngxDirective protocol > +syn keyword ngxDirective protocol nextgroup=ngxMailProtocol skipwhite > +syn keyword ngxMailProtocol imap pop3 smtp > syn keyword ngxDirective proxy > syn keyword ngxDirective proxy_bind > syn keyword ngxDirective proxy_buffer > syn keyword ngxDirective proxy_buffer_size > syn keyword ngxDirective proxy_buffering > syn keyword ngxDirective proxy_buffers > syn keyword ngxDirective proxy_busy_buffers_size > syn keyword ngxDirective proxy_cache > @@ -466,16 +482,17 @@ syn keyword ngxDirective uwsgi_bind > syn keyword ngxDirective uwsgi_buffer_size > syn keyword ngxDirective uwsgi_buffering > syn keyword ngxDirective uwsgi_buffers > syn keyword ngxDirective uwsgi_busy_buffers_size > syn keyword ngxDirective uwsgi_cache > syn keyword ngxDirective uwsgi_cache_bypass > syn keyword ngxDirective uwsgi_cache_key > syn keyword ngxDirective uwsgi_cache_lock > +syn keyword ngxDirective uwsgi_cache_lock_age > syn keyword ngxDirective uwsgi_cache_lock_timeout > syn keyword ngxDirective uwsgi_cache_methods > syn keyword ngxDirective uwsgi_cache_min_uses > syn keyword ngxDirective uwsgi_cache_path > syn keyword ngxDirective uwsgi_cache_revalidate > syn keyword ngxDirective uwsgi_cache_use_stale > syn keyword ngxDirective uwsgi_cache_valid > syn keyword ngxDirective uwsgi_connect_timeout > @@ -487,24 +504,29 @@ syn keyword ngxDirective uwsgi_intercept > syn keyword ngxDirective uwsgi_max_temp_file_size > syn keyword ngxDirective uwsgi_modifier1 > syn keyword ngxDirective uwsgi_modifier2 > syn keyword ngxDirective uwsgi_next_upstream > syn keyword ngxDirective uwsgi_next_upstream_timeout > syn keyword ngxDirective uwsgi_next_upstream_tries > syn keyword ngxDirective uwsgi_no_cache > syn keyword ngxDirective uwsgi_param > +syn keyword ngxDirective uwsgi_pass > syn keyword ngxDirective uwsgi_pass_header > syn keyword ngxDirective uwsgi_pass_request_body > syn keyword ngxDirective uwsgi_pass_request_headers > syn keyword ngxDirective uwsgi_read_timeout > +syn keyword ngxDirective uwsgi_request_buffering > syn keyword ngxDirective uwsgi_send_timeout > +syn keyword ngxDirective uwsgi_ssl_certificate > +syn keyword ngxDirective uwsgi_ssl_certificate_key > syn keyword ngxDirective uwsgi_ssl_ciphers > syn keyword ngxDirective uwsgi_ssl_crl > syn keyword ngxDirective uwsgi_ssl_name > +syn keyword ngxDirective uwsgi_ssl_password_file > syn keyword ngxDirective uwsgi_ssl_protocols > syn keyword ngxDirective uwsgi_ssl_server_name > syn keyword ngxDirective uwsgi_ssl_session_reuse > syn keyword ngxDirective uwsgi_ssl_trusted_certificate > syn keyword ngxDirective uwsgi_ssl_verify > syn keyword ngxDirective uwsgi_ssl_verify_depth > syn keyword ngxDirective uwsgi_store > syn keyword ngxDirective uwsgi_store_access > @@ -546,16 +568,26 @@ syn keyword ngxDirectiveThirdParty acces > syn keyword ngxDirectiveThirdParty accesskey_hashmethod > syn keyword ngxDirectiveThirdParty accesskey_signature > > " Auth PAM Module > " HTTP Basic Authentication using PAM. > syn keyword ngxDirectiveThirdParty auth_pam > syn keyword ngxDirectiveThirdParty auth_pam_service_name > > +" Brotli Module > +" Nginx module for Brotli compression > +syn keyword ngxDirectiveThirdParty brotli_static > +syn keyword ngxDirectiveThirdParty brotli > +syn keyword ngxDirectiveThirdParty brotli_types > +syn keyword ngxDirectiveThirdParty brotli_buffers > +syn keyword ngxDirectiveThirdParty brotli_comp_level > +syn keyword ngxDirectiveThirdParty brotli_window > +syn keyword ngxDirectiveThirdParty brotli_min_length > + > " Cache Purge Module > " Module adding ability to purge content from FastCGI and proxy caches. > syn keyword ngxDirectiveThirdParty fastcgi_cache_purge > syn keyword ngxDirectiveThirdParty proxy_cache_purge > > " Chunkin Module > " HTTP 1.1 chunked-encoding request body support for Nginx. > syn keyword ngxDirectiveThirdParty chunkin > @@ -664,16 +696,80 @@ syn keyword ngxDirectiveThirdParty js_re > syn keyword ngxDirectiveThirdParty js_set > syn keyword ngxDirectiveThirdParty js_utf8 > > " Log Request Speed > " Log the time it took to process each request. > syn keyword ngxDirectiveThirdParty log_request_speed_filter > syn keyword ngxDirectiveThirdParty log_request_speed_filter_timeout > > + > +" Lua Module > +" Embed the Power of Lua into NGINX HTTP servers > +syn keyword ngxDirectiveThirdParty lua_use_default_type > +syn keyword ngxDirectiveThirdParty lua_code_cache > +syn keyword ngxDirectiveThirdParty lua_regex_cache_max_entries > +syn keyword ngxDirectiveThirdParty lua_regex_match_limit > +syn keyword ngxDirectiveThirdParty lua_package_path > +syn keyword ngxDirectiveThirdParty lua_package_cpath > +syn keyword ngxDirectiveThirdParty init_by_lua > +syn keyword ngxDirectiveThirdParty init_by_lua_block > +syn keyword ngxDirectiveThirdParty init_by_lua_file > +syn keyword ngxDirectiveThirdParty init_worker_by_lua > +syn keyword ngxDirectiveThirdParty init_worker_by_lua_block > +syn keyword ngxDirectiveThirdParty init_worker_by_lua_file > +syn keyword ngxDirectiveThirdParty set_by_lua > +syn keyword ngxDirectiveThirdParty set_by_lua_block > +syn keyword ngxDirectiveThirdParty set_by_lua_file > +syn keyword ngxDirectiveThirdParty content_by_lua > +syn keyword ngxDirectiveThirdParty content_by_lua_block > +syn keyword ngxDirectiveThirdParty content_by_lua_file > +syn keyword ngxDirectiveThirdParty rewrite_by_lua > +syn keyword ngxDirectiveThirdParty rewrite_by_lua_block > +syn keyword ngxDirectiveThirdParty rewrite_by_lua_file > +syn keyword ngxDirectiveThirdParty access_by_lua > +syn keyword ngxDirectiveThirdParty access_by_lua_block > +syn keyword ngxDirectiveThirdParty access_by_lua_file > +syn keyword ngxDirectiveThirdParty header_filter_by_lua > +syn keyword ngxDirectiveThirdParty header_filter_by_lua_block > +syn keyword ngxDirectiveThirdParty header_filter_by_lua_file > +syn keyword ngxDirectiveThirdParty body_filter_by_lua > +syn keyword ngxDirectiveThirdParty body_filter_by_lua_block > +syn keyword ngxDirectiveThirdParty body_filter_by_lua_file > +syn keyword ngxDirectiveThirdParty log_by_lua > +syn keyword ngxDirectiveThirdParty log_by_lua_block > +syn keyword ngxDirectiveThirdParty log_by_lua_file > +syn keyword ngxDirectiveThirdParty balancer_by_lua_block > +syn keyword ngxDirectiveThirdParty balancer_by_lua_file > +syn keyword ngxDirectiveThirdParty lua_need_request_body > +syn keyword ngxDirectiveThirdParty ssl_certificate_by_lua_block > +syn keyword ngxDirectiveThirdParty ssl_certificate_by_lua_file > +syn keyword ngxDirectiveThirdParty lua_shared_dict > +syn keyword ngxDirectiveThirdParty lua_socket_connect_timeout > +syn keyword ngxDirectiveThirdParty lua_socket_send_timeout > +syn keyword ngxDirectiveThirdParty lua_socket_send_lowat > +syn keyword ngxDirectiveThirdParty lua_socket_read_timeout > +syn keyword ngxDirectiveThirdParty lua_socket_buffer_size > +syn keyword ngxDirectiveThirdParty lua_socket_pool_size > +syn keyword ngxDirectiveThirdParty lua_socket_keepalive_timeout > +syn keyword ngxDirectiveThirdParty lua_socket_log_errors > +syn keyword ngxDirectiveThirdParty lua_ssl_ciphers > +syn keyword ngxDirectiveThirdParty lua_ssl_crl > +syn keyword ngxDirectiveThirdParty lua_ssl_protocols > +syn keyword ngxDirectiveThirdParty lua_ssl_trusted_certificate > +syn keyword ngxDirectiveThirdParty lua_ssl_verify_depth > +syn keyword ngxDirectiveThirdParty lua_http10_buffering > +syn keyword ngxDirectiveThirdParty rewrite_by_lua_no_postpone > +syn keyword ngxDirectiveThirdParty access_by_lua_no_postpone > +syn keyword ngxDirectiveThirdParty > lua_transform_underscores_in_response_headers > +syn keyword ngxDirectiveThirdParty lua_check_client_abort > +syn keyword ngxDirectiveThirdParty lua_max_pending_timers > +syn keyword ngxDirectiveThirdParty lua_max_running_timers > + > + > " Memc Module > " An extended version of the standard memcached module that supports set, > add, delete, and many more memcached commands. > syn keyword ngxDirectiveThirdParty memc_buffer_size > syn keyword ngxDirectiveThirdParty memc_cmds_allowed > syn keyword ngxDirectiveThirdParty memc_connect_timeout > syn keyword ngxDirectiveThirdParty memc_flags_to_last_modified > syn keyword ngxDirectiveThirdParty memc_next_upstream > syn keyword ngxDirectiveThirdParty memc_pass > @@ -814,22 +910,23 @@ syn keyword ngxDirectiveThirdParty xss_c > syn keyword ngxDirectiveThirdParty xss_get > syn keyword ngxDirectiveThirdParty xss_input_types > syn keyword ngxDirectiveThirdParty xss_output_type > > " highlight > > hi link ngxComment Comment > hi link ngxVariable Identifier > -hi link ngxVariableBlock Identifier > hi link ngxVariableString PreProc > -hi link ngxBlock Normal > hi link ngxString String > +hi link ngxLocationPath String > +hi link ngxLocationNamedLoc Identifier > > hi link ngxBoolean Boolean > +hi link ngxRewriteFlag Boolean > hi link ngxDirectiveBlock Statement > hi link ngxDirectiveImportant Type > hi link ngxDirectiveControl Keyword > hi link ngxDirectiveError Constant > hi link ngxDirectiveDeprecated Error > hi link ngxDirective Identifier > hi link ngxDirectiveThirdParty Special > > > -- OOO -------------- next part -------------- An HTML attachment was scrubbed... URL: From jli.justinli at gmail.com Mon Mar 7 18:16:13 2016 From: jli.justinli at gmail.com (Justin Li) Date: Mon, 07 Mar 2016 13:16:13 -0500 Subject: [PATCH] Upstream: avoid closing connection when no client body needed Message-ID: # HG changeset patch # User Justin Li # Date 1457369412 18000 # Mon Mar 07 11:50:12 2016 -0500 # Node ID e84a844f3c2634488285fb9677d3254a032440a2 # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 Upstream: avoid closing connection when no client body needed Despite 4a75e1a6, it was previously possible for the connection to be closed in cases where a response body from the upstream should not be sent to the client. This is due to the conditional in ngx_http_upstream_process_request that may call ngx_http_upstream_finalize_request in certain cases. Example configuration: proxy_cache foo; proxy_cache_bypass 1; proxy_no_cache 1; If a client sends If-None-Match, and the upstream server returns 200 with a matching ETag, no body should be returned to the client. At the start of ngx_http_upstream_send_response proxy_no_cache is not yet tested, thus cacheable is still 1 and downstream_error is set. However, by the time the downstream_error check is done in process_request, proxy_no_cache has been tested and cacheable is set to 0. The client connection is then closed, regardless of keepalive. The fix is to avoid using the p->downstream_error flag, and instead repurpose p->downstream_done to indicate the event pipe should be drained. Additionally, a check is added for this flag in ngx_http_upstream_check_broken_connection to prevent a 499 if the client validly closes the connection after receiving the headers. diff -r c5f81dcf97a7 -r e84a844f3c26 src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c Thu Mar 03 21:14:19 2016 +0300 +++ b/src/event/ngx_event_pipe.c Mon Mar 07 11:50:12 2016 -0500 @@ -502,7 +502,7 @@ flushed = 0; for ( ;; ) { - if (p->downstream_error) { + if (p->downstream_error || p->downstream_done) { return ngx_event_pipe_drain_chains(p); } diff -r c5f81dcf97a7 -r e84a844f3c26 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Thu Mar 03 21:14:19 2016 +0300 +++ b/src/http/ngx_http_upstream.c Mon Mar 07 11:50:12 2016 -0500 @@ -1172,6 +1172,10 @@ } #endif + if (u->pipe->downstream_done) { + return; + } + #if (NGX_HAVE_KQUEUE) if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { @@ -2697,7 +2701,7 @@ return; } - u->pipe->downstream_error = 1; + u->pipe->downstream_done = 1; } if (r->request_body && r->request_body->temp_file) { From jli.justinli at gmail.com Mon Mar 7 18:24:26 2016 From: jli.justinli at gmail.com (Justin Li) Date: Mon, 7 Mar 2016 13:24:26 -0500 Subject: [PATCH] Upstream: avoid closing connection when no client body needed In-Reply-To: References: Message-ID: Apologies, I referenced a git commit hash in the first sentence, the corresponding mercurial commit is 5746:35990c69. On Mon, Mar 7, 2016 at 1:16 PM, Justin Li wrote: > # HG changeset patch > # User Justin Li > # Date 1457369412 18000 > # Mon Mar 07 11:50:12 2016 -0500 > # Node ID e84a844f3c2634488285fb9677d3254a032440a2 > # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 > Upstream: avoid closing connection when no client body needed > > Despite 4a75e1a6, it was previously possible for the connection to be > closed in > cases where a response body from the upstream should not be sent to the > client. > This is due to the conditional in ngx_http_upstream_process_request that > may > call ngx_http_upstream_finalize_request in certain cases. > > Example configuration: > > proxy_cache foo; > proxy_cache_bypass 1; > proxy_no_cache 1; > > If a client sends If-None-Match, and the upstream server returns 200 with a > matching ETag, no body should be returned to the client. At the start of > ngx_http_upstream_send_response proxy_no_cache is not yet tested, thus > cacheable > is still 1 and downstream_error is set. > > However, by the time the downstream_error check is done in process_request, > proxy_no_cache has been tested and cacheable is set to 0. The client > connection > is then closed, regardless of keepalive. > > The fix is to avoid using the p->downstream_error flag, and instead > repurpose > p->downstream_done to indicate the event pipe should be drained. > Additionally, > a check is added for this flag in > ngx_http_upstream_check_broken_connection to > prevent a 499 if the client validly closes the connection after receiving > the > headers. > > diff -r c5f81dcf97a7 -r e84a844f3c26 src/event/ngx_event_pipe.c > --- a/src/event/ngx_event_pipe.c Thu Mar 03 21:14:19 2016 +0300 > +++ b/src/event/ngx_event_pipe.c Mon Mar 07 11:50:12 2016 -0500 > @@ -502,7 +502,7 @@ > flushed = 0; > > for ( ;; ) { > - if (p->downstream_error) { > + if (p->downstream_error || p->downstream_done) { > return ngx_event_pipe_drain_chains(p); > } > > diff -r c5f81dcf97a7 -r e84a844f3c26 src/http/ngx_http_upstream.c > --- a/src/http/ngx_http_upstream.c Thu Mar 03 21:14:19 2016 +0300 > +++ b/src/http/ngx_http_upstream.c Mon Mar 07 11:50:12 2016 -0500 > @@ -1172,6 +1172,10 @@ > } > #endif > > + if (u->pipe->downstream_done) { > + return; > + } > + > #if (NGX_HAVE_KQUEUE) > > if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { > @@ -2697,7 +2701,7 @@ > return; > } > > - u->pipe->downstream_error = 1; > + u->pipe->downstream_done = 1; > } > > if (r->request_body && r->request_body->temp_file) { > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tolga.ceylan at gmail.com Tue Mar 8 23:13:35 2016 From: tolga.ceylan at gmail.com (tolga ceylan) Date: Tue, 8 Mar 2016 15:13:35 -0800 Subject: [PATCH] Core: ngx_palloc after alignment boundary check In-Reply-To: References: Message-ID: <56DF5C9F.207@gmail.com> # HG changeset patch # User Tolga Ceylan # Date 1457477267 28800 # Tue Mar 08 14:47:47 2016 -0800 # Node ID 44c90f64f3eec25cdf2e5bee13419cb71e9cdf93 # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 Core: ngx_palloc after alignment boundary check Alignment macro can move the current pointer beyond the current pool boundary. Additional check is needed to ensure within range. diff -r c5f81dcf97a7 -r 44c90f64f3ee src/core/ngx_palloc.c --- a/src/core/ngx_palloc.c Thu Mar 03 21:14:19 2016 +0300 +++ b/src/core/ngx_palloc.c Tue Mar 08 14:47:47 2016 -0800 @@ -129,7 +129,7 @@ do { m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT); - if ((size_t) (p->d.end - m) >= size) { + if (m < p->d.end && (size_t) (p->d.end - m) >= size) { p->d.last = m + size; return m; From mdounin at mdounin.ru Tue Mar 8 23:16:25 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 9 Mar 2016 02:16:25 +0300 Subject: [PATCH] Core: ngx_palloc after alignment boundary check In-Reply-To: <56DF5C9F.207@gmail.com> References: <56DF5C9F.207@gmail.com> Message-ID: <20160308231625.GU31796@mdounin.ru> Hello! On Tue, Mar 08, 2016 at 03:13:35PM -0800, tolga ceylan wrote: > # HG changeset patch > # User Tolga Ceylan > # Date 1457477267 28800 > # Tue Mar 08 14:47:47 2016 -0800 > # Node ID 44c90f64f3eec25cdf2e5bee13419cb71e9cdf93 > # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 > Core: ngx_palloc after alignment boundary check > > Alignment macro can move the current pointer beyond > the current pool boundary. Additional check is needed > to ensure within range. No, it can't, see https://trac.nginx.org/nginx/ticket/686. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Mar 9 01:13:46 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 9 Mar 2016 04:13:46 +0300 Subject: [PATCH] Upstream: avoid closing connection when no client body needed In-Reply-To: References: Message-ID: <20160309011345.GX31796@mdounin.ru> Hello! On Mon, Mar 07, 2016 at 01:16:13PM -0500, Justin Li wrote: > # HG changeset patch > # User Justin Li > # Date 1457369412 18000 > # Mon Mar 07 11:50:12 2016 -0500 > # Node ID e84a844f3c2634488285fb9677d3254a032440a2 > # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 > Upstream: avoid closing connection when no client body needed The term "client body" is used to refer client request body, as in client_body_buffer_size (http://nginx.org/r/client_body_buffer_size). The patch seems to be about a response body. > Despite 4a75e1a6, it was previously possible for the connection to be closed in > cases where a response body from the upstream should not be sent to the client. > This is due to the conditional in ngx_http_upstream_process_request that may > call ngx_http_upstream_finalize_request in certain cases. There are two connections: one with the client, another one with the upstream server. You may want to be more explicit to avoid confusion. > Example configuration: > > proxy_cache foo; > proxy_cache_bypass 1; > proxy_no_cache 1; > > If a client sends If-None-Match, and the upstream server returns 200 with a > matching ETag, no body should be returned to the client. At the start of > ngx_http_upstream_send_response proxy_no_cache is not yet tested, thus cacheable > is still 1 and downstream_error is set. > > However, by the time the downstream_error check is done in process_request, > proxy_no_cache has been tested and cacheable is set to 0. The client connection > is then closed, regardless of keepalive. So you are trying to optimize a specific case with proxy_no_cache in addition to what 35990c69b3ac fixed, right? It might worth to make it clear from the very start. Better understanding of what is fixed might also help to develop better fix, see below. > The fix is to avoid using the p->downstream_error flag, and instead repurpose > p->downstream_done to indicate the event pipe should be drained. Additionally, > a check is added for this flag in ngx_http_upstream_check_broken_connection to > prevent a 499 if the client validly closes the connection after receiving the > headers. The fix looks wrong, see below. > diff -r c5f81dcf97a7 -r e84a844f3c26 src/event/ngx_event_pipe.c > --- a/src/event/ngx_event_pipe.c Thu Mar 03 21:14:19 2016 +0300 > +++ b/src/event/ngx_event_pipe.c Mon Mar 07 11:50:12 2016 -0500 > @@ -502,7 +502,7 @@ Please add [diff] showfunc=1 to your ~/.hgrc, this greatly simplifies review process. > flushed = 0; > > for ( ;; ) { > - if (p->downstream_error) { > + if (p->downstream_error || p->downstream_done) { > return ngx_event_pipe_drain_chains(p); > } > This is incorrect. The ngx_event_pipe_drain_chains() call will corrupt busy buffers, that is, already sent to output filter chain, leading to undefined behaviour. (See also ticket #918, https://trac.nginx.org/nginx/ticket/918, which demonstrates that ngx_event_pipe_drain_chains() isn't completely safe even in case of errors.) > diff -r c5f81dcf97a7 -r e84a844f3c26 src/http/ngx_http_upstream.c > --- a/src/http/ngx_http_upstream.c Thu Mar 03 21:14:19 2016 +0300 > +++ b/src/http/ngx_http_upstream.c Mon Mar 07 11:50:12 2016 -0500 > @@ -1172,6 +1172,10 @@ > } > #endif > > + if (u->pipe->downstream_done) { > + return; > + } > + This is incorrect as well, as it will fail to remove appropriate events and will result in CPU hog when using level-triggered events. It is also believed that if the response is not cacheable there are no reasons why we should keep reading from the upstream connection. Normally we just close the upstream connection once we sent headers to the client and found that we don't need to sent anything else (r->header_only is set). What about explicitly handling the proxy_no_cache case right after the proxy_no_cache cache check, much like it is already done with cache object (see ngx_http_file_cache_free() call)? (Additionally, the code between the no_cache test and the ngx_http_file_cache_free() call also shows that lack of proxy_cache_valid and/or explicit cache validity headers can lead to the same behaviour.) -- Maxim Dounin http://nginx.org/ From tolga.ceylan at gmail.com Wed Mar 9 01:42:20 2016 From: tolga.ceylan at gmail.com (tolga ceylan) Date: Tue, 8 Mar 2016 17:42:20 -0800 Subject: [PATCH] Core: Added comment for ngx_create_pool In-Reply-To: <56DF5C9F.207@gmail.com> References: <56DF5C9F.207@gmail.com> Message-ID: <56DF7F7C.8080002@gmail.com> # HG changeset patch # User Tolga Ceylan # Date 1457487679 28800 # Tue Mar 08 17:41:19 2016 -0800 # Node ID 5b9659f40da1e685c5b78f04a1c031ef597b410d # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 Core: Added comment for ngx_create_pool Pool size must be at least 16-bytes aligned (the NGX_POOL_ALIGNMENT macro). diff -r c5f81dcf97a7 -r 5b9659f40da1 src/core/ngx_palloc.h --- a/src/core/ngx_palloc.h Thu Mar 03 21:14:19 2016 +0300 +++ b/src/core/ngx_palloc.h Tue Mar 08 17:41:19 2016 -0800 @@ -75,6 +75,9 @@ void *ngx_alloc(size_t size, ngx_log_t *log); void *ngx_calloc(size_t size, ngx_log_t *log); +/* + * Pool sizes must be at least NGX_POOL_ALIGNMENT aligned + */ ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log); void ngx_destroy_pool(ngx_pool_t *pool); void ngx_reset_pool(ngx_pool_t *pool); From jli.justinli at gmail.com Wed Mar 9 01:56:11 2016 From: jli.justinli at gmail.com (Justin Li) Date: Tue, 8 Mar 2016 20:56:11 -0500 Subject: [PATCH] Upstream: avoid closing connection when no client body needed Message-ID: Thanks for your feedback Maxim! On Wed, Mar 09, 2016 at 01:13:46, Maxim Dounin wrote: > So you are trying to optimize a specific case with proxy_no_cache > in addition to what 35990c69b3ac fixed, right? Yes, as you figured, this is about preventing the client connection from being closed when the client response is header_only and the upstream response switches from cacheable to not cacheable between the header_only check and downstream_error check. Sorry for the vagueness. > What about explicitly handling the proxy_no_cache case right > after the proxy_no_cache cache check, much like it is already done > with cache object (see ngx_http_file_cache_free() call)? > > (Additionally, the code between the no_cache test and the > ngx_http_file_cache_free() call also shows that lack of > proxy_cache_valid and/or explicit cache validity headers can lead > to the same behaviour.) I assume you mean something like calling ngx_http_upstream_finalize_request() if (r->header_only && !u->cacheable && !u->store) after the referenced call to ngx_http_file_cache_free(). I'll submit another patch after testing to confirm it fully fixes our issue unless you object to that interpretation. -- Justin Li Developer @ Shopify -------------- next part -------------- An HTML attachment was scrubbed... URL: From jli.justinli at gmail.com Wed Mar 9 02:29:36 2016 From: jli.justinli at gmail.com (Justin Li) Date: Tue, 08 Mar 2016 21:29:36 -0500 Subject: [PATCH] Upstream: avoid closing client conn when no response body needed Message-ID: # HG changeset patch # User Justin Li # Date 1457490530 18000 # Tue Mar 08 21:28:50 2016 -0500 # Node ID e9f916f271b86e446c6f1de371832432a9f2a66d # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 Upstream: avoid closing client conn when no response body needed If proxy_cache is enabled, and proxy_cache_bypass tests true, it was previously possible for the client connection to be closed after a 304. The fix is to recheck r->header_only after the final cacheability is determined, and end the request if no longer cacheable. diff -r c5f81dcf97a7 -r e9f916f271b8 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Thu Mar 03 21:14:19 2016 +0300 +++ b/src/http/ngx_http_upstream.c Tue Mar 08 21:28:50 2016 -0500 @@ -2861,6 +2861,12 @@ ngx_http_upstream_send_response(ngx_http ngx_http_file_cache_free(r->cache, u->pipe->temp_file); } + if (r->header_only && !u->cacheable && !u->store) { + u->pipe->downstream_error = 0; + ngx_http_upstream_finalize_request(r, u, rc); + return; + } + #endif p = u->pipe; From jli.justinli at gmail.com Wed Mar 9 02:40:41 2016 From: jli.justinli at gmail.com (Justin Li) Date: Tue, 8 Mar 2016 21:40:41 -0500 Subject: [PATCH] Upstream: avoid closing client conn when no response body needed In-Reply-To: References: Message-ID: Another mistake in the message... that proxy_cache_bypass should be proxy_no_cache. I'm not sure I understand exactly how this was functioning beforehand. In the case of a cacheable response, if downstream_error is 1, then won't ngx_event_pipe_drain_chains be called? Why does that case not have the same issues with busy buffers as previously described? -- Justin Li Developer @ Shopify On Tue, Mar 8, 2016 at 9:29 PM, Justin Li wrote: > # HG changeset patch > # User Justin Li > # Date 1457490530 18000 > # Tue Mar 08 21:28:50 2016 -0500 > # Node ID e9f916f271b86e446c6f1de371832432a9f2a66d > # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 > Upstream: avoid closing client conn when no response body needed > > If proxy_cache is enabled, and proxy_cache_bypass tests true, it was > previously > possible for the client connection to be closed after a 304. The fix is to > recheck r->header_only after the final cacheability is determined, and end > the > request if no longer cacheable. > > diff -r c5f81dcf97a7 -r e9f916f271b8 src/http/ngx_http_upstream.c > --- a/src/http/ngx_http_upstream.c Thu Mar 03 21:14:19 2016 +0300 > +++ b/src/http/ngx_http_upstream.c Tue Mar 08 21:28:50 2016 -0500 > @@ -2861,6 +2861,12 @@ ngx_http_upstream_send_response(ngx_http > ngx_http_file_cache_free(r->cache, u->pipe->temp_file); > } > > + if (r->header_only && !u->cacheable && !u->store) { > + u->pipe->downstream_error = 0; > + ngx_http_upstream_finalize_request(r, u, rc); > + return; > + } > + > #endif > > p = u->pipe; > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Wed Mar 9 03:04:32 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 9 Mar 2016 06:04:32 +0300 Subject: [PATCH] Upstream: avoid closing client conn when no response body needed In-Reply-To: References: Message-ID: <20160309030432.GZ31796@mdounin.ru> Hello! On Tue, Mar 08, 2016 at 09:40:41PM -0500, Justin Li wrote: > Another mistake in the message... that proxy_cache_bypass should be > proxy_no_cache. Feel free to submit an updated patch. A bit more detailed commit message describing how to reproduce the problem will be also a good idea. > I'm not sure I understand exactly how this was functioning beforehand. In > the case of a cacheable response, if downstream_error is 1, then > won't ngx_event_pipe_drain_chains be called? Why does that case not have > the same issues with busy buffers as previously described? If p->downstream_error is set from the very start there is no harm, as there are no busy buffers. And the same is true if there is a real error and we don't need to send anything - these buffers won't be used, so they can be drained (other code have to be careful to don't trigger false alerts though). The problem with your previous patch is that you've tried to drain buffers in the p->downstream_done case, when p->busy buffers are important and can contain real data (already passed to output filters though not yet sent to the client). > On Tue, Mar 8, 2016 at 9:29 PM, Justin Li wrote: > > > # HG changeset patch > > # User Justin Li > > # Date 1457490530 18000 > > # Tue Mar 08 21:28:50 2016 -0500 > > # Node ID e9f916f271b86e446c6f1de371832432a9f2a66d > > # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 > > Upstream: avoid closing client conn when no response body needed Please use trailing dot. Please use full words, just "conn" looks wrong. (But please make sure to keep 1st line under 67 characters.) > > > > If proxy_cache is enabled, and proxy_cache_bypass tests true, it was > > previously > > possible for the client connection to be closed after a 304. The fix is to > > recheck r->header_only after the final cacheability is determined, and end > > the > > request if no longer cacheable. > > > > diff -r c5f81dcf97a7 -r e9f916f271b8 src/http/ngx_http_upstream.c > > --- a/src/http/ngx_http_upstream.c Thu Mar 03 21:14:19 2016 +0300 > > +++ b/src/http/ngx_http_upstream.c Tue Mar 08 21:28:50 2016 -0500 > > @@ -2861,6 +2861,12 @@ ngx_http_upstream_send_response(ngx_http > > ngx_http_file_cache_free(r->cache, u->pipe->temp_file); > > } > > > > + if (r->header_only && !u->cacheable && !u->store) { > > + u->pipe->downstream_error = 0; There is no need to reset p->downstream_error flag, as far as I see. > > + ngx_http_upstream_finalize_request(r, u, rc); I would rather avoid using "rc" here, as this code is far away from the place where rc is set. It should be better to use just 0. > > + return; > > + } > > + > > #endif > > > > p = u->pipe; > > -- Maxim Dounin http://nginx.org/ From jli.justinli at gmail.com Wed Mar 9 03:25:54 2016 From: jli.justinli at gmail.com (Justin Li) Date: Tue, 8 Mar 2016 22:25:54 -0500 Subject: [PATCH] Upstream: avoid closing client conn when no response body needed In-Reply-To: <20160309030432.GZ31796@mdounin.ru> References: <20160309030432.GZ31796@mdounin.ru> Message-ID: Thanks for your quick response again. On Tue, Mar 8, 2016 at 10:04 PM, Maxim Dounin wrote: > If p->downstream_error is set from the very start there is no > harm, as there are no busy buffers. And the same is true if > there is a real error and we don't need to send anything - these > buffers won't be used, so they can be drained (other code have to > be careful to don't trigger false alerts though). > > The problem with your previous patch is that you've tried to drain > buffers in the p->downstream_done case, when p->busy buffers are > important and can contain real data (already passed to output > filters though not yet sent to the client). In the original patch, downstream_done was being set at the same point downstream_error was previously set, inside the first header_only check of ngx_http_upstream_send_response. Is the reason for your original comment about busy buffer corruption because this flag is set in another place as well? If not, then I still don't understand why the original patch would cause issues. If so, then it seems like the cleanest solution is to introduce another flag (perhaps downstream_drain) that can be used in this case. -- Justin Li Developer @ Shopify -------------- next part -------------- An HTML attachment was scrubbed... URL: From jli.justinli at gmail.com Wed Mar 9 03:40:12 2016 From: jli.justinli at gmail.com (Justin Li) Date: Tue, 08 Mar 2016 22:40:12 -0500 Subject: [PATCH] Upstream: avoid closing client connection in edge case Message-ID: <80d1d2148e4bd82eb27e.1457494812@tomato> # HG changeset patch # User Justin Li # Date 1457494315 18000 # Tue Mar 08 22:31:55 2016 -0500 # Node ID 80d1d2148e4bd82eb27e50fba91fa36fed039871 # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 Upstream: avoid closing client connection in edge case. If proxy_cache is enabled, and proxy_no_cache tests true, it was previously possible for the client connection to be closed after a 304. The fix is to recheck r->header_only after the final cacheability is determined, and end the request if no longer cacheable. Example configuration: proxy_cache foo; proxy_cache_bypass 1; proxy_no_cache 1; If a client sends If-None-Match, and the upstream server returns 200 with a matching ETag, no body should be returned to the client. At the start of ngx_http_upstream_send_response proxy_no_cache is not yet tested, thus cacheable is still 1 and downstream_error is set. However, by the time the downstream_error check is done in process_request, proxy_no_cache has been tested and cacheable is set to 0. The client connection is then closed, regardless of keepalive. diff -r c5f81dcf97a7 -r 80d1d2148e4b src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Thu Mar 03 21:14:19 2016 +0300 +++ b/src/http/ngx_http_upstream.c Tue Mar 08 22:31:55 2016 -0500 @@ -2861,6 +2861,11 @@ ngx_http_upstream_send_response(ngx_http ngx_http_file_cache_free(r->cache, u->pipe->temp_file); } + if (r->header_only && !u->cacheable && !u->store) { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + #endif p = u->pipe; From mdounin at mdounin.ru Wed Mar 9 15:22:43 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 9 Mar 2016 18:22:43 +0300 Subject: [PATCH] Upstream: avoid closing client conn when no response body needed In-Reply-To: References: <20160309030432.GZ31796@mdounin.ru> Message-ID: <20160309152243.GD31796@mdounin.ru> Hello! On Tue, Mar 08, 2016 at 10:25:54PM -0500, Justin Li wrote: > Thanks for your quick response again. > > On Tue, Mar 8, 2016 at 10:04 PM, Maxim Dounin wrote: > > > If p->downstream_error is set from the very start there is no > > harm, as there are no busy buffers. And the same is true if > > there is a real error and we don't need to send anything - these > > buffers won't be used, so they can be drained (other code have to > > be careful to don't trigger false alerts though). > > > > The problem with your previous patch is that you've tried to drain > > buffers in the p->downstream_done case, when p->busy buffers are > > important and can contain real data (already passed to output > > filters though not yet sent to the client). > > In the original patch, downstream_done was being set at the same point > downstream_error was previously set, inside the first header_only check of > ngx_http_upstream_send_response. Is the reason for your original comment > about busy buffer corruption because this flag is set in another place as > well? Yes. > If not, then I still don't understand why the original patch would > cause issues. If so, then it seems like the cleanest solution is to > introduce another flag (perhaps downstream_drain) that can be used in this > case. I don't see reasons why we need another flag (or the flag at all) to handle this case. Just finalizing the request as in your last patch will handle things correctly. -- Maxim Dounin http://nginx.org/ From jli.justinli at gmail.com Wed Mar 9 17:11:27 2016 From: jli.justinli at gmail.com (Justin Li) Date: Wed, 9 Mar 2016 12:11:27 -0500 Subject: [PATCH] Upstream: avoid closing client conn when no response body needed In-Reply-To: <20160309152243.GD31796@mdounin.ru> References: <20160309030432.GZ31796@mdounin.ru> <20160309152243.GD31796@mdounin.ru> Message-ID: On Wed, Mar 9, 2016 at 10:22 AM, Maxim Dounin wrote: > I don't see reasons why we need another flag (or the flag at all) > to handle this case. Just finalizing the request as in your last > patch will handle things correctly. You're right, it's not strictly necessary. My instinct was simply to avoid adding further conditionals with special behaviour, which can be done by using a common flag for both cases. I am totally OK with my last patch though if you feel it's the better solution, now that I understand your reasoning. -- Justin Li Developer @ Shopify -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Thu Mar 10 07:43:54 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 10 Mar 2016 07:43:54 +0000 Subject: [nginx] Configure: style. Message-ID: details: http://hg.nginx.org/nginx/rev/ae41f64f7c9b branches: changeset: 6424:ae41f64f7c9b user: Ruslan Ermilov date: Thu Mar 10 10:43:00 2016 +0300 description: Configure: style. Removed extraneous braces around shell variables. diffstat: auto/make | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diffs (29 lines): diff -r c5f81dcf97a7 -r ae41f64f7c9b auto/make --- a/auto/make Thu Mar 03 21:14:19 2016 +0300 +++ b/auto/make Thu Mar 10 10:43:00 2016 +0300 @@ -225,12 +225,12 @@ cat << END build: binary modules manpage -binary: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} +binary: $NGX_OBJS${ngx_dirsep}nginx$ngx_binext -$NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer - \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link +$NGX_OBJS${ngx_dirsep}nginx$ngx_binext: $ngx_deps$ngx_spacer + \$(LINK) $ngx_long_start$ngx_binout$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link $ngx_rcc -${ngx_long_end} +$ngx_long_end modules: END @@ -607,7 +607,7 @@ END | sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \ -e "s/\//$ngx_regex_dirsep/g"` - ngx_obj=$NGX_OBJS${ngx_dirsep}${ngx_module}${ngx_modext} + ngx_obj=$NGX_OBJS$ngx_dirsep$ngx_module$ngx_modext NGX_MODULES="$NGX_MODULES $ngx_obj" From mdounin at mdounin.ru Thu Mar 10 13:51:06 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 10 Mar 2016 13:51:06 +0000 Subject: [nginx] Dynamic modules: do not overwrite old modules on install. Message-ID: details: http://hg.nginx.org/nginx/rev/05c894a598ea branches: changeset: 6425:05c894a598ea user: Maxim Dounin date: Thu Mar 10 16:50:13 2016 +0300 description: Dynamic modules: do not overwrite old modules on install. Just using "cp" is incorrect, as it will overwrite old files possibly used by OS, leading to unexpected effects. Changed to "mv + cp", much like used for the main binary. diffstat: auto/init | 1 - auto/install | 18 ++++++++++++++++-- auto/make | 2 -- 3 files changed, 16 insertions(+), 5 deletions(-) diffs (60 lines): diff --git a/auto/init b/auto/init --- a/auto/init +++ b/auto/init @@ -5,7 +5,6 @@ NGX_MAKEFILE=$NGX_OBJS/Makefile NGX_MODULES_C=$NGX_OBJS/ngx_modules.c -NGX_MODULES= NGX_AUTO_HEADERS_H=$NGX_OBJS/ngx_auto_headers.h NGX_AUTO_CONFIG_H=$NGX_OBJS/ngx_auto_config.h diff --git a/auto/install b/auto/install --- a/auto/install +++ b/auto/install @@ -169,17 +169,31 @@ END fi -if test -n "$NGX_MODULES"; then +if test -n "$DYNAMIC_MODULES"; then cat << END >> $NGX_MAKEFILE test -d '\$(DESTDIR)$NGX_MODULES_PATH' \ || mkdir -p '\$(DESTDIR)$NGX_MODULES_PATH' - cp $NGX_MODULES '\$(DESTDIR)$NGX_MODULES_PATH' END fi +for ngx_module in $DYNAMIC_MODULES +do + ngx_module=$ngx_module$ngx_modext + + cat << END >> $NGX_MAKEFILE + + test ! -f '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \ + || mv '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \ + '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module.old' + cp $NGX_OBJS/$ngx_module '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' +END + +done + + # create Makefile cat << END >> Makefile diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -609,8 +609,6 @@ END ngx_obj=$NGX_OBJS$ngx_dirsep$ngx_module$ngx_modext - NGX_MODULES="$NGX_MODULES $ngx_obj" - if [ "$NGX_PLATFORM" = win32 ]; then ngx_module_libs="$CORE_LIBS $ngx_module_libs" fi From ru at nginx.com Thu Mar 10 15:31:35 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 10 Mar 2016 15:31:35 +0000 Subject: [nginx] Configure: style. Message-ID: details: http://hg.nginx.org/nginx/rev/1cbd7f87c6ed branches: changeset: 6426:1cbd7f87c6ed user: Ruslan Ermilov date: Thu Mar 10 18:31:05 2016 +0300 description: Configure: style. Generate Makefile with not so long lines. diffstat: auto/install | 44 ++++++++++++++++++++++---------------------- 1 files changed, 22 insertions(+), 22 deletions(-) diffs (106 lines): diff -r 05c894a598ea -r 1cbd7f87c6ed auto/install --- a/auto/install Thu Mar 10 16:50:13 2016 +0300 +++ b/auto/install Thu Mar 10 18:31:05 2016 +0300 @@ -107,54 +107,54 @@ manpage: $NGX_OBJS/nginx.8 install: build $NGX_INSTALL_PERL_MODULES test -d '\$(DESTDIR)$NGX_PREFIX' || mkdir -p '\$(DESTDIR)$NGX_PREFIX' - test -d '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' \ + test -d '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' \\ || mkdir -p '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' - test ! -f '\$(DESTDIR)$NGX_SBIN_PATH' \ - || mv '\$(DESTDIR)$NGX_SBIN_PATH' \ + test ! -f '\$(DESTDIR)$NGX_SBIN_PATH' \\ + || mv '\$(DESTDIR)$NGX_SBIN_PATH' \\ '\$(DESTDIR)$NGX_SBIN_PATH.old' cp $NGX_OBJS/nginx '\$(DESTDIR)$NGX_SBIN_PATH' - test -d '\$(DESTDIR)$NGX_CONF_PREFIX' \ + test -d '\$(DESTDIR)$NGX_CONF_PREFIX' \\ || mkdir -p '\$(DESTDIR)$NGX_CONF_PREFIX' cp conf/koi-win '\$(DESTDIR)$NGX_CONF_PREFIX' cp conf/koi-utf '\$(DESTDIR)$NGX_CONF_PREFIX' cp conf/win-utf '\$(DESTDIR)$NGX_CONF_PREFIX' - test -f '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types' \ + test -f '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types' \\ || cp conf/mime.types '\$(DESTDIR)$NGX_CONF_PREFIX' cp conf/mime.types '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types.default' - test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params' \ + test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params' \\ || cp conf/fastcgi_params '\$(DESTDIR)$NGX_CONF_PREFIX' - cp conf/fastcgi_params \ + cp conf/fastcgi_params \\ '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params.default' - test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf' \ + test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf' \\ || cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX' cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf.default' - test -f '\$(DESTDIR)$NGX_CONF_PREFIX/uwsgi_params' \ + test -f '\$(DESTDIR)$NGX_CONF_PREFIX/uwsgi_params' \\ || cp conf/uwsgi_params '\$(DESTDIR)$NGX_CONF_PREFIX' - cp conf/uwsgi_params \ + cp conf/uwsgi_params \\ '\$(DESTDIR)$NGX_CONF_PREFIX/uwsgi_params.default' - test -f '\$(DESTDIR)$NGX_CONF_PREFIX/scgi_params' \ + test -f '\$(DESTDIR)$NGX_CONF_PREFIX/scgi_params' \\ || cp conf/scgi_params '\$(DESTDIR)$NGX_CONF_PREFIX' - cp conf/scgi_params \ + cp conf/scgi_params \\ '\$(DESTDIR)$NGX_CONF_PREFIX/scgi_params.default' - test -f '\$(DESTDIR)$NGX_CONF_PATH' \ + test -f '\$(DESTDIR)$NGX_CONF_PATH' \\ || cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PATH' cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PREFIX/nginx.conf.default' - test -d '\$(DESTDIR)`dirname "$NGX_PID_PATH"`' \ + test -d '\$(DESTDIR)`dirname "$NGX_PID_PATH"`' \\ || mkdir -p '\$(DESTDIR)`dirname "$NGX_PID_PATH"`' - test -d '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`' || \ - mkdir -p '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`' + test -d '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`' \\ + || mkdir -p '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`' - test -d '\$(DESTDIR)$NGX_PREFIX/html' \ + test -d '\$(DESTDIR)$NGX_PREFIX/html' \\ || cp -R $NGX_HTML '\$(DESTDIR)$NGX_PREFIX' END @@ -162,8 +162,8 @@ END if test -n "$NGX_ERROR_LOG_PATH"; then cat << END >> $NGX_MAKEFILE - test -d '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' || \ - mkdir -p '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' + test -d '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' \\ + || mkdir -p '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' END fi @@ -172,7 +172,7 @@ fi if test -n "$DYNAMIC_MODULES"; then cat << END >> $NGX_MAKEFILE - test -d '\$(DESTDIR)$NGX_MODULES_PATH' \ + test -d '\$(DESTDIR)$NGX_MODULES_PATH' \\ || mkdir -p '\$(DESTDIR)$NGX_MODULES_PATH' END @@ -185,8 +185,8 @@ do cat << END >> $NGX_MAKEFILE - test ! -f '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \ - || mv '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \ + test ! -f '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \\ + || mv '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \\ '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module.old' cp $NGX_OBJS/$ngx_module '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' END From mdounin at mdounin.ru Thu Mar 10 18:58:33 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 10 Mar 2016 18:58:33 +0000 Subject: [nginx] Upstream: fixed "zero size buf" alerts with cache (ticket #918). Message-ID: details: http://hg.nginx.org/nginx/rev/ad3f342f14ba branches: changeset: 6427:ad3f342f14ba user: Maxim Dounin date: Thu Mar 10 21:58:03 2016 +0300 description: Upstream: fixed "zero size buf" alerts with cache (ticket #918). If caching was used, "zero size buf in output" alerts might appear in logs if a client prematurely closed connection. Alerts appeared in the following situation: - writing to client returned an error, so event pipe drained all busy buffers leaving body output filters in an invalid state; - when upstream response was fully received, ngx_http_upstream_finalize_request() tried to flush all pending data. Fix is to avoid flushing body if p->downstream_error is set. diffstat: src/http/ngx_http_upstream.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -4068,7 +4068,8 @@ ngx_http_upstream_finalize_request(ngx_h if (!u->header_sent || rc == NGX_HTTP_REQUEST_TIME_OUT - || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST) + || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST + || (u->pipe && u->pipe->downstream_error)) { ngx_http_finalize_request(r, rc); return; From mdounin at mdounin.ru Thu Mar 10 20:39:24 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 10 Mar 2016 20:39:24 +0000 Subject: [nginx] Upstream: avoid closing client connection in edge case. Message-ID: details: http://hg.nginx.org/nginx/rev/545b5e4d83b2 branches: changeset: 6428:545b5e4d83b2 user: Justin Li date: Tue Mar 08 22:31:55 2016 -0500 description: Upstream: avoid closing client connection in edge case. If proxy_cache is enabled, and proxy_no_cache tests true, it was previously possible for the client connection to be closed after a 304. The fix is to recheck r->header_only after the final cacheability is determined, and end the request if no longer cacheable. Example configuration: proxy_cache foo; proxy_cache_bypass 1; proxy_no_cache 1; If a client sends If-None-Match, and the upstream server returns 200 with a matching ETag, no body should be returned to the client. At the start of ngx_http_upstream_send_response proxy_no_cache is not yet tested, thus cacheable is still 1 and downstream_error is set. However, by the time the downstream_error check is done in process_request, proxy_no_cache has been tested and cacheable is set to 0. The client connection is then closed, regardless of keepalive. diffstat: src/http/ngx_http_upstream.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -2861,6 +2861,11 @@ ngx_http_upstream_send_response(ngx_http ngx_http_file_cache_free(r->cache, u->pipe->temp_file); } + if (r->header_only && !u->cacheable && !u->store) { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + #endif p = u->pipe; From mdounin at mdounin.ru Thu Mar 10 20:39:44 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 10 Mar 2016 23:39:44 +0300 Subject: [PATCH] Upstream: avoid closing client connection in edge case In-Reply-To: <80d1d2148e4bd82eb27e.1457494812@tomato> References: <80d1d2148e4bd82eb27e.1457494812@tomato> Message-ID: <20160310203944.GE12808@mdounin.ru> Hello! On Tue, Mar 08, 2016 at 10:40:12PM -0500, Justin Li wrote: > # HG changeset patch > # User Justin Li > # Date 1457494315 18000 > # Tue Mar 08 22:31:55 2016 -0500 > # Node ID 80d1d2148e4bd82eb27e50fba91fa36fed039871 > # Parent c5f81dcf97a79576138917501c9a6cc6f53ee930 > Upstream: avoid closing client connection in edge case. > > If proxy_cache is enabled, and proxy_no_cache tests true, it was previously > possible for the client connection to be closed after a 304. The fix is to > recheck r->header_only after the final cacheability is determined, and end the > request if no longer cacheable. > > Example configuration: > > proxy_cache foo; > proxy_cache_bypass 1; > proxy_no_cache 1; > > If a client sends If-None-Match, and the upstream server returns 200 with a > matching ETag, no body should be returned to the client. At the start of > ngx_http_upstream_send_response proxy_no_cache is not yet tested, thus cacheable > is still 1 and downstream_error is set. > > However, by the time the downstream_error check is done in process_request, > proxy_no_cache has been tested and cacheable is set to 0. The client connection > is then closed, regardless of keepalive. > > diff -r c5f81dcf97a7 -r 80d1d2148e4b src/http/ngx_http_upstream.c > --- a/src/http/ngx_http_upstream.c Thu Mar 03 21:14:19 2016 +0300 > +++ b/src/http/ngx_http_upstream.c Tue Mar 08 22:31:55 2016 -0500 > @@ -2861,6 +2861,11 @@ ngx_http_upstream_send_response(ngx_http > ngx_http_file_cache_free(r->cache, u->pipe->temp_file); > } > > + if (r->header_only && !u->cacheable && !u->store) { > + ngx_http_upstream_finalize_request(r, u, 0); > + return; > + } > + > #endif > > p = u->pipe; Committed, thanks. -- Maxim Dounin http://nginx.org/ From joel.cunningham at me.com Mon Mar 14 14:28:01 2016 From: joel.cunningham at me.com (Joel Cunningham) Date: Mon, 14 Mar 2016 14:28:01 +0000 (GMT) Subject: [PATCH] Correct reference to GCC compiler macro Message-ID: <1f886976-0274-4c90-b2c5-ee1763f7b50d@me.com> Anyone have comments on this small change?? Any interest in accepting it? Thanks, Joel On Mar 01, 2016, at 01:40 PM, Joel Cunningham wrote: # HG changeset patch # User Joel Cunningham # Date 1456860378 21600 # Tue Mar 01 13:26:18 2016 -0600 # Node ID cce5f2f6ed76ffa0f6890e90e7b1b68718ffa8a9 # Parent 3b9fe734a76ca0863ec87596369690831e9f4086 Correct reference to GCC compiler macro This commit corrects a small typo where __GNU__ was used in place of __GNUC__ This was identified on a GCC system that built with undefined macros treated as errors when used with #if diff -r 3b9fe734a76c -r cce5f2f6ed76 src/core/ngx_config.h --- a/src/core/ngx_config.h Tue Mar 01 15:18:07 2016 +0300 +++ b/src/core/ngx_config.h Tue Mar 01 13:26:18 2016 -0600 @@ -125,7 +125,7 @@ #endif -#if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8)) +#if ((__GNUC__ == 2) && (__GNUC_MINOR__ < 8)) #define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffffLL #else #define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffff _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Mon Mar 14 14:45:57 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 14 Mar 2016 17:45:57 +0300 Subject: [PATCH] Correct reference to GCC compiler macro In-Reply-To: <1f886976-0274-4c90-b2c5-ee1763f7b50d@me.com> References: <1f886976-0274-4c90-b2c5-ee1763f7b50d@me.com> Message-ID: <20160314144556.GR12808@mdounin.ru> Hello! On Mon, Mar 14, 2016 at 02:28:01PM +0000, Joel Cunningham wrote: > Anyone have comments on this small change?? Any interest in accepting it? It might be better idea to just remove the whole chunk. If the typo exists for years and nobody noticed, it's probably not needed at all - either because it works fine or because nobody uses so old GCC. I don't have GCC 2.7 on hand to test though. -- Maxim Dounin http://nginx.org/ From pluknet at nginx.com Mon Mar 14 16:24:02 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Mon, 14 Mar 2016 16:24:02 +0000 Subject: [nginx] Fixed compilation with -Wmissing-prototypes. Message-ID: details: http://hg.nginx.org/nginx/rev/3600bbfb43e3 branches: changeset: 6429:3600bbfb43e3 user: Sergey Kandaurov date: Mon Mar 14 19:23:23 2016 +0300 description: Fixed compilation with -Wmissing-prototypes. diffstat: src/core/ngx_module.c | 2 +- src/core/ngx_module.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff -r 545b5e4d83b2 -r 3600bbfb43e3 src/core/ngx_module.c --- a/src/core/ngx_module.c Tue Mar 08 22:31:55 2016 -0500 +++ b/src/core/ngx_module.c Mon Mar 14 19:23:23 2016 +0300 @@ -23,7 +23,7 @@ static ngx_uint_t ngx_modules_n; ngx_int_t -ngx_preinit_modules() +ngx_preinit_modules(void) { ngx_uint_t i; diff -r 545b5e4d83b2 -r 3600bbfb43e3 src/core/ngx_module.h --- a/src/core/ngx_module.h Tue Mar 08 22:31:55 2016 -0500 +++ b/src/core/ngx_module.h Mon Mar 14 19:23:23 2016 +0300 @@ -288,7 +288,7 @@ typedef struct { } ngx_core_module_t; -ngx_int_t ngx_preinit_modules(); +ngx_int_t ngx_preinit_modules(void); ngx_int_t ngx_cycle_modules(ngx_cycle_t *cycle); ngx_int_t ngx_init_modules(ngx_cycle_t *cycle); ngx_int_t ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type); From arut at nginx.com Tue Mar 15 10:05:45 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 15 Mar 2016 10:05:45 +0000 Subject: [nginx] Events: fixed error logging in devpoll. Message-ID: details: http://hg.nginx.org/nginx/rev/33aef5cd3d43 branches: changeset: 6430:33aef5cd3d43 user: Roman Arutyunyan date: Tue Mar 15 00:04:04 2016 +0300 description: Events: fixed error logging in devpoll. diffstat: src/event/modules/ngx_devpoll_module.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 3600bbfb43e3 -r 33aef5cd3d43 src/event/modules/ngx_devpoll_module.c --- a/src/event/modules/ngx_devpoll_module.c Mon Mar 14 19:23:23 2016 +0300 +++ b/src/event/modules/ngx_devpoll_module.c Tue Mar 15 00:04:04 2016 +0300 @@ -436,7 +436,7 @@ ngx_devpoll_process_events(ngx_cycle_t * default: ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "unexpected event %04Xd for closed and removed socket %d, ", + "unexpected event %04Xd for closed and removed socket %d, " "ioctl(DP_ISPOLLED) returned rc:%d, fd:%d, event %04Xd", revents, fd, rc, pfd.fd, pfd.revents); From vbart at nginx.com Tue Mar 15 10:18:40 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 15 Mar 2016 10:18:40 +0000 Subject: [nginx] Fixed handling of EAGAIN with sendfile in threads. Message-ID: details: http://hg.nginx.org/nginx/rev/3b9c6b91d988 branches: changeset: 6431:3b9c6b91d988 user: Valentin Bartenev date: Mon Mar 14 22:42:35 2016 +0300 description: Fixed handling of EAGAIN with sendfile in threads. diffstat: src/os/unix/ngx_linux_sendfile_chain.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (17 lines): diff -r 33aef5cd3d43 -r 3b9c6b91d988 src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c Tue Mar 15 00:04:04 2016 +0300 +++ b/src/os/unix/ngx_linux_sendfile_chain.c Mon Mar 14 22:42:35 2016 +0300 @@ -343,7 +343,12 @@ ngx_linux_sendfile_thread(ngx_connection if (task->event.complete) { task->event.complete = 0; - if (ctx->err && ctx->err != NGX_EAGAIN) { + if (ctx->err == NGX_EAGAIN) { + *sent = 0; + return NGX_AGAIN; + } + + if (ctx->err) { wev->error = 1; ngx_connection_error(c, ctx->err, "sendfile() failed"); return NGX_ERROR; From ru at nginx.com Tue Mar 15 11:29:16 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 15 Mar 2016 11:29:16 +0000 Subject: [nginx] Added variables support to server_tokens. Message-ID: details: http://hg.nginx.org/nginx/rev/cf3e75cfa951 branches: changeset: 6432:cf3e75cfa951 user: Ruslan Ermilov date: Tue Mar 15 13:36:19 2016 +0300 description: Added variables support to server_tokens. It can now be set to "off" conditionally, e.g. using the map directive. An empty value will disable the emission of the Server: header and the signature in error messages generated by nginx. Any other value is treated as "on", meaning that full nginx version is emitted in the Server: header and error messages generated by nginx. diffstat: src/http/ngx_http_core_module.c | 56 ++++++++++++++++++++++++++++-- src/http/ngx_http_core_module.h | 4 +- src/http/ngx_http_header_filter_module.c | 45 ++++++++++++++++-------- src/http/ngx_http_special_response.c | 58 +++++++++++++++++++++++-------- src/http/v2/ngx_http_v2_filter_module.c | 50 ++++++++++++++++++++++----- 5 files changed, 166 insertions(+), 47 deletions(-) diffs (377 lines): diff -r 3b9c6b91d988 -r cf3e75cfa951 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Mon Mar 14 22:42:35 2016 +0300 +++ b/src/http/ngx_http_core_module.c Tue Mar 15 13:36:19 2016 +0300 @@ -59,6 +59,8 @@ static char *ngx_http_core_set_aio(ngx_c void *conf); static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_core_server_tokens(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, @@ -585,10 +587,10 @@ static ngx_command_t ngx_http_core_comm NULL }, { ngx_string("server_tokens"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_core_server_tokens, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, server_tokens), + 0, NULL }, { ngx_string("if_modified_since"), @@ -3635,9 +3637,9 @@ ngx_http_core_create_loc_conf(ngx_conf_t clcf->log_not_found = NGX_CONF_UNSET; clcf->log_subrequest = NGX_CONF_UNSET; clcf->recursive_error_pages = NGX_CONF_UNSET; - clcf->server_tokens = NGX_CONF_UNSET; clcf->chunked_transfer_encoding = NGX_CONF_UNSET; clcf->etag = NGX_CONF_UNSET; + clcf->server_tokens = NGX_CONF_UNSET_UINT; clcf->types_hash_max_size = NGX_CONF_UNSET_UINT; clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT; @@ -3900,11 +3902,15 @@ ngx_http_core_merge_loc_conf(ngx_conf_t ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0); ngx_conf_merge_value(conf->recursive_error_pages, prev->recursive_error_pages, 0); - ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1); ngx_conf_merge_value(conf->chunked_transfer_encoding, prev->chunked_transfer_encoding, 1); ngx_conf_merge_value(conf->etag, prev->etag, 1); + if (conf->server_tokens == NGX_CONF_UNSET_UINT) { + ngx_conf_merge_uint_value(conf->server_tokens, prev->server_tokens, 1); + conf->server_tokens_value = prev->server_tokens_value; + } + ngx_conf_merge_ptr_value(conf->open_file_cache, prev->open_file_cache, NULL); @@ -4787,6 +4793,46 @@ ngx_http_core_directio(ngx_conf_t *cf, n static char * +ngx_http_core_server_tokens(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_core_loc_conf_t *clcf = conf; + + ngx_str_t *value; + ngx_http_compile_complex_value_t ccv; + + if (clcf->server_tokens != NGX_CONF_UNSET_UINT) { + return "is duplicate"; + } + + value = cf->args->elts; + + if (ngx_strcmp(value[1].data, "on") == 0) { + clcf->server_tokens = 1; + return NGX_CONF_OK; + } + + if (ngx_strcmp(value[1].data, "off") == 0) { + clcf->server_tokens = 0; + return NGX_CONF_OK; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &clcf->server_tokens_value; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + + clcf->server_tokens = 2; + + return NGX_CONF_OK; +} + + +static char * ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf = conf; diff -r 3b9c6b91d988 -r cf3e75cfa951 src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Mon Mar 14 22:42:35 2016 +0300 +++ b/src/http/ngx_http_core_module.h Tue Mar 15 13:36:19 2016 +0300 @@ -414,10 +414,12 @@ struct ngx_http_core_loc_conf_s { ngx_flag_t log_not_found; /* log_not_found */ ngx_flag_t log_subrequest; /* log_subrequest */ ngx_flag_t recursive_error_pages; /* recursive_error_pages */ - ngx_flag_t server_tokens; /* server_tokens */ ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */ ngx_flag_t etag; /* etag */ + ngx_uint_t server_tokens; /* server_tokens */ + ngx_http_complex_value_t server_tokens_value; + #if (NGX_HTTP_GZIP) ngx_flag_t gzip_vary; /* gzip_vary */ diff -r 3b9c6b91d988 -r cf3e75cfa951 src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c Mon Mar 14 22:42:35 2016 +0300 +++ b/src/http/ngx_http_header_filter_module.c Tue Mar 15 13:36:19 2016 +0300 @@ -46,8 +46,8 @@ ngx_module_t ngx_http_header_filter_mod }; -static char ngx_http_server_string[] = "Server: nginx" CRLF; -static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF; +static u_char ngx_http_server_string[] = "Server: nginx" CRLF; +static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF; static ngx_str_t ngx_http_status_lines[] = { @@ -152,7 +152,7 @@ ngx_http_header_filter(ngx_http_request_ { u_char *p; size_t len; - ngx_str_t host, *status_line; + ngx_str_t host, *status_line, tokens; ngx_buf_t *b; ngx_uint_t status, i, port; ngx_chain_t out; @@ -278,8 +278,30 @@ ngx_http_header_filter(ngx_http_request_ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->headers_out.server == NULL) { - len += clcf->server_tokens ? sizeof(ngx_http_server_full_string) - 1: - sizeof(ngx_http_server_string) - 1; + if (clcf->server_tokens == 0) { + ngx_str_set(&tokens, ngx_http_server_string); + + } else if (clcf->server_tokens == 1) { + ngx_str_set(&tokens, ngx_http_server_full_string); + + } else { + if (ngx_http_complex_value(r, &clcf->server_tokens_value, &tokens) + != NGX_OK) + { + return NGX_ERROR; + } + + if (tokens.len == 3 + && ngx_strncmp(tokens.data, "off", 3) == 0) + { + ngx_str_set(&tokens, ngx_http_server_string); + + } else if (tokens.len) { + ngx_str_set(&tokens, ngx_http_server_full_string); + } + } + + len += tokens.len; } if (r->headers_out.date == NULL) { @@ -455,17 +477,8 @@ ngx_http_header_filter(ngx_http_request_ } *b->last++ = CR; *b->last++ = LF; - if (r->headers_out.server == NULL) { - if (clcf->server_tokens) { - p = (u_char *) ngx_http_server_full_string; - len = sizeof(ngx_http_server_full_string) - 1; - - } else { - p = (u_char *) ngx_http_server_string; - len = sizeof(ngx_http_server_string) - 1; - } - - b->last = ngx_cpymem(b->last, p, len); + if (r->headers_out.server == NULL && tokens.len) { + b->last = ngx_cpymem(b->last, tokens.data, tokens.len); } if (r->headers_out.date == NULL) { diff -r 3b9c6b91d988 -r cf3e75cfa951 src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c Mon Mar 14 22:42:35 2016 +0300 +++ b/src/http/ngx_http_special_response.c Tue Mar 15 13:36:19 2016 +0300 @@ -32,6 +32,12 @@ static u_char ngx_http_error_tail[] = ; +static u_char ngx_http_error_no_tail[] = +"" CRLF +"" CRLF +; + + static u_char ngx_http_msie_padding[] = "" CRLF "" CRLF @@ -609,26 +615,45 @@ static ngx_int_t ngx_http_send_special_response(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf, ngx_uint_t err) { - u_char *tail; - size_t len; ngx_int_t rc; + ngx_str_t tail, tokens; ngx_buf_t *b; ngx_uint_t msie_padding; ngx_chain_t out[3]; - if (clcf->server_tokens) { - len = sizeof(ngx_http_error_full_tail) - 1; - tail = ngx_http_error_full_tail; - - } else { - len = sizeof(ngx_http_error_tail) - 1; - tail = ngx_http_error_tail; - } - msie_padding = 0; if (ngx_http_error_pages[err].len) { - r->headers_out.content_length_n = ngx_http_error_pages[err].len + len; + + if (clcf->server_tokens == 0) { + ngx_str_set(&tail, ngx_http_error_tail); + + } else if (clcf->server_tokens == 1) { + ngx_str_set(&tail, ngx_http_error_full_tail); + + } else { + if (ngx_http_complex_value(r, &clcf->server_tokens_value, &tokens) + != NGX_OK) + { + return NGX_ERROR; + } + + if (tokens.len == 3 + && ngx_strncmp(tokens.data, "off", 3) == 0) + { + ngx_str_set(&tail, ngx_http_error_tail); + + } else if (tokens.len) { + ngx_str_set(&tail, ngx_http_error_full_tail); + + } else { + ngx_str_set(&tail, ngx_http_error_no_tail); + } + } + + r->headers_out.content_length_n = ngx_http_error_pages[err].len + + tail.len; + if (clcf->msie_padding && (r->headers_in.msie || r->headers_in.chrome) && r->http_version >= NGX_HTTP_VERSION_10 @@ -645,6 +670,10 @@ ngx_http_send_special_response(ngx_http_ } else { r->headers_out.content_length_n = 0; + +#if (NGX_SUPPRESS_WARN) + ngx_str_null(&tail); +#endif } if (r->headers_out.content_length) { @@ -684,9 +713,8 @@ ngx_http_send_special_response(ngx_http_ } b->memory = 1; - - b->pos = tail; - b->last = tail + len; + b->pos = tail.data; + b->last = tail.data + tail.len; out[1].buf = b; out[1].next = NULL; diff -r 3b9c6b91d988 -r cf3e75cfa951 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Mon Mar 14 22:42:35 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Tue Mar 15 13:36:19 2016 +0300 @@ -128,8 +128,8 @@ ngx_http_v2_header_filter(ngx_http_reque { u_char status, *pos, *start, *p, *tmp; size_t len, tmp_len; - ngx_str_t host, location; - ngx_uint_t i, port; + ngx_str_t host, location, tokens; + ngx_uint_t i, port, server_tokens; ngx_list_part_t *part; ngx_table_elt_t *header; ngx_connection_t *fc; @@ -229,8 +229,38 @@ ngx_http_v2_header_filter(ngx_http_reque clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + server_tokens = clcf->server_tokens; + if (r->headers_out.server == NULL) { - len += 1 + (clcf->server_tokens ? nginx_ver_len : sizeof(nginx)); + + if (server_tokens == 0) { + len += 1 + sizeof(nginx); + ngx_str_set(&tokens, "nginx"); + + } else if (server_tokens == 1) { + len += 1 + nginx_ver_len; + ngx_str_set(&tokens, NGINX_VER); + + } else { + if (ngx_http_complex_value(r, &clcf->server_tokens_value, &tokens) + != NGX_OK) + { + return NGX_ERROR; + } + + if (tokens.len == 3 + && ngx_strncmp(tokens.data, "off", 3) == 0) + { + server_tokens = 0; + len += 1 + sizeof(nginx); + ngx_str_set(&tokens, "nginx"); + + } else if (tokens.len) { + server_tokens = 1; + len += 1 + nginx_ver_len; + ngx_str_set(&tokens, NGINX_VER); + } + } } if (r->headers_out.date == NULL) { @@ -434,14 +464,17 @@ ngx_http_v2_header_filter(ngx_http_reque pos = ngx_sprintf(pos, "%03ui", r->headers_out.status); } - if (r->headers_out.server == NULL) { + if (r->headers_out.server == NULL && tokens.len) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, - "http2 output header: \"server: %s\"", - clcf->server_tokens ? NGINX_VER : "nginx"); + "http2 output header: \"server: %V\"", + &tokens); *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX); - if (clcf->server_tokens) { + if (server_tokens == 0) { + pos = ngx_cpymem(pos, nginx, sizeof(nginx)); + + } else { if (nginx_ver[0] == '\0') { p = ngx_http_v2_write_value(nginx_ver, (u_char *) NGINX_VER, sizeof(NGINX_VER) - 1, tmp); @@ -449,9 +482,6 @@ ngx_http_v2_header_filter(ngx_http_reque } pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len); - - } else { - pos = ngx_cpymem(pos, nginx, sizeof(nginx)); } } From ru at nginx.com Tue Mar 15 12:11:47 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 15 Mar 2016 12:11:47 +0000 Subject: [nginx] Win32: fixed build after cf3e75cfa951. Message-ID: details: http://hg.nginx.org/nginx/rev/6b72414dfb4f branches: changeset: 6433:6b72414dfb4f user: Ruslan Ermilov date: Tue Mar 15 15:10:41 2016 +0300 description: Win32: fixed build after cf3e75cfa951. diffstat: src/http/ngx_http_header_filter_module.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r cf3e75cfa951 -r 6b72414dfb4f src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c Tue Mar 15 13:36:19 2016 +0300 +++ b/src/http/ngx_http_header_filter_module.c Tue Mar 15 15:10:41 2016 +0300 @@ -277,6 +277,10 @@ ngx_http_header_filter(ngx_http_request_ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); +#if (NGX_SUPPRESS_WARN) + ngx_str_null(&tokens); +#endif + if (r->headers_out.server == NULL) { if (clcf->server_tokens == 0) { ngx_str_set(&tokens, ngx_http_server_string); From ru at nginx.com Tue Mar 15 12:16:21 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 15 Mar 2016 12:16:21 +0000 Subject: [nginx] Win32: fixed build after cf3e75cfa951. Message-ID: details: http://hg.nginx.org/nginx/rev/602dc42035fe branches: changeset: 6434:602dc42035fe user: Ruslan Ermilov date: Tue Mar 15 15:15:30 2016 +0300 description: Win32: fixed build after cf3e75cfa951. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r 6b72414dfb4f -r 602dc42035fe src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Tue Mar 15 15:10:41 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Tue Mar 15 15:15:30 2016 +0300 @@ -231,6 +231,10 @@ ngx_http_v2_header_filter(ngx_http_reque server_tokens = clcf->server_tokens; +#if (NGX_SUPPRESS_WARN) + ngx_str_null(&tokens); +#endif + if (r->headers_out.server == NULL) { if (server_tokens == 0) { From arut at nginx.com Tue Mar 15 13:08:39 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 15 Mar 2016 13:08:39 +0000 Subject: [nginx] Stream: post first read events from client and upstream. Message-ID: details: http://hg.nginx.org/nginx/rev/d1c791479bbb branches: changeset: 6435:d1c791479bbb user: Roman Arutyunyan date: Tue Mar 15 15:55:23 2016 +0300 description: Stream: post first read events from client and upstream. The main proxy function ngx_stream_proxy_process() can terminate the stream session. The code, following it, should check its return code to make sure the session still exists. This happens in client and upstream initialization functions. Swapping ngx_stream_proxy_process() call with the code, that follows it, leaves the same problem vice versa. In future ngx_stream_proxy_process() will call ngx_stream_proxy_next_upstream() making it too complicated to know if stream session still exists after this call. Now ngx_stream_proxy_process() is called from posted event handlers in both places with no code following it. The posted event is automatically removed once session is terminated. diffstat: src/stream/ngx_stream_proxy_module.c | 22 ++++++++++------------ 1 files changed, 10 insertions(+), 12 deletions(-) diffs (85 lines): diff -r 602dc42035fe -r d1c791479bbb src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Tue Mar 15 15:15:30 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Tue Mar 15 15:55:23 2016 +0300 @@ -54,7 +54,7 @@ static void ngx_stream_proxy_process_con ngx_uint_t from_upstream); static void ngx_stream_proxy_connect_handler(ngx_event_t *ev); static ngx_int_t ngx_stream_proxy_test_connect(ngx_connection_t *c); -static ngx_int_t ngx_stream_proxy_process(ngx_stream_session_t *s, +static void ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream, ngx_uint_t do_write); static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s); static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc); @@ -406,8 +406,8 @@ ngx_stream_proxy_handler(ngx_stream_sess u->proxy_protocol = 0; } - if (ngx_stream_proxy_process(s, 0, 0) != NGX_OK) { - return; + if (c->read->ready) { + ngx_post_event(c->read, &ngx_posted_events); } ngx_stream_proxy_connect(s); @@ -560,8 +560,8 @@ ngx_stream_proxy_init_upstream(ngx_strea pc->read->handler = ngx_stream_proxy_upstream_handler; pc->write->handler = ngx_stream_proxy_upstream_handler; - if (ngx_stream_proxy_process(s, 1, 0) != NGX_OK) { - return; + if (pc->read->ready) { + ngx_post_event(pc->read, &ngx_posted_events); } ngx_stream_proxy_process(s, 0, 1); @@ -1019,7 +1019,7 @@ ngx_stream_proxy_test_connect(ngx_connec } -static ngx_int_t +static void ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream, ngx_uint_t do_write) { @@ -1068,7 +1068,7 @@ ngx_stream_proxy_process(ngx_stream_sess if (n == NGX_ERROR) { ngx_stream_proxy_finalize(s, NGX_DECLINED); - return NGX_ERROR; + return; } if (n > 0) { @@ -1147,20 +1147,20 @@ ngx_stream_proxy_process(ngx_stream_sess c->log->handler = handler; ngx_stream_proxy_finalize(s, NGX_OK); - return NGX_DONE; + return; } flags = src->read->eof ? NGX_CLOSE_EVENT : 0; if (ngx_handle_read_event(src->read, flags) != NGX_OK) { ngx_stream_proxy_finalize(s, NGX_ERROR); - return NGX_ERROR; + return; } if (dst) { if (ngx_handle_write_event(dst->write, 0) != NGX_OK) { ngx_stream_proxy_finalize(s, NGX_ERROR); - return NGX_ERROR; + return; } if (!c->read->delayed && !pc->read->delayed) { @@ -1170,8 +1170,6 @@ ngx_stream_proxy_process(ngx_stream_sess ngx_del_timer(c->write); } } - - return NGX_OK; } From arut at nginx.com Tue Mar 15 13:08:42 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 15 Mar 2016 13:08:42 +0000 Subject: [nginx] Stream: UDP proxy. Message-ID: details: http://hg.nginx.org/nginx/rev/8f038068f4bc branches: changeset: 6436:8f038068f4bc user: Roman Arutyunyan date: Wed Jan 20 19:52:12 2016 +0300 description: Stream: UDP proxy. diffstat: auto/options | 4 +- auto/sources | 1 + auto/unix | 39 +++ src/core/ngx_connection.c | 92 ++++++- src/core/ngx_connection.h | 4 + src/event/ngx_event.c | 4 +- src/event/ngx_event.h | 4 + src/event/ngx_event_accept.c | 443 ++++++++++++++++++++++++++++++---- src/event/ngx_event_connect.c | 47 ++- src/event/ngx_event_connect.h | 1 + src/os/unix/ngx_darwin_init.c | 1 + src/os/unix/ngx_freebsd_init.c | 1 + src/os/unix/ngx_linux_init.c | 1 + src/os/unix/ngx_os.h | 2 + src/os/unix/ngx_posix_init.c | 1 + src/os/unix/ngx_solaris_init.c | 1 + src/os/unix/ngx_udp_send.c | 56 ++++ src/stream/ngx_stream.c | 9 +- src/stream/ngx_stream.h | 2 + src/stream/ngx_stream_core_module.c | 30 ++- src/stream/ngx_stream_handler.c | 7 +- src/stream/ngx_stream_proxy_module.c | 140 +++++++++-- src/stream/ngx_stream_upstream.h | 1 + 23 files changed, 776 insertions(+), 115 deletions(-) diffs (truncated from 1446 to 1000 lines): diff -r d1c791479bbb -r 8f038068f4bc auto/options --- a/auto/options Tue Mar 15 15:55:23 2016 +0300 +++ b/auto/options Wed Jan 20 19:52:12 2016 +0300 @@ -479,8 +479,8 @@ cat << END --without-mail_imap_module disable ngx_mail_imap_module --without-mail_smtp_module disable ngx_mail_smtp_module - --with-stream enable TCP proxy module - --with-stream=dynamic enable dynamic TCP proxy module + --with-stream enable TCP/UDP proxy module + --with-stream=dynamic enable dynamic TCP/UDP proxy module --with-stream_ssl_module enable ngx_stream_ssl_module --without-stream_limit_conn_module disable ngx_stream_limit_conn_module --without-stream_access_module disable ngx_stream_access_module diff -r d1c791479bbb -r 8f038068f4bc auto/sources --- a/auto/sources Tue Mar 15 15:55:23 2016 +0300 +++ b/auto/sources Wed Jan 20 19:52:12 2016 +0300 @@ -165,6 +165,7 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/unix/ngx_udp_recv.c \ src/os/unix/ngx_send.c \ src/os/unix/ngx_writev_chain.c \ + src/os/unix/ngx_udp_send.c \ src/os/unix/ngx_channel.c \ src/os/unix/ngx_shmem.c \ src/os/unix/ngx_process.c \ diff -r d1c791479bbb -r 8f038068f4bc auto/unix --- a/auto/unix Tue Mar 15 15:55:23 2016 +0300 +++ b/auto/unix Wed Jan 20 19:52:12 2016 +0300 @@ -329,6 +329,45 @@ ngx_feature_test="setsockopt(0, SOL_SOCK . auto/feature +# BSD way to get IPv4 datagram destination address + +ngx_feature="IP_RECVDSTADDR" +ngx_feature_name="NGX_HAVE_IP_RECVDSTADDR" +ngx_feature_run=no +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_RECVDSTADDR, NULL, 0)" +. auto/feature + + +# Linux way to get IPv4 datagram destination address + +ngx_feature="IP_PKTINFO" +ngx_feature_name="NGX_HAVE_IP_PKTINFO" +ngx_feature_run=no +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" +. auto/feature + + +# RFC 3542 way to get IPv6 datagram destination address + +ngx_feature="IPV6_RECVPKTINFO" +ngx_feature_name="NGX_HAVE_IPV6_RECVPKTINFO" +ngx_feature_run=no +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, IPPROTO_IPV6, IPV6_RECVPKTINFO, NULL, 0)" +. auto/feature + + ngx_feature="TCP_DEFER_ACCEPT" ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT" ngx_feature_run=no diff -r d1c791479bbb -r 8f038068f4bc src/core/ngx_connection.c --- a/src/core/ngx_connection.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/core/ngx_connection.c Wed Jan 20 19:52:12 2016 +0300 @@ -566,6 +566,11 @@ ngx_open_listening_sockets(ngx_cycle_t * } #endif + if (ls[i].type != SOCK_STREAM) { + ls[i].fd = s; + continue; + } + if (listen(s, ls[i].backlog) == -1) { err = ngx_socket_errno; @@ -865,6 +870,67 @@ ngx_configure_listening_sockets(ngx_cycl #endif #endif /* NGX_HAVE_DEFERRED_ACCEPT */ + +#if (NGX_HAVE_IP_RECVDSTADDR) + + if (ls[i].wildcard + && ls[i].type == SOCK_DGRAM + && ls[i].sockaddr->sa_family == AF_INET) + { + value = 1; + + if (setsockopt(ls[i].fd, IPPROTO_IP, IP_RECVDSTADDR, + (const void *) &value, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(IP_RECVDSTADDR) " + "for %V failed, ignored", + &ls[i].addr_text); + } + } + +#elif (NGX_HAVE_IP_PKTINFO) + + if (ls[i].wildcard + && ls[i].type == SOCK_DGRAM + && ls[i].sockaddr->sa_family == AF_INET) + { + value = 1; + + if (setsockopt(ls[i].fd, IPPROTO_IP, IP_PKTINFO, + (const void *) &value, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(IP_PKTINFO) " + "for %V failed, ignored", + &ls[i].addr_text); + } + } + +#endif + +#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) + + if (ls[i].wildcard + && ls[i].type == SOCK_DGRAM + && ls[i].sockaddr->sa_family == AF_INET6) + { + value = 1; + + if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, + (const void *) &value, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(IPV6_RECVPKTINFO) " + "for %V failed, ignored", + &ls[i].addr_text); + } + } + +#endif } return; @@ -978,7 +1044,7 @@ ngx_get_connection(ngx_socket_t s, ngx_l ngx_cycle->free_connections = c->data; ngx_cycle->free_connection_n--; - if (ngx_cycle->files) { + if (ngx_cycle->files && ngx_cycle->files[s] == NULL) { ngx_cycle->files[s] = c; } @@ -1019,7 +1085,7 @@ ngx_free_connection(ngx_connection_t *c) ngx_cycle->free_connections = c; ngx_cycle->free_connection_n++; - if (ngx_cycle->files) { + if (ngx_cycle->files && ngx_cycle->files[c->fd] == c) { ngx_cycle->files[c->fd] = NULL; } } @@ -1045,16 +1111,18 @@ ngx_close_connection(ngx_connection_t *c ngx_del_timer(c->write); } - if (ngx_del_conn) { - ngx_del_conn(c, NGX_CLOSE_EVENT); + if (!c->shared) { + if (ngx_del_conn) { + ngx_del_conn(c, NGX_CLOSE_EVENT); - } else { - if (c->read->active || c->read->disabled) { - ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); - } + } else { + if (c->read->active || c->read->disabled) { + ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); + } - if (c->write->active || c->write->disabled) { - ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); + if (c->write->active || c->write->disabled) { + ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); + } } } @@ -1078,6 +1146,10 @@ ngx_close_connection(ngx_connection_t *c fd = c->fd; c->fd = (ngx_socket_t) -1; + if (c->shared) { + return; + } + if (ngx_close_socket(fd) == -1) { err = ngx_socket_errno; diff -r d1c791479bbb -r 8f038068f4bc src/core/ngx_connection.h --- a/src/core/ngx_connection.h Tue Mar 15 15:55:23 2016 +0300 +++ b/src/core/ngx_connection.h Wed Jan 20 19:52:12 2016 +0300 @@ -64,6 +64,7 @@ struct ngx_listening_s { unsigned nonblocking:1; unsigned shared:1; /* shared between threads or processes */ unsigned addr_ntop:1; + unsigned wildcard:1; #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:1; @@ -141,6 +142,8 @@ struct ngx_connection_s { ngx_pool_t *pool; + int type; + struct sockaddr *sockaddr; socklen_t socklen; ngx_str_t addr_text; @@ -174,6 +177,7 @@ struct ngx_connection_s { unsigned idle:1; unsigned reusable:1; unsigned close:1; + unsigned shared:1; unsigned sendfile:1; unsigned sndlowat:1; diff -r d1c791479bbb -r 8f038068f4bc src/event/ngx_event.c --- a/src/event/ngx_event.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/event/ngx_event.c Wed Jan 20 19:52:12 2016 +0300 @@ -746,6 +746,7 @@ ngx_event_process_init(ngx_cycle_t *cycl return NGX_ERROR; } + c->type = ls[i].type; c->log = &ls[i].log; c->listening = &ls[i]; @@ -818,7 +819,8 @@ ngx_event_process_init(ngx_cycle_t *cycl #else - rev->handler = ngx_event_accept; + rev->handler = (c->type == SOCK_STREAM) ? ngx_event_accept + : ngx_event_recvmsg; if (ngx_use_accept_mutex #if (NGX_HAVE_REUSEPORT) diff -r d1c791479bbb -r 8f038068f4bc src/event/ngx_event.h --- a/src/event/ngx_event.h Tue Mar 15 15:55:23 2016 +0300 +++ b/src/event/ngx_event.h Wed Jan 20 19:52:12 2016 +0300 @@ -418,6 +418,7 @@ extern ngx_os_io_t ngx_io; #define ngx_udp_recv ngx_io.udp_recv #define ngx_send ngx_io.send #define ngx_send_chain ngx_io.send_chain +#define ngx_udp_send ngx_io.udp_send #define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */ @@ -491,6 +492,9 @@ extern ngx_module_t ngx_event_ void ngx_event_accept(ngx_event_t *ev); +#if !(NGX_WIN32) +void ngx_event_recvmsg(ngx_event_t *ev); +#endif ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle); u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len); diff -r d1c791479bbb -r 8f038068f4bc src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/event/ngx_event_accept.c Wed Jan 20 19:52:12 2016 +0300 @@ -13,6 +13,10 @@ static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle); static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all); static void ngx_close_accepted_connection(ngx_connection_t *c); +#if (NGX_DEBUG) +static void ngx_debug_accepted_connection(ngx_event_conf_t *ecf, + ngx_connection_t *c); +#endif void @@ -149,6 +153,8 @@ ngx_event_accept(ngx_event_t *ev) return; } + c->type = SOCK_STREAM; + #if (NGX_STAT_STUB) (void) ngx_atomic_fetch_add(ngx_stat_active, 1); #endif @@ -276,60 +282,10 @@ ngx_event_accept(ngx_event_t *ev) #if (NGX_DEBUG) { + ngx_str_t addr; + u_char text[NGX_SOCKADDR_STRLEN]; - ngx_str_t addr; - struct sockaddr_in *sin; - ngx_cidr_t *cidr; - ngx_uint_t i; - u_char text[NGX_SOCKADDR_STRLEN]; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; - ngx_uint_t n; -#endif - - cidr = ecf->debug_connection.elts; - for (i = 0; i < ecf->debug_connection.nelts; i++) { - if (cidr[i].family != (ngx_uint_t) c->sockaddr->sa_family) { - goto next; - } - - switch (cidr[i].family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) c->sockaddr; - for (n = 0; n < 16; n++) { - if ((sin6->sin6_addr.s6_addr[n] - & cidr[i].u.in6.mask.s6_addr[n]) - != cidr[i].u.in6.addr.s6_addr[n]) - { - goto next; - } - } - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) c->sockaddr; - if ((sin->sin_addr.s_addr & cidr[i].u.in.mask) - != cidr[i].u.in.addr) - { - goto next; - } - break; - } - - log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL; - break; - - next: - continue; - } + ngx_debug_accepted_connection(ecf, c); if (log->log_level & NGX_LOG_DEBUG_EVENT) { addr.data = text; @@ -363,6 +319,324 @@ ngx_event_accept(ngx_event_t *ev) } +#if !(NGX_WIN32) + +void +ngx_event_recvmsg(ngx_event_t *ev) +{ + ssize_t n; + ngx_log_t *log; + ngx_err_t err; + ngx_event_t *rev, *wev; + struct iovec iov[1]; + struct msghdr msg; + ngx_listening_t *ls; + ngx_event_conf_t *ecf; + ngx_connection_t *c, *lc; + u_char sa[NGX_SOCKADDRLEN]; + static u_char buffer[65535]; + +#if (NGX_HAVE_MSGHDR_MSG_CONTROL) + +#if (NGX_HAVE_IP_RECVDSTADDR) + u_char msg_control[CMSG_SPACE(sizeof(struct in_addr))]; +#elif (NGX_HAVE_IP_PKTINFO) + u_char msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))]; +#endif + +#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) + u_char msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; +#endif + +#endif + + if (ev->timedout) { + if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) { + return; + } + + ev->timedout = 0; + } + + ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); + + if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) { + ev->available = ecf->multi_accept; + } + + lc = ev->data; + ls = lc->listening; + ev->ready = 0; + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "recvmsg on %V, ready: %d", &ls->addr_text, ev->available); + + do { + ngx_memzero(&msg, sizeof(struct msghdr)); + + iov[0].iov_base = (void *) buffer; + iov[0].iov_len = sizeof(buffer); + + msg.msg_name = &sa; + msg.msg_namelen = sizeof(sa); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + +#if (NGX_HAVE_MSGHDR_MSG_CONTROL) + + if (ls->wildcard) { + +#if (NGX_HAVE_IP_RECVDSTADDR || NGX_HAVE_IP_PKTINFO) + if (ls->sockaddr->sa_family == AF_INET) { + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + } +#endif + +#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) + if (ls->sockaddr->sa_family == AF_INET6) { + msg.msg_control = &msg_control6; + msg.msg_controllen = sizeof(msg_control6); + } +#endif + } + +#endif + + n = recvmsg(lc->fd, &msg, 0); + + if (n == -1) { + err = ngx_socket_errno; + + if (err == NGX_EAGAIN) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err, + "recvmsg() not ready"); + return; + } + + ngx_log_error(NGX_LOG_ALERT, ev->log, err, "recvmsg() failed"); + + return; + } + +#if (NGX_STAT_STUB) + (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1); +#endif + +#if (NGX_HAVE_MSGHDR_MSG_CONTROL) + if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) { + ngx_log_error(NGX_LOG_ALERT, ev->log, 0, + "recvmsg() truncated data"); + continue; + } +#endif + + ngx_accept_disabled = ngx_cycle->connection_n / 8 + - ngx_cycle->free_connection_n; + + c = ngx_get_connection(lc->fd, ev->log); + if (c == NULL) { + return; + } + + c->shared = 1; + c->type = SOCK_DGRAM; + c->socklen = msg.msg_namelen; + +#if (NGX_STAT_STUB) + (void) ngx_atomic_fetch_add(ngx_stat_active, 1); +#endif + + c->pool = ngx_create_pool(ls->pool_size, ev->log); + if (c->pool == NULL) { + ngx_close_accepted_connection(c); + return; + } + + c->sockaddr = ngx_palloc(c->pool, c->socklen); + if (c->sockaddr == NULL) { + ngx_close_accepted_connection(c); + return; + } + + ngx_memcpy(c->sockaddr, msg.msg_name, c->socklen); + + log = ngx_palloc(c->pool, sizeof(ngx_log_t)); + if (log == NULL) { + ngx_close_accepted_connection(c); + return; + } + + *log = ls->log; + + c->send = ngx_udp_send; + + c->log = log; + c->pool->log = log; + + c->listening = ls; + c->local_sockaddr = ls->sockaddr; + c->local_socklen = ls->socklen; + +#if (NGX_HAVE_MSGHDR_MSG_CONTROL) + + if (ls->wildcard) { + struct cmsghdr *cmsg; + struct sockaddr *sockaddr; + + sockaddr = ngx_palloc(c->pool, c->local_socklen); + if (sockaddr == NULL) { + ngx_close_accepted_connection(c); + return; + } + + ngx_memcpy(sockaddr, c->local_sockaddr, c->local_socklen); + c->local_sockaddr = sockaddr; + + for (cmsg = CMSG_FIRSTHDR(&msg); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + +#if (NGX_HAVE_IP_RECVDSTADDR) + + if (cmsg->cmsg_level == IPPROTO_IP + && cmsg->cmsg_type == IP_RECVDSTADDR + && sockaddr->sa_family == AF_INET) + { + struct in_addr *addr; + struct sockaddr_in *sin; + + addr = (struct in_addr *) CMSG_DATA(cmsg); + sin = (struct sockaddr_in *) sockaddr; + sin->sin_addr = *addr; + + break; + } + +#elif (NGX_HAVE_IP_PKTINFO) + + if (cmsg->cmsg_level == IPPROTO_IP + && cmsg->cmsg_type == IP_PKTINFO + && sockaddr->sa_family == AF_INET) + { + struct in_pktinfo *pkt; + struct sockaddr_in *sin; + + pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); + sin = (struct sockaddr_in *) sockaddr; + sin->sin_addr = pkt->ipi_addr; + + break; + } + +#endif + +#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) + + if (cmsg->cmsg_level == IPPROTO_IPV6 + && cmsg->cmsg_type == IPV6_PKTINFO + && sockaddr->sa_family == AF_INET6) + { + struct in6_pktinfo *pkt6; + struct sockaddr_in6 *sin6; + + pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); + sin6 = (struct sockaddr_in6 *) sockaddr; + sin6->sin6_addr = pkt6->ipi6_addr; + + break; + } + +#endif + + } + } + +#endif + + c->buffer = ngx_create_temp_buf(c->pool, n); + if (c->buffer == NULL) { + ngx_close_accepted_connection(c); + return; + } + + c->buffer->last = ngx_cpymem(c->buffer->last, buffer, n); + + rev = c->read; + wev = c->write; + + wev->ready = 1; + + rev->log = log; + wev->log = log; + + /* + * TODO: MT: - ngx_atomic_fetch_add() + * or protection by critical section or light mutex + * + * TODO: MP: - allocated in a shared memory + * - ngx_atomic_fetch_add() + * or protection by critical section or light mutex + */ + + c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); + +#if (NGX_STAT_STUB) + (void) ngx_atomic_fetch_add(ngx_stat_handled, 1); +#endif + + if (ls->addr_ntop) { + c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len); + if (c->addr_text.data == NULL) { + ngx_close_accepted_connection(c); + return; + } + + c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen, + c->addr_text.data, + ls->addr_text_max_len, 0); + if (c->addr_text.len == 0) { + ngx_close_accepted_connection(c); + return; + } + } + +#if (NGX_DEBUG) + { + ngx_str_t addr; + u_char text[NGX_SOCKADDR_STRLEN]; + + ngx_debug_accepted_connection(ecf, c); + + if (log->log_level & NGX_LOG_DEBUG_EVENT) { + addr.data = text; + addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text, + NGX_SOCKADDR_STRLEN, 1); + + ngx_log_debug4(NGX_LOG_DEBUG_EVENT, log, 0, + "*%uA recvmsg: %V fd:%d n:%z", + c->number, &addr, c->fd, n); + } + + } +#endif + + log->data = NULL; + log->handler = NULL; + + ls->handler(c); + + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { + ev->available -= n; + } + + } while (ev->available); +} + +#endif + + ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle) { @@ -476,7 +750,7 @@ ngx_close_accepted_connection(ngx_connec fd = c->fd; c->fd = (ngx_socket_t) -1; - if (ngx_close_socket(fd) == -1) { + if (!c->shared && ngx_close_socket(fd) == -1) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, ngx_close_socket_n " failed"); } @@ -497,3 +771,64 @@ ngx_accept_log_error(ngx_log_t *log, u_c return ngx_snprintf(buf, len, " while accepting new connection on %V", log->data); } + + +#if (NGX_DEBUG) + +static void +ngx_debug_accepted_connection(ngx_event_conf_t *ecf, ngx_connection_t *c) +{ + struct sockaddr_in *sin; + ngx_cidr_t *cidr; + ngx_uint_t i; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; + ngx_uint_t n; +#endif + + cidr = ecf->debug_connection.elts; + for (i = 0; i < ecf->debug_connection.nelts; i++) { + if (cidr[i].family != (ngx_uint_t) c->sockaddr->sa_family) { + goto next; + } + + switch (cidr[i].family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) c->sockaddr; + for (n = 0; n < 16; n++) { + if ((sin6->sin6_addr.s6_addr[n] + & cidr[i].u.in6.mask.s6_addr[n]) + != cidr[i].u.in6.addr.s6_addr[n]) + { + goto next; + } + } + break; +#endif + +#if (NGX_HAVE_UNIX_DOMAIN) + case AF_UNIX: + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) c->sockaddr; + if ((sin->sin_addr.s_addr & cidr[i].u.in.mask) + != cidr[i].u.in.addr) + { + goto next; + } + break; + } + + c->log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL; + break; + + next: + continue; + } +} + +#endif diff -r d1c791479bbb -r 8f038068f4bc src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/event/ngx_event_connect.c Wed Jan 20 19:52:12 2016 +0300 @@ -14,7 +14,7 @@ ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc) { - int rc; + int rc, type; ngx_int_t event; ngx_err_t err; ngx_uint_t level; @@ -27,9 +27,12 @@ ngx_event_connect_peer(ngx_peer_connecti return rc; } - s = ngx_socket(pc->sockaddr->sa_family, SOCK_STREAM, 0); + type = (pc->type ? pc->type : SOCK_STREAM); - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, "socket %d", s); + s = ngx_socket(pc->sockaddr->sa_family, type, 0); + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, "%s socket %d", + (type == SOCK_STREAM) ? "stream" : "dgram", s); if (s == (ngx_socket_t) -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, @@ -49,6 +52,8 @@ ngx_event_connect_peer(ngx_peer_connecti return NGX_ERROR; } + c->type = type; + if (pc->rcvbuf) { if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const void *) &pc->rcvbuf, sizeof(int)) == -1) @@ -75,25 +80,31 @@ ngx_event_connect_peer(ngx_peer_connecti } } - c->recv = ngx_recv; - c->send = ngx_send; - c->recv_chain = ngx_recv_chain; - c->send_chain = ngx_send_chain; + if (type == SOCK_STREAM) { + c->recv = ngx_recv; + c->send = ngx_send; + c->recv_chain = ngx_recv_chain; + c->send_chain = ngx_send_chain; - c->sendfile = 1; + c->sendfile = 1; + + if (pc->sockaddr->sa_family == AF_UNIX) { + c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; + c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; + +#if (NGX_SOLARIS) + /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */ + c->sendfile = 0; +#endif + } + + } else { /* type == SOCK_DGRAM */ + c->recv = ngx_udp_recv; + c->send = ngx_send; + } c->log_error = pc->log_error; - if (pc->sockaddr->sa_family == AF_UNIX) { - c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; - c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; - -#if (NGX_SOLARIS) - /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */ - c->sendfile = 0; -#endif - } - rev = c->read; wev = c->write; diff -r d1c791479bbb -r 8f038068f4bc src/event/ngx_event_connect.h --- a/src/event/ngx_event_connect.h Tue Mar 15 15:55:23 2016 +0300 +++ b/src/event/ngx_event_connect.h Wed Jan 20 19:52:12 2016 +0300 @@ -55,6 +55,7 @@ struct ngx_peer_connection_s { ngx_addr_t *local; + int type; int rcvbuf; ngx_log_t *log; diff -r d1c791479bbb -r 8f038068f4bc src/os/unix/ngx_darwin_init.c --- a/src/os/unix/ngx_darwin_init.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/os/unix/ngx_darwin_init.c Wed Jan 20 19:52:12 2016 +0300 @@ -23,6 +23,7 @@ static ngx_os_io_t ngx_darwin_io = { ngx_readv_chain, ngx_udp_unix_recv, ngx_unix_send, + ngx_udp_unix_send, #if (NGX_HAVE_SENDFILE) ngx_darwin_sendfile_chain, NGX_IO_SENDFILE diff -r d1c791479bbb -r 8f038068f4bc src/os/unix/ngx_freebsd_init.c --- a/src/os/unix/ngx_freebsd_init.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/os/unix/ngx_freebsd_init.c Wed Jan 20 19:52:12 2016 +0300 @@ -32,6 +32,7 @@ static ngx_os_io_t ngx_freebsd_io = { ngx_readv_chain, ngx_udp_unix_recv, ngx_unix_send, + ngx_udp_unix_send, #if (NGX_HAVE_SENDFILE) ngx_freebsd_sendfile_chain, NGX_IO_SENDFILE diff -r d1c791479bbb -r 8f038068f4bc src/os/unix/ngx_linux_init.c --- a/src/os/unix/ngx_linux_init.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/os/unix/ngx_linux_init.c Wed Jan 20 19:52:12 2016 +0300 @@ -18,6 +18,7 @@ static ngx_os_io_t ngx_linux_io = { ngx_readv_chain, ngx_udp_unix_recv, ngx_unix_send, + ngx_udp_unix_send, #if (NGX_HAVE_SENDFILE) ngx_linux_sendfile_chain, NGX_IO_SENDFILE diff -r d1c791479bbb -r 8f038068f4bc src/os/unix/ngx_os.h --- a/src/os/unix/ngx_os.h Tue Mar 15 15:55:23 2016 +0300 +++ b/src/os/unix/ngx_os.h Wed Jan 20 19:52:12 2016 +0300 @@ -28,6 +28,7 @@ typedef struct { ngx_recv_chain_pt recv_chain; ngx_recv_pt udp_recv; ngx_send_pt send; + ngx_send_pt udp_send; ngx_send_chain_pt send_chain; ngx_uint_t flags; } ngx_os_io_t; @@ -47,6 +48,7 @@ ssize_t ngx_udp_unix_recv(ngx_connection ssize_t ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size); ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); +ssize_t ngx_udp_unix_send(ngx_connection_t *c, u_char *buf, size_t size); #if (IOV_MAX > 64) diff -r d1c791479bbb -r 8f038068f4bc src/os/unix/ngx_posix_init.c --- a/src/os/unix/ngx_posix_init.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/os/unix/ngx_posix_init.c Wed Jan 20 19:52:12 2016 +0300 @@ -24,6 +24,7 @@ ngx_os_io_t ngx_os_io = { ngx_readv_chain, ngx_udp_unix_recv, ngx_unix_send, + ngx_udp_unix_send, ngx_writev_chain, 0 }; diff -r d1c791479bbb -r 8f038068f4bc src/os/unix/ngx_solaris_init.c --- a/src/os/unix/ngx_solaris_init.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/os/unix/ngx_solaris_init.c Wed Jan 20 19:52:12 2016 +0300 @@ -19,6 +19,7 @@ static ngx_os_io_t ngx_solaris_io = { ngx_readv_chain, ngx_udp_unix_recv, ngx_unix_send, + ngx_udp_unix_send, #if (NGX_HAVE_SENDFILE) ngx_solaris_sendfilev_chain, NGX_IO_SENDFILE diff -r d1c791479bbb -r 8f038068f4bc src/os/unix/ngx_udp_send.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os/unix/ngx_udp_send.c Wed Jan 20 19:52:12 2016 +0300 @@ -0,0 +1,56 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Nginx, Inc. + */ + + +#include +#include +#include + + +ssize_t +ngx_udp_unix_send(ngx_connection_t *c, u_char *buf, size_t size) +{ + ssize_t n; + ngx_err_t err; + ngx_event_t *wev; + + wev = c->write; + + for ( ;; ) { + n = sendto(c->fd, buf, size, 0, c->sockaddr, c->socklen); + + ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, + "sendto: fd:%d %z of %uz to \"%V\"", + c->fd, n, size, &c->addr_text); + + if (n >= 0) { + if ((size_t) n != size) { + wev->error = 1; + (void) ngx_connection_error(c, 0, "sendto() incomplete"); + return NGX_ERROR; + } + + c->sent += n; + + return n; + } + + err = ngx_socket_errno; + + if (err == NGX_EAGAIN) { + wev->ready = 0; + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, NGX_EAGAIN, + "sendto() not ready"); + return NGX_AGAIN; + } + + if (err != NGX_EINTR) { + wev->error = 1; + (void) ngx_connection_error(c, err, "sendto() failed"); + return NGX_ERROR; + } + } +} diff -r d1c791479bbb -r 8f038068f4bc src/stream/ngx_stream.c --- a/src/stream/ngx_stream.c Tue Mar 15 15:55:23 2016 +0300 +++ b/src/stream/ngx_stream.c Wed Jan 20 19:52:12 2016 +0300 From dirk.feytons at gmail.com Tue Mar 15 13:33:09 2016 From: dirk.feytons at gmail.com (Dirk Feytons) Date: Tue, 15 Mar 2016 14:33:09 +0100 Subject: Exporting all symbols Message-ID: Hi, With the introduction of the dynamic modules feature nginx is now always exporting its symbols. This is a bit unfortunate for our use case: we incorporate nginx in an embedded device and keep the binary size down by only enabling a couple (static) modules and removing unused symbols with -ffunction-sections -fdata-sections and -Wl,--gc-sections. This makes quite a difference but it now no longer works due to the hardcoded -Wl,-E I can easily patch the build system but I'm hoping for an official solution. Perhaps some build flag to disable support for dynamic modules? Thanks, Dirk F. -------------- next part -------------- An HTML attachment was scrubbed... URL: From joel.cunningham at me.com Tue Mar 15 13:44:29 2016 From: joel.cunningham at me.com (Joel Cunningham) Date: Tue, 15 Mar 2016 13:44:29 +0000 (GMT) Subject: [PATCH] Correct reference to GCC compiler macro Message-ID: <064f59fa-087a-4ed4-9625-e76d06a23eef@me.com> I'm fine with the code being removed as well since I'm also using an update-to-date version of GCC, but up to you guys :) Joel On Mar 14, 2016, at 08:46 AM, Maxim Dounin wrote: Hello! On Mon, Mar 14, 2016 at 02:28:01PM +0000, Joel Cunningham wrote: Anyone have comments on this small change?? Any interest in accepting it? It might be better idea to just remove the whole chunk. If the typo exists for years and nobody noticed, it's probably not needed at all - either because it works fine or because nobody uses so old GCC. I don't have GCC 2.7 on hand to test though. -- Maxim Dounin http://nginx.org/ _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Tue Mar 15 15:28:22 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 15 Mar 2016 15:28:22 +0000 Subject: [nginx] Truncation detection in sendfile() on Linux. Message-ID: details: http://hg.nginx.org/nginx/rev/4df3d9fcdee8 branches: changeset: 6437:4df3d9fcdee8 user: Maxim Dounin date: Tue Mar 15 18:26:17 2016 +0300 description: Truncation detection in sendfile() on Linux. This addresses connection hangs as observed in ticket #504, and CPU hogs with "aio threads; sendfile on" as reported in the mailing list, see http://mailman.nginx.org/pipermail/nginx-ru/2016-March/057638.html. The alert is identical to one used on FreeBSD. diffstat: src/os/unix/ngx_linux_sendfile_chain.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-) diffs (43 lines): diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -292,6 +292,19 @@ eintr: } } + if (n == 0) { + /* + * if sendfile returns zero, then someone has truncated the file, + * so the offset became beyond the end of the file + */ + + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "sendfile() reported that \"%s\" was truncated at %O", + file->file->name.data, file->file_pos); + + return NGX_ERROR; + } + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "sendfile: %z of %uz @%O", n, size, file->file_pos); @@ -354,6 +367,19 @@ ngx_linux_sendfile_thread(ngx_connection return NGX_ERROR; } + if (ctx->sent == 0) { + /* + * if sendfile returns zero, then someone has truncated the file, + * so the offset became beyond the end of the file + */ + + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "sendfile() reported that \"%s\" was truncated at %O", + file->file->name.data, file->file_pos); + + return NGX_ERROR; + } + *sent = ctx->sent; return (ctx->sent == ctx->size) ? NGX_DONE : NGX_AGAIN; From mdounin at mdounin.ru Tue Mar 15 15:28:31 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 15 Mar 2016 15:28:31 +0000 Subject: [nginx] Truncation detection in sendfilev() on Solaris. Message-ID: details: http://hg.nginx.org/nginx/rev/646985c55393 branches: changeset: 6438:646985c55393 user: Maxim Dounin date: Tue Mar 15 18:26:59 2016 +0300 description: Truncation detection in sendfilev() on Solaris. While sendfilev() is documented to return -1 with EINVAL set if the file was truncated, at least Solaris 11 silently returns 0, and this results in CPU hog. Added a test to complain appropriately if 0 is returned. diffstat: src/os/unix/ngx_solaris_sendfilev_chain.c | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-) diffs (54 lines): diff --git a/src/os/unix/ngx_solaris_sendfilev_chain.c b/src/os/unix/ngx_solaris_sendfilev_chain.c --- a/src/os/unix/ngx_solaris_sendfilev_chain.c +++ b/src/os/unix/ngx_solaris_sendfilev_chain.c @@ -48,6 +48,7 @@ ngx_solaris_sendfilev_chain(ngx_connecti ssize_t n; ngx_int_t eintr; ngx_err_t err; + ngx_buf_t *file; ngx_uint_t nsfv; sendfilevec_t *sfv, sfvs[NGX_SENDFILEVECS]; ngx_event_t *wev; @@ -77,6 +78,7 @@ ngx_solaris_sendfilev_chain(ngx_connecti fd = SFV_FD_SELF; prev = NULL; fprev = 0; + file = NULL; sfv = NULL; eintr = 0; sent = 0; @@ -153,6 +155,7 @@ ngx_solaris_sendfilev_chain(ngx_connecti sfv->sfv_len = (size_t) size; } + file = cl->buf; fprev = cl->buf->file_pos + size; send += size; } @@ -179,6 +182,26 @@ ngx_solaris_sendfilev_chain(ngx_connecti ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, "sendfilev() sent only %uz bytes", sent); + + } else if (n == 0 && sent == 0) { + + /* + * sendfilev() is documented to return -1 with errno + * set to EINVAL if svf_len is greater than the file size, + * but at least Solaris 11 returns 0 instead + */ + + if (file) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "sendfilev() reported that \"%s\" was truncated at %O", + file->file->name.data, file->file_pos); + + } else { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "sendfilev() returned 0 with memory buffers"); + } + + return NGX_CHAIN_ERROR; } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, From ru at nginx.com Wed Mar 16 09:26:35 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 16 Mar 2016 12:26:35 +0300 Subject: Exporting all symbols In-Reply-To: References: Message-ID: <20160316092635.GD63181@lo0.su> On Tue, Mar 15, 2016 at 02:33:09PM +0100, Dirk Feytons wrote: > Hi, > > With the introduction of the dynamic modules feature nginx is now always > exporting its symbols. This is a bit unfortunate for our use case: we > incorporate nginx in an embedded device and keep the binary size down by > only enabling a couple (static) modules and removing unused symbols with > -ffunction-sections -fdata-sections and -Wl,--gc-sections. This makes quite > a difference but it now no longer works due to the hardcoded -Wl,-E > > I can easily patch the build system but I'm hoping for an official > solution. Perhaps some build flag to disable support for dynamic modules? Does this work for you? $ auto/configure --with-cc-opt=-fvisibility=hidden From dirk.feytons at gmail.com Wed Mar 16 12:35:15 2016 From: dirk.feytons at gmail.com (Dirk Feytons) Date: Wed, 16 Mar 2016 13:35:15 +0100 Subject: Exporting all symbols In-Reply-To: <20160316092635.GD63181@lo0.su> References: <20160316092635.GD63181@lo0.su> Message-ID: On 16 March 2016 at 10:26, Ruslan Ermilov wrote: > On Tue, Mar 15, 2016 at 02:33:09PM +0100, Dirk Feytons wrote: > > Hi, > > > > With the introduction of the dynamic modules feature nginx is now always > > exporting its symbols. This is a bit unfortunate for our use case: we > > incorporate nginx in an embedded device and keep the binary size down by > > only enabling a couple (static) modules and removing unused symbols with > > -ffunction-sections -fdata-sections and -Wl,--gc-sections. This makes > quite > > a difference but it now no longer works due to the hardcoded -Wl,-E > > > > I can easily patch the build system but I'm hoping for an official > > solution. Perhaps some build flag to disable support for dynamic modules? > > Does this work for you? > > $ auto/configure --with-cc-opt=-fvisibility=hidden > > Yes indeed, this works. Thanks for the tip! Dirk F. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ahutchings at nginx.com Wed Mar 16 17:13:56 2016 From: ahutchings at nginx.com (Andrew Hutchings) Date: Wed, 16 Mar 2016 17:13:56 +0000 Subject: [PATCH] Correct reference to GCC compiler macro In-Reply-To: <20160314144556.GR12808@mdounin.ru> References: <1f886976-0274-4c90-b2c5-ee1763f7b50d@me.com> <20160314144556.GR12808@mdounin.ru> Message-ID: <56E99454.1020300@nginx.com> Hi! On 14/03/16 14:45, Maxim Dounin wrote: > Hello! > > On Mon, Mar 14, 2016 at 02:28:01PM +0000, Joel Cunningham wrote: > >> Anyone have comments on this small change? Any interest in accepting it? > > It might be better idea to just remove the whole chunk. If the > typo exists for years and nobody noticed, it's probably not needed > at all - either because it works fine or because nobody uses so > old GCC. I don't have GCC 2.7 on hand to test though. Given that no LTS release of any major Linux or BSD uses GCC that old I would be inclined to agree with removing. Especially since 2.7 died around 18 years ago :) Kind Regards -- Andrew Hutchings (LinuxJedi) Technical Product Manager, NGINX Inc. From ru at nginx.com Wed Mar 16 17:27:11 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 16 Mar 2016 17:27:11 +0000 Subject: [nginx] Style. Message-ID: details: http://hg.nginx.org/nginx/rev/81329f6a4254 branches: changeset: 6439:81329f6a4254 user: Ruslan Ermilov date: Wed Mar 16 14:44:41 2016 +0300 description: Style. diffstat: src/http/ngx_http_upstream.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (18 lines): diff -r 646985c55393 -r 81329f6a4254 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Tue Mar 15 18:26:59 2016 +0300 +++ b/src/http/ngx_http_upstream.c Wed Mar 16 14:44:41 2016 +0300 @@ -416,10 +416,10 @@ static ngx_http_upstream_next_t ngx_htt ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = { - { ngx_string("GET"), NGX_HTTP_GET}, - { ngx_string("HEAD"), NGX_HTTP_HEAD }, - { ngx_string("POST"), NGX_HTTP_POST }, - { ngx_null_string, 0 } + { ngx_string("GET"), NGX_HTTP_GET }, + { ngx_string("HEAD"), NGX_HTTP_HEAD }, + { ngx_string("POST"), NGX_HTTP_POST }, + { ngx_null_string, 0 } }; From takahiro.kujirai at it.zeus-enterprise.co.jp Thu Mar 17 06:00:43 2016 From: takahiro.kujirai at it.zeus-enterprise.co.jp (ZEUS-mgtGM KUJIRAI, Takahiro) Date: Thu, 17 Mar 2016 15:00:43 +0900 (JST) Subject: No subject Message-ID: <62405.153.214.79.8.1458194443.squirrel@www.info.zeus-enterprise.co.jp> # HG changeset patch # User Takahiro Kujirai # Date 1458193783 -32400 # Thu Mar 17 14:49:43 2016 +0900 # Node ID c08b49903ee70fb2fa4d9e133eadbd9ab8e4a12d # Parent 81329f6a4254df3701b626d18cf8b9245e6d8aa1 Translate to ja(LICENSE & README) diff -r 81329f6a4254 -r c08b49903ee7 docs/text/LICENSE.ja --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/text/LICENSE.ja Thu Mar 17 14:49:43 2016 +0900 @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2002-2016 Igor Sysoev + * Copyright (C) 2011-2016 Nginx, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * ????????????????????????????????????? ??? + * ?????????????? + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * ??????????????????????????????????? ????????????? + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * ??????????????????????????????????? ???? + * ??????????????????????????? + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ diff -r 81329f6a4254 -r c08b49903ee7 docs/text/README.ja --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/text/README.ja Thu Mar 17 14:49:43 2016 +0900 @@ -0,0 +1,4 @@ + +Documentation is available at http://nginx.org +????????http://nginx.org???????? + From takahiro.kujirai at it.zeus-enterprise.co.jp Thu Mar 17 06:01:45 2016 From: takahiro.kujirai at it.zeus-enterprise.co.jp (ZEUS-mgtGM KUJIRAI, Takahiro) Date: Thu, 17 Mar 2016 15:01:45 +0900 (JST) Subject: [PATCH]Translation to ja(LICENSE & README) Message-ID: <62418.153.214.79.8.1458194505.squirrel@www.info.zeus-enterprise.co.jp> # HG changeset patch # User Takahiro Kujirai # Date 1458193783 -32400 # Thu Mar 17 14:49:43 2016 +0900 # Node ID c08b49903ee70fb2fa4d9e133eadbd9ab8e4a12d # Parent 81329f6a4254df3701b626d18cf8b9245e6d8aa1 Translate to ja(LICENSE & README) diff -r 81329f6a4254 -r c08b49903ee7 docs/text/LICENSE.ja --- /dev/nullThu Jan 01 00:00:00 1970 +0000 +++ b/docs/text/LICENSE.jaThu Mar 17 14:49:43 2016 +0900 @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2002-2016 Igor Sysoev + * Copyright (C) 2011-2016 Nginx, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * ????????????????????????????????????? ??? + * ?????????????? + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * ??????????????????????????????????? ????????????? + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * ??????????????????????????????????? ???? + * ??????????????????????????? + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ diff -r 81329f6a4254 -r c08b49903ee7 docs/text/README.ja --- /dev/nullThu Jan 01 00:00:00 1970 +0000 +++ b/docs/text/README.jaThu Mar 17 14:49:43 2016 +0900 @@ -0,0 +1,4 @@ + +Documentation is available at http://nginx.org +????????http://nginx.org???????? + From mdounin at mdounin.ru Thu Mar 17 13:35:59 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 17 Mar 2016 16:35:59 +0300 Subject: [PATCH]Translation to ja(LICENSE & README) In-Reply-To: <62418.153.214.79.8.1458194505.squirrel@www.info.zeus-enterprise.co.jp> References: <62418.153.214.79.8.1458194505.squirrel@www.info.zeus-enterprise.co.jp> Message-ID: <20160317133558.GR12808@mdounin.ru> Hello! On Thu, Mar 17, 2016 at 03:01:45PM +0900, ZEUS-mgtGM KUJIRAI, Takahiro wrote: > # HG changeset patch > # User Takahiro Kujirai > # Date 1458193783 -32400 > # Thu Mar 17 14:49:43 2016 +0900 > # Node ID c08b49903ee70fb2fa4d9e133eadbd9ab8e4a12d > # Parent 81329f6a4254df3701b626d18cf8b9245e6d8aa1 > Translate to ja(LICENSE & README) Sorry, but we have no resources to maintain such translations to multiple languages. Additionally, license translations needs a lawyer - and this is not something we want to spend our time on. If you really need appropriate translation of the license, Wikipedia has translations to various languages: https://en.wikipedia.org/wiki/BSD_licenses#2-clause -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Fri Mar 18 03:43:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 18 Mar 2016 03:43:27 +0000 Subject: [nginx] Fixed timeouts with threaded sendfile() and subrequests. Message-ID: details: http://hg.nginx.org/nginx/rev/248aa2757332 branches: changeset: 6440:248aa2757332 user: Maxim Dounin date: Fri Mar 18 05:04:45 2016 +0300 description: Fixed timeouts with threaded sendfile() and subrequests. If a write event happens after sendfile() but before we've got the sendfile results in the main thread, this write event will be ignored. And if no more events will happen, the connection will hang. Removing the events works in the simple cases, but not always, as in some cases events are added back by an unrelated code. E.g., the upstream module adds write event in the ngx_http_upstream_init() to track client aborts. Fix is to use wev->complete instead. It is now set to 0 before a sendfile() task is posted, and it is set to 1 once a write event happens. If on completion of the sendfile() task wev->complete is 1, we know that an event happened while we were executing sendfile(), and the socket is still ready for writing even if sendfile() did not sent all the data or returned EAGAIN. diffstat: src/event/modules/ngx_epoll_module.c | 3 +++ src/os/unix/ngx_linux_sendfile_chain.c | 21 +++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diffs (65 lines): diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c --- a/src/event/modules/ngx_epoll_module.c +++ b/src/event/modules/ngx_epoll_module.c @@ -840,6 +840,9 @@ ngx_epoll_process_events(ngx_cycle_t *cy } wev->ready = 1; +#if (NGX_THREADS) + wev->complete = 1; +#endif if (flags & NGX_POST_EVENTS) { ngx_post_event(wev, &ngx_posted_events); diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -328,7 +328,6 @@ static ngx_int_t ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size, size_t *sent) { - ngx_uint_t flags; ngx_event_t *wev; ngx_thread_task_t *task; ngx_linux_sendfile_ctx_t *ctx; @@ -358,6 +357,11 @@ ngx_linux_sendfile_thread(ngx_connection if (ctx->err == NGX_EAGAIN) { *sent = 0; + + if (wev->complete) { + return NGX_DONE; + } + return NGX_AGAIN; } @@ -382,7 +386,11 @@ ngx_linux_sendfile_thread(ngx_connection *sent = ctx->sent; - return (ctx->sent == ctx->size) ? NGX_DONE : NGX_AGAIN; + if (ctx->sent == ctx->size || wev->complete) { + return NGX_DONE; + } + + return NGX_AGAIN; } if (task->event.active && ctx->file == file) { @@ -400,14 +408,7 @@ ngx_linux_sendfile_thread(ngx_connection ctx->socket = c->fd; ctx->size = size; - if (wev->active) { - flags = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ? NGX_CLEAR_EVENT - : NGX_LEVEL_EVENT; - - if (ngx_del_event(wev, NGX_WRITE_EVENT, flags) == NGX_ERROR) { - return NGX_ERROR; - } - } + wev->complete = 0; if (file->file->thread_handler(task, file->file) != NGX_OK) { return NGX_ERROR; From mdounin at mdounin.ru Fri Mar 18 03:49:24 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 18 Mar 2016 03:49:24 +0000 Subject: [nginx] Threads: task pointer stored in ngx_file_t. Message-ID: details: http://hg.nginx.org/nginx/rev/9fd738b85fad branches: changeset: 6441:9fd738b85fad user: Maxim Dounin date: Fri Mar 18 06:43:52 2016 +0300 description: Threads: task pointer stored in ngx_file_t. This simplifies the interface of the ngx_thread_read() function. Additionally, most of the thread operations now explicitly set file->thread_task, file->thread_handler and file->thread_ctx, to facilitate use of thread operations in other places. (Potential problems remain with sendfile in threads though - it uses file->thread_handler as set in ngx_output_chain(), and it should not be overwritten to an incompatible one.) In collaboration with Valentin Bartenev. diffstat: src/core/ngx_file.h | 1 + src/core/ngx_output_chain.c | 11 ++++++++--- src/http/ngx_http_file_cache.c | 7 ++++--- src/os/unix/ngx_files.c | 8 ++++---- src/os/unix/ngx_files.h | 4 ++-- 5 files changed, 19 insertions(+), 12 deletions(-) diffs (99 lines): diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -27,6 +27,7 @@ struct ngx_file_s { ngx_int_t (*thread_handler)(ngx_thread_task_t *task, ngx_file_t *file); void *thread_ctx; + ngx_thread_task_t *thread_task; #endif #if (NGX_HAVE_FILE_AIO) diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c --- a/src/core/ngx_output_chain.c +++ b/src/core/ngx_output_chain.c @@ -577,10 +577,15 @@ ngx_output_chain_copy_buf(ngx_output_cha } else #endif #if (NGX_THREADS) - if (src->file->thread_handler) { - n = ngx_thread_read(&ctx->thread_task, src->file, dst->pos, - (size_t) size, src->file_pos, ctx->pool); + if (ctx->thread_handler) { + src->file->thread_task = ctx->thread_task; + src->file->thread_handler = ctx->thread_handler; + src->file->thread_ctx = ctx->filter_ctx; + + n = ngx_thread_read(src->file, dst->pos, (size_t) size, + src->file_pos, ctx->pool); if (n == NGX_AGAIN) { + ctx->thread_task = src->file->thread_task; return NGX_AGAIN; } diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -691,12 +691,13 @@ ngx_http_file_cache_aio_read(ngx_http_re #if (NGX_THREADS) if (clcf->aio == NGX_HTTP_AIO_THREADS) { + c->file.thread_task = c->thread_task; c->file.thread_handler = ngx_http_cache_thread_handler; c->file.thread_ctx = r; - n = ngx_thread_read(&c->thread_task, &c->file, c->buf->pos, - c->body_start, 0, r->pool); - + n = ngx_thread_read(&c->file, c->buf->pos, c->body_start, 0, r->pool); + + c->thread_task = c->file.thread_task; c->reading = (n == NGX_AGAIN); return n; diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -88,8 +88,8 @@ typedef struct { ssize_t -ngx_thread_read(ngx_thread_task_t **taskp, ngx_file_t *file, u_char *buf, - size_t size, off_t offset, ngx_pool_t *pool) +ngx_thread_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset, + ngx_pool_t *pool) { ngx_thread_task_t *task; ngx_thread_read_ctx_t *ctx; @@ -98,7 +98,7 @@ ngx_thread_read(ngx_thread_task_t **task "thread read: %d, %p, %uz, %O", file->fd, buf, size, offset); - task = *taskp; + task = file->thread_task; if (task == NULL) { task = ngx_thread_task_alloc(pool, sizeof(ngx_thread_read_ctx_t)); @@ -108,7 +108,7 @@ ngx_thread_read(ngx_thread_task_t **task task->handler = ngx_thread_read_handler; - *taskp = task; + file->thread_task = task; } ctx = task->ctx; diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -385,8 +385,8 @@ extern ngx_uint_t ngx_file_aio; #endif #if (NGX_THREADS) -ssize_t ngx_thread_read(ngx_thread_task_t **taskp, ngx_file_t *file, - u_char *buf, size_t size, off_t offset, ngx_pool_t *pool); +ssize_t ngx_thread_read(ngx_file_t *file, u_char *buf, size_t size, + off_t offset, ngx_pool_t *pool); #endif From mdounin at mdounin.ru Fri Mar 18 03:49:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 18 Mar 2016 03:49:27 +0000 Subject: [nginx] Threads: offloading of temp files writing to thread pools. Message-ID: details: http://hg.nginx.org/nginx/rev/6e10518f95d8 branches: changeset: 6442:6e10518f95d8 user: Maxim Dounin date: Fri Mar 18 06:44:03 2016 +0300 description: Threads: offloading of temp files writing to thread pools. The ngx_thread_write_chain_to_file() function introduced, which uses ngx_file_t thread_handler, thread_ctx and thread_task fields. The task context structure (ngx_thread_file_ctx_t) is the same for both reading and writing, and can be safely shared as long as operations are serialized. The task->handler field is now always set (and not only when task is allocated), as the same task can be used with different handlers. The thread_write flag is introduced in the ngx_temp_file_t structure to explicitly enable use of ngx_thread_write_chain_to_file() in ngx_write_chain_to_temp_file() when supported by caller. In collaboration with Valentin Bartenev. diffstat: src/core/ngx_file.c | 9 ++ src/core/ngx_file.h | 1 + src/os/unix/ngx_files.c | 166 +++++++++++++++++++++++++++++++++++++++++++---- src/os/unix/ngx_files.h | 2 + 4 files changed, 164 insertions(+), 14 deletions(-) diffs (280 lines): diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -124,6 +124,15 @@ ngx_write_chain_to_temp_file(ngx_temp_fi } } +#if (NGX_THREADS && NGX_HAVE_PWRITEV) + + if (tf->thread_write) { + return ngx_thread_write_chain_to_file(&tf->file, chain, tf->offset, + tf->pool); + } + +#endif + return ngx_write_chain_to_file(&tf->file, chain, tf->offset, tf->pool); } diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -78,6 +78,7 @@ typedef struct { unsigned log_level:8; unsigned persistent:1; unsigned clean:1; + unsigned thread_write:1; } ngx_temp_file_t; diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -12,6 +12,7 @@ #if (NGX_THREADS) #include static void ngx_thread_read_handler(void *data, ngx_log_t *log); +static void ngx_thread_write_chain_to_file_handler(void *data, ngx_log_t *log); #endif static ngx_chain_t *ngx_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *cl); @@ -77,14 +78,17 @@ ngx_read_file(ngx_file_t *file, u_char * #if (NGX_THREADS) typedef struct { - ngx_fd_t fd; - u_char *buf; - size_t size; - off_t offset; + ngx_fd_t fd; + ngx_uint_t write; /* unsigned write:1; */ - size_t read; - ngx_err_t err; -} ngx_thread_read_ctx_t; + u_char *buf; + size_t size; + ngx_chain_t *chain; + off_t offset; + + size_t nbytes; + ngx_err_t err; +} ngx_thread_file_ctx_t; ssize_t @@ -92,7 +96,7 @@ ngx_thread_read(ngx_file_t *file, u_char ngx_pool_t *pool) { ngx_thread_task_t *task; - ngx_thread_read_ctx_t *ctx; + ngx_thread_file_ctx_t *ctx; ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, "thread read: %d, %p, %uz, %O", @@ -101,13 +105,11 @@ ngx_thread_read(ngx_file_t *file, u_char task = file->thread_task; if (task == NULL) { - task = ngx_thread_task_alloc(pool, sizeof(ngx_thread_read_ctx_t)); + task = ngx_thread_task_alloc(pool, sizeof(ngx_thread_file_ctx_t)); if (task == NULL) { return NGX_ERROR; } - task->handler = ngx_thread_read_handler; - file->thread_task = task; } @@ -116,15 +118,25 @@ ngx_thread_read(ngx_file_t *file, u_char if (task->event.complete) { task->event.complete = 0; + if (ctx->write) { + ngx_log_error(NGX_LOG_ALERT, file->log, 0, + "invalid thread call, read instead of write"); + return NGX_ERROR; + } + if (ctx->err) { ngx_log_error(NGX_LOG_CRIT, file->log, ctx->err, "pread() \"%s\" failed", file->name.data); return NGX_ERROR; } - return ctx->read; + return ctx->nbytes; } + task->handler = ngx_thread_read_handler; + + ctx->write = 0; + ctx->fd = file->fd; ctx->buf = buf; ctx->size = size; @@ -143,7 +155,7 @@ ngx_thread_read(ngx_file_t *file, u_char static void ngx_thread_read_handler(void *data, ngx_log_t *log) { - ngx_thread_read_ctx_t *ctx = data; + ngx_thread_file_ctx_t *ctx = data; ssize_t n; @@ -155,7 +167,7 @@ ngx_thread_read_handler(void *data, ngx_ ctx->err = ngx_errno; } else { - ctx->read = n; + ctx->nbytes = n; ctx->err = 0; } @@ -454,6 +466,132 @@ eintr: } +#if (NGX_THREADS) + +ssize_t +ngx_thread_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset, + ngx_pool_t *pool) +{ + ngx_thread_task_t *task; + ngx_thread_file_ctx_t *ctx; + + ngx_log_debug3(NGX_LOG_DEBUG_CORE, file->log, 0, + "thread write chain: %d, %p, %O", + file->fd, cl, offset); + + task = file->thread_task; + + if (task == NULL) { + task = ngx_thread_task_alloc(pool, + sizeof(ngx_thread_file_ctx_t)); + if (task == NULL) { + return NGX_ERROR; + } + + file->thread_task = task; + } + + ctx = task->ctx; + + if (task->event.complete) { + task->event.complete = 0; + + if (!ctx->write) { + ngx_log_error(NGX_LOG_ALERT, file->log, 0, + "invalid thread call, write instead of read"); + return NGX_ERROR; + } + + if (ctx->err || ctx->nbytes == 0) { + ngx_log_error(NGX_LOG_CRIT, file->log, ctx->err, + "pwritev() \"%s\" failed", file->name.data); + return NGX_ERROR; + } + + file->offset += ctx->nbytes; + return ctx->nbytes; + } + + task->handler = ngx_thread_write_chain_to_file_handler; + + ctx->write = 1; + + ctx->fd = file->fd; + ctx->chain = cl; + ctx->offset = offset; + + if (file->thread_handler(task, file) != NGX_OK) { + return NGX_ERROR; + } + + return NGX_AGAIN; +} + + +static void +ngx_thread_write_chain_to_file_handler(void *data, ngx_log_t *log) +{ + ngx_thread_file_ctx_t *ctx = data; + +#if (NGX_HAVE_PWRITEV) + + off_t offset; + ssize_t n; + ngx_err_t err; + ngx_chain_t *cl; + ngx_iovec_t vec; + struct iovec iovs[NGX_IOVS_PREALLOCATE]; + + vec.iovs = iovs; + vec.nalloc = NGX_IOVS_PREALLOCATE; + + cl = ctx->chain; + offset = ctx->offset; + + ctx->nbytes = 0; + ctx->err = 0; + + do { + /* create the iovec and coalesce the neighbouring bufs */ + cl = ngx_chain_to_iovec(&vec, cl); + +eintr: + + n = pwritev(ctx->fd, iovs, vec.count, offset); + + if (n == -1) { + err = ngx_errno; + + if (err == NGX_EINTR) { + ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, err, + "pwritev() was interrupted"); + goto eintr; + } + + ctx->err = err; + return; + } + + if ((size_t) n != vec.size) { + ctx->nbytes = 0; + return; + } + + ctx->nbytes += n; + offset += n; + } while (cl); + +#else + + ctx->err = NGX_ENOSYS; + return; + +#endif +} + +#endif /* NGX_THREADS */ + + ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s) { diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -387,6 +387,8 @@ extern ngx_uint_t ngx_file_aio; #if (NGX_THREADS) ssize_t ngx_thread_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset, ngx_pool_t *pool); +ssize_t ngx_thread_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, + off_t offset, ngx_pool_t *pool); #endif From mdounin at mdounin.ru Fri Mar 18 03:49:29 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 18 Mar 2016 03:49:29 +0000 Subject: [nginx] Threads: writing via threads pools in event pipe. Message-ID: details: http://hg.nginx.org/nginx/rev/fc72784b1f52 branches: changeset: 6443:fc72784b1f52 user: Maxim Dounin date: Fri Mar 18 06:44:49 2016 +0300 description: Threads: writing via threads pools in event pipe. The "aio_write" directive is introduced, which enables use of aio for writing. Currently it is meaningful only with "aio threads". Note that aio operations can be done by both event pipe and output chain, so proper mapping between r->aio and p->aio is provided when calling ngx_event_pipe() and in output filter. In collaboration with Valentin Bartenev. diffstat: src/event/ngx_event_pipe.c | 98 ++++++++++++++++++++++++++------ src/event/ngx_event_pipe.h | 10 +++ src/http/ngx_http_core_module.c | 9 +++ src/http/ngx_http_core_module.h | 1 + src/http/ngx_http_upstream.c | 117 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 214 insertions(+), 21 deletions(-) diffs (405 lines): diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c +++ b/src/event/ngx_event_pipe.c @@ -112,6 +112,14 @@ ngx_event_pipe_read_upstream(ngx_event_p return NGX_OK; } +#if (NGX_THREADS) + if (p->aio) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, + "pipe read upstream: aio"); + return NGX_AGAIN; + } +#endif + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe read upstream: %d", p->upstream->read->ready); @@ -258,19 +266,6 @@ ngx_event_pipe_read_upstream(ngx_event_p break; } - if (rc == NGX_AGAIN) { - if (ngx_event_flags & NGX_USE_LEVEL_EVENT - && p->upstream->read->active - && p->upstream->read->ready) - { - if (ngx_del_event(p->upstream->read, NGX_READ_EVENT, 0) - == NGX_ERROR) - { - return NGX_ABORT; - } - } - } - if (rc != NGX_OK) { return rc; } @@ -475,8 +470,10 @@ ngx_event_pipe_read_upstream(ngx_event_p ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe write chain"); - if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) { - return NGX_ABORT; + rc = ngx_event_pipe_write_chain_to_temp_file(p); + + if (rc != NGX_OK) { + return rc; } } @@ -499,6 +496,18 @@ ngx_event_pipe_write_to_downstream(ngx_e ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe write downstream: %d", downstream->write->ready); +#if (NGX_THREADS) + + if (p->writing) { + rc = ngx_event_pipe_write_chain_to_temp_file(p); + + if (rc == NGX_ABORT) { + return NGX_ABORT; + } + } + +#endif + flushed = 0; for ( ;; ) { @@ -532,6 +541,10 @@ ngx_event_pipe_write_to_downstream(ngx_e p->out = NULL; } + if (p->writing) { + break; + } + if (p->in) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe write downstream flush in"); @@ -608,7 +621,7 @@ ngx_event_pipe_write_to_downstream(ngx_e p->out = p->out->next; - } else if (!p->cacheable && p->in) { + } else if (!p->cacheable && !p->writing && p->in) { cl = p->in; ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, @@ -710,12 +723,38 @@ ngx_event_pipe_write_chain_to_temp_file( ssize_t size, bsize, n; ngx_buf_t *b; ngx_uint_t prev_last_shadow; - ngx_chain_t *cl, *tl, *next, *out, **ll, **last_out, **last_free, fl; + ngx_chain_t *cl, *tl, *next, *out, **ll, **last_out, **last_free; + +#if (NGX_THREADS) + + if (p->writing) { + + if (p->aio) { + return NGX_AGAIN; + } + + out = p->writing; + p->writing = NULL; + + n = ngx_write_chain_to_temp_file(p->temp_file, NULL); + + if (n == NGX_ERROR) { + return NGX_ABORT; + } + + goto done; + } + +#endif if (p->buf_to_file) { - fl.buf = p->buf_to_file; - fl.next = p->in; - out = &fl; + out = ngx_alloc_chain_link(p->pool); + if (out == NULL) { + return NGX_ABORT; + } + + out->buf = p->buf_to_file; + out->next = p->in; } else { out = p->in; @@ -775,12 +814,31 @@ ngx_event_pipe_write_chain_to_temp_file( p->last_in = &p->in; } +#if (NGX_THREADS) + p->temp_file->thread_write = p->thread_handler ? 1 : 0; + p->temp_file->file.thread_task = p->thread_task; + p->temp_file->file.thread_handler = p->thread_handler; + p->temp_file->file.thread_ctx = p->thread_ctx; +#endif + n = ngx_write_chain_to_temp_file(p->temp_file, out); if (n == NGX_ERROR) { return NGX_ABORT; } +#if (NGX_THREADS) + + if (n == NGX_AGAIN) { + p->writing = out; + p->thread_task = p->temp_file->file.thread_task; + return NGX_AGAIN; + } + +done: + +#endif + if (p->buf_to_file) { p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos; n -= p->buf_to_file->last - p->buf_to_file->pos; diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h --- a/src/event/ngx_event_pipe.h +++ b/src/event/ngx_event_pipe.h @@ -30,6 +30,8 @@ struct ngx_event_pipe_s { ngx_chain_t *in; ngx_chain_t **last_in; + ngx_chain_t *writing; + ngx_chain_t *out; ngx_chain_t *free; ngx_chain_t *busy; @@ -45,6 +47,13 @@ struct ngx_event_pipe_s { ngx_event_pipe_output_filter_pt output_filter; void *output_ctx; +#if (NGX_THREADS) + ngx_int_t (*thread_handler)(ngx_thread_task_t *task, + ngx_file_t *file); + void *thread_ctx; + ngx_thread_task_t *thread_task; +#endif + unsigned read:1; unsigned cacheable:1; unsigned single_buf:1; @@ -56,6 +65,7 @@ struct ngx_event_pipe_s { unsigned downstream_done:1; unsigned downstream_error:1; unsigned cyclic_temp_file:1; + unsigned aio:1; ngx_int_t allocated; ngx_bufs_t bufs; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -402,6 +402,13 @@ static ngx_command_t ngx_http_core_comm 0, NULL }, + { ngx_string("aio_write"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_core_loc_conf_t, aio_write), + NULL }, + { ngx_string("read_ahead"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, @@ -3608,6 +3615,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t clcf->sendfile = NGX_CONF_UNSET; clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE; clcf->aio = NGX_CONF_UNSET; + clcf->aio_write = NGX_CONF_UNSET; #if (NGX_THREADS) clcf->thread_pool = NGX_CONF_UNSET_PTR; clcf->thread_pool_value = NGX_CONF_UNSET_PTR; @@ -3829,6 +3837,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t prev->sendfile_max_chunk, 0); #if (NGX_HAVE_FILE_AIO || NGX_THREADS) ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF); + ngx_conf_merge_value(conf->aio_write, prev->aio_write, 0); #endif #if (NGX_THREADS) ngx_conf_merge_ptr_value(conf->thread_pool, prev->thread_pool, NULL); diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -404,6 +404,7 @@ struct ngx_http_core_loc_conf_s { ngx_flag_t internal; /* internal */ ngx_flag_t sendfile; /* sendfile */ ngx_flag_t aio; /* aio */ + ngx_flag_t aio_write; /* aio_write */ ngx_flag_t tcp_nopush; /* tcp_nopush */ ngx_flag_t tcp_nodelay; /* tcp_nodelay */ ngx_flag_t reset_timedout_connection; /* reset_timedout_connection */ diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -76,6 +76,13 @@ static void 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); +static void ngx_http_upstream_thread_event_handler(ngx_event_t *ev); +#endif +static ngx_int_t ngx_http_upstream_output_filter(void *data, + ngx_chain_t *chain); static void ngx_http_upstream_process_downstream(ngx_http_request_t *r); static void ngx_http_upstream_process_upstream(ngx_http_request_t *r, ngx_http_upstream_t *u); @@ -2870,7 +2877,7 @@ ngx_http_upstream_send_response(ngx_http p = u->pipe; - p->output_filter = (ngx_event_pipe_output_filter_pt) ngx_http_output_filter; + p->output_filter = ngx_http_upstream_output_filter; p->output_ctx = r; p->tag = u->output.tag; p->bufs = u->conf->bufs; @@ -2913,6 +2920,13 @@ ngx_http_upstream_send_response(ngx_http p->max_temp_file_size = u->conf->max_temp_file_size; p->temp_file_write_size = u->conf->temp_file_write_size; +#if (NGX_THREADS) + if (clcf->aio == NGX_HTTP_AIO_THREADS && clcf->aio_write) { + p->thread_handler = ngx_http_upstream_thread_handler; + p->thread_ctx = r; + } +#endif + p->preread_bufs = ngx_alloc_chain_link(r->pool); if (p->preread_bufs == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_ERROR); @@ -3487,6 +3501,97 @@ ngx_http_upstream_non_buffered_filter(vo } +#if (NGX_THREADS) + +static ngx_int_t +ngx_http_upstream_thread_handler(ngx_thread_task_t *task, ngx_file_t *file) +{ + ngx_str_t name; + ngx_event_pipe_t *p; + ngx_thread_pool_t *tp; + ngx_http_request_t *r; + ngx_http_core_loc_conf_t *clcf; + + r = file->thread_ctx; + p = r->upstream->pipe; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + tp = clcf->thread_pool; + + if (tp == NULL) { + if (ngx_http_complex_value(r, clcf->thread_pool_value, &name) + != NGX_OK) + { + return NGX_ERROR; + } + + tp = ngx_thread_pool_get((ngx_cycle_t *) ngx_cycle, &name); + + if (tp == NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "thread pool \"%V\" not found", &name); + return NGX_ERROR; + } + } + + task->event.data = r; + task->event.handler = ngx_http_upstream_thread_event_handler; + + if (ngx_thread_task_post(tp, task) != NGX_OK) { + return NGX_ERROR; + } + + r->main->blocked++; + r->aio = 1; + p->aio = 1; + + return NGX_OK; +} + + +static void +ngx_http_upstream_thread_event_handler(ngx_event_t *ev) +{ + ngx_connection_t *c; + ngx_http_request_t *r; + + r = ev->data; + c = r->connection; + + ngx_http_set_log_request(c->log, r); + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http upstream thread: \"%V?%V\"", &r->uri, &r->args); + + r->main->blocked--; + r->aio = 0; + + r->write_event_handler(r); + + ngx_http_run_posted_requests(c); +} + +#endif + + +static ngx_int_t +ngx_http_upstream_output_filter(void *data, ngx_chain_t *chain) +{ + ngx_int_t rc; + ngx_event_pipe_t *p; + ngx_http_request_t *r; + + r = data; + p = r->upstream->pipe; + + rc = ngx_http_output_filter(r, chain); + + p->aio = r->aio; + + return rc; +} + + static void ngx_http_upstream_process_downstream(ngx_http_request_t *r) { @@ -3505,6 +3610,10 @@ ngx_http_upstream_process_downstream(ngx c->log->action = "sending to client"; +#if (NGX_THREADS) + p->aio = r->aio; +#endif + if (wev->timedout) { if (wev->delayed) { @@ -3634,6 +3743,12 @@ ngx_http_upstream_process_request(ngx_ht p = u->pipe; +#if (NGX_THREADS) + if (p->writing) { + return; + } +#endif + if (u->peer.connection) { if (u->store) { From xeioex at nginx.com Fri Mar 18 11:28:27 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 18 Mar 2016 11:28:27 +0000 Subject: [nginx] Cache: report error if slab allocator fails during cache loading. Message-ID: details: http://hg.nginx.org/nginx/rev/043914d19be8 branches: changeset: 6444:043914d19be8 user: Dmitry Volyntsev date: Fri Mar 18 14:27:30 2016 +0300 description: Cache: report error if slab allocator fails during cache loading. diffstat: src/http/ngx_http_cache.h | 2 ++ src/http/ngx_http_file_cache.c | 6 ++++++ 2 files changed, 8 insertions(+), 0 deletions(-) diffs (28 lines): diff -r fc72784b1f52 -r 043914d19be8 src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h Fri Mar 18 06:44:49 2016 +0300 +++ b/src/http/ngx_http_cache.h Fri Mar 18 14:27:30 2016 +0300 @@ -153,6 +153,8 @@ struct ngx_http_file_cache_s { time_t inactive; + time_t fail_time; + ngx_uint_t files; ngx_uint_t loader_files; ngx_msec_t last; diff -r fc72784b1f52 -r 043914d19be8 src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c Fri Mar 18 06:44:49 2016 +0300 +++ b/src/http/ngx_http_file_cache.c Fri Mar 18 14:27:30 2016 +0300 @@ -2094,6 +2094,12 @@ ngx_http_file_cache_add(ngx_http_file_ca fcn = ngx_slab_calloc_locked(cache->shpool, sizeof(ngx_http_file_cache_node_t)); if (fcn == NULL) { + if (cache->fail_time != ngx_time()) { + cache->fail_time = ngx_time(); + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, + "could not allocate node%s", cache->shpool->log_ctx); + } + ngx_shmtx_unlock(&cache->shpool->mutex); return NGX_ERROR; } From xeioex at nginx.com Fri Mar 18 12:12:44 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 18 Mar 2016 12:12:44 +0000 Subject: [nginx] Cache: added watermark to reduce IO load when keys_zone is full. Message-ID: details: http://hg.nginx.org/nginx/rev/c9d680b00744 branches: changeset: 6445:c9d680b00744 user: Dmitry Volyntsev date: Fri Mar 18 15:08:21 2016 +0300 description: Cache: added watermark to reduce IO load when keys_zone is full. When a keys_zone is full then each next request to the cache is penalized. That is, the cache has to evict older files to get a slot from the keys_zone synchronously. The patch introduces new behavior in this scenario. Manager will try to maintain available free slots in the keys_zone by cleaning old files in the background. diffstat: src/http/ngx_http_cache.h | 2 ++ src/http/ngx_http_file_cache.c | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diffs (133 lines): diff -r 043914d19be8 -r c9d680b00744 src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h Fri Mar 18 14:27:30 2016 +0300 +++ b/src/http/ngx_http_cache.h Fri Mar 18 15:08:21 2016 +0300 @@ -138,6 +138,8 @@ typedef struct { ngx_atomic_t cold; ngx_atomic_t loading; off_t size; + ngx_uint_t count; + ngx_uint_t watermark; } ngx_http_file_cache_sh_t; diff -r 043914d19be8 -r c9d680b00744 src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c Fri Mar 18 14:27:30 2016 +0300 +++ b/src/http/ngx_http_file_cache.c Fri Mar 18 15:08:21 2016 +0300 @@ -62,6 +62,7 @@ static ngx_int_t ngx_http_file_cache_add ngx_http_cache_t *c); static ngx_int_t ngx_http_file_cache_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path); +static void ngx_http_file_cache_set_watermark(ngx_http_file_cache_t *cache); ngx_str_t ngx_http_cache_status[] = { @@ -147,6 +148,8 @@ ngx_http_file_cache_init(ngx_shm_zone_t cache->sh->cold = 1; cache->sh->loading = 0; cache->sh->size = 0; + cache->sh->count = 0; + cache->sh->watermark = (ngx_uint_t) -1; cache->bsize = ngx_fs_bsize(cache->path->name.data); @@ -861,6 +864,8 @@ ngx_http_file_cache_exists(ngx_http_file fcn = ngx_slab_calloc_locked(cache->shpool, sizeof(ngx_http_file_cache_node_t)); if (fcn == NULL) { + ngx_http_file_cache_set_watermark(cache); + ngx_shmtx_unlock(&cache->shpool->mutex); (void) ngx_http_file_cache_forced_expire(cache); @@ -877,6 +882,8 @@ ngx_http_file_cache_exists(ngx_http_file } } + cache->sh->count++; + ngx_memcpy((u_char *) &fcn->node.key, c->key, sizeof(ngx_rbtree_key_t)); ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)], @@ -1631,6 +1638,7 @@ ngx_http_file_cache_free(ngx_http_cache_ ngx_queue_remove(&fcn->queue); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); + cache->sh->count--; c->node = NULL; } @@ -1883,6 +1891,7 @@ ngx_http_file_cache_delete(ngx_http_file ngx_queue_remove(q); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); + cache->sh->count--; } } @@ -1892,8 +1901,9 @@ ngx_http_file_cache_manager(void *data) { ngx_http_file_cache_t *cache = data; - off_t size; - time_t next, wait; + off_t size; + time_t next, wait; + ngx_uint_t count, watermark; next = ngx_http_file_cache_expire(cache); @@ -1904,13 +1914,16 @@ ngx_http_file_cache_manager(void *data) ngx_shmtx_lock(&cache->shpool->mutex); size = cache->sh->size; + count = cache->sh->count; + watermark = cache->sh->watermark; ngx_shmtx_unlock(&cache->shpool->mutex); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "http file cache size: %O", size); - - if (size < cache->max_size) { + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "http file cache size: %O c:%ui w:%i", + size, count, (ngx_int_t) watermark); + + if (size < cache->max_size && count < watermark) { return next; } @@ -2094,12 +2107,16 @@ ngx_http_file_cache_add(ngx_http_file_ca fcn = ngx_slab_calloc_locked(cache->shpool, sizeof(ngx_http_file_cache_node_t)); if (fcn == NULL) { + ngx_http_file_cache_set_watermark(cache); + if (cache->fail_time != ngx_time()) { cache->fail_time = ngx_time(); ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "could not allocate node%s", cache->shpool->log_ctx); } + cache->sh->count++; + ngx_shmtx_unlock(&cache->shpool->mutex); return NGX_ERROR; } @@ -2146,6 +2163,16 @@ ngx_http_file_cache_delete_file(ngx_tree } +static void +ngx_http_file_cache_set_watermark(ngx_http_file_cache_t *cache) +{ + cache->sh->watermark = cache->sh->count - cache->sh->count / 8; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "http file cache watermark: %ui", cache->sh->watermark); +} + + time_t ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status) { From piotrsikora at google.com Fri Mar 18 23:43:23 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Fri, 18 Mar 2016 16:43:23 -0700 Subject: [PATCH] Fix build with -Wmissing-prototypes Message-ID: <446abf3e009c5bdeee86.1458344603@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1458344288 25200 # Fri Mar 18 16:38:08 2016 -0700 # Node ID 446abf3e009c5bdeee865161ad5813c07163c0e8 # Parent c9d680b00744ea515369113585e5d5bfc4ce51de Fix build with -Wmissing-prototypes. Broken in 5eb4d7541107 (1.9.6), fix somehow missed in 3600bbfb43e3. Signed-off-by: Piotr Sikora diff -r c9d680b00744 -r 446abf3e009c src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -10,7 +10,7 @@ #include -static void ngx_show_version_info(); +static void ngx_show_version_info(void); static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle); static ngx_int_t ngx_get_options(int argc, char *const *argv); static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); From ru at nginx.com Sat Mar 19 04:29:04 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Sat, 19 Mar 2016 04:29:04 +0000 Subject: [nginx] Fix build with -Wmissing-prototypes. Message-ID: details: http://hg.nginx.org/nginx/rev/0ff7eff48c7e branches: changeset: 6446:0ff7eff48c7e user: Piotr Sikora date: Fri Mar 18 16:38:08 2016 -0700 description: Fix build with -Wmissing-prototypes. Broken in 5eb4d7541107 (1.9.6), fix somehow missed in 3600bbfb43e3. Signed-off-by: Piotr Sikora diffstat: src/core/nginx.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r c9d680b00744 -r 0ff7eff48c7e src/core/nginx.c --- a/src/core/nginx.c Fri Mar 18 15:08:21 2016 +0300 +++ b/src/core/nginx.c Fri Mar 18 16:38:08 2016 -0700 @@ -10,7 +10,7 @@ #include -static void ngx_show_version_info(); +static void ngx_show_version_info(void); static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle); static ngx_int_t ngx_get_options(int argc, char *const *argv); static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); @@ -372,7 +372,7 @@ main(int argc, char *const *argv) static void -ngx_show_version_info() +ngx_show_version_info(void) { ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED); From ru at nginx.com Sat Mar 19 04:32:14 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Sat, 19 Mar 2016 07:32:14 +0300 Subject: [PATCH] Fix build with -Wmissing-prototypes In-Reply-To: <446abf3e009c5bdeee86.1458344603@piotrsikora.sfo.corp.google.com> References: <446abf3e009c5bdeee86.1458344603@piotrsikora.sfo.corp.google.com> Message-ID: <20160319043214.GC37101@lo0.su> On Fri, Mar 18, 2016 at 04:43:23PM -0700, Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1458344288 25200 > # Fri Mar 18 16:38:08 2016 -0700 > # Node ID 446abf3e009c5bdeee865161ad5813c07163c0e8 > # Parent c9d680b00744ea515369113585e5d5bfc4ce51de > Fix build with -Wmissing-prototypes. > > Broken in 5eb4d7541107 (1.9.6), fix somehow missed in 3600bbfb43e3. > > Signed-off-by: Piotr Sikora > > diff -r c9d680b00744 -r 446abf3e009c src/core/nginx.c > --- a/src/core/nginx.c > +++ b/src/core/nginx.c > @@ -10,7 +10,7 @@ > #include > > > -static void ngx_show_version_info(); > +static void ngx_show_version_info(void); > static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle); > static ngx_int_t ngx_get_options(int argc, char *const *argv); > static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); Thanks, committed with minor change: http://hg.nginx.org/nginx/rev/0ff7eff48c7e For some reason, clang(1) only warns about it if you remove "static". From pluknet at nginx.com Mon Mar 21 09:37:48 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Mon, 21 Mar 2016 09:37:48 +0000 Subject: [nginx] Events: fixed test building with devpoll and eventport on Linux. Message-ID: details: http://hg.nginx.org/nginx/rev/d17f0584006f branches: changeset: 6447:d17f0584006f user: Sergey Kandaurov date: Mon Mar 21 12:36:36 2016 +0300 description: Events: fixed test building with devpoll and eventport on Linux. Avoid POLLREMOVE and itimerspec redefinition. diffstat: src/event/modules/ngx_devpoll_module.c | 2 ++ src/event/modules/ngx_eventport_module.c | 2 +- 2 files changed, 3 insertions(+), 1 deletions(-) diffs (25 lines): diff -r 0ff7eff48c7e -r d17f0584006f src/event/modules/ngx_devpoll_module.c --- a/src/event/modules/ngx_devpoll_module.c Fri Mar 18 16:38:08 2016 -0700 +++ b/src/event/modules/ngx_devpoll_module.c Mon Mar 21 12:36:36 2016 +0300 @@ -14,7 +14,9 @@ /* Solaris declarations */ +#ifndef POLLREMOVE #define POLLREMOVE 0x0800 +#endif #define DP_POLL 0xD001 #define DP_ISPOLLED 0xD002 diff -r 0ff7eff48c7e -r d17f0584006f src/event/modules/ngx_eventport_module.c --- a/src/event/modules/ngx_eventport_module.c Fri Mar 18 16:38:08 2016 -0700 +++ b/src/event/modules/ngx_eventport_module.c Mon Mar 21 12:36:36 2016 +0300 @@ -49,7 +49,7 @@ typedef struct port_notify { void *portnfy_user; /* user defined */ } port_notify_t; -#if (__FreeBSD_version < 700005) +#if (__FreeBSD__) && (__FreeBSD_version < 700005) typedef struct itimerspec { /* definition per POSIX.4 */ struct timespec it_interval;/* timer period */ From vbart at nginx.com Mon Mar 21 14:05:02 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 21 Mar 2016 14:05:02 +0000 Subject: [nginx] HTTP/2: improved debugging of sending control frames. Message-ID: details: http://hg.nginx.org/nginx/rev/4d1d3c2530e0 branches: changeset: 6448:4d1d3c2530e0 user: Valentin Bartenev date: Mon Mar 21 17:04:21 2016 +0300 description: HTTP/2: improved debugging of sending control frames. diffstat: src/http/v2/ngx_http_v2.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-) diffs (46 lines): diff -r d17f0584006f -r 4d1d3c2530e0 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Mon Mar 21 12:36:36 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Mon Mar 21 17:04:21 2016 +0300 @@ -2503,8 +2503,8 @@ ngx_http_v2_send_settings(ngx_http_v2_co ngx_http_v2_srv_conf_t *h2scf; ngx_http_v2_out_frame_t *frame; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "http2 send SETTINGS frame"); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2 send SETTINGS frame ack:%ui", ack); frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t)); if (frame == NULL) { @@ -2595,6 +2595,10 @@ ngx_http_v2_send_window_update(ngx_http_ ngx_buf_t *buf; ngx_http_v2_out_frame_t *frame; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2 send WINDOW_UPDATE frame sid:%ui, window:%uz", + sid, window); + frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_WINDOW_UPDATE_SIZE, NGX_HTTP_V2_WINDOW_UPDATE_FRAME, NGX_HTTP_V2_NO_FLAG, sid); @@ -2619,6 +2623,10 @@ ngx_http_v2_send_rst_stream(ngx_http_v2_ ngx_buf_t *buf; ngx_http_v2_out_frame_t *frame; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2 send RST_STREAM frame sid:%ui, status:%uz", + sid, status); + frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_RST_STREAM_SIZE, NGX_HTTP_V2_RST_STREAM_FRAME, NGX_HTTP_V2_NO_FLAG, sid); @@ -2642,6 +2650,9 @@ ngx_http_v2_send_goaway(ngx_http_v2_conn ngx_buf_t *buf; ngx_http_v2_out_frame_t *frame; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2 send GOAWAY frame, status:%uz", status); + frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_GOAWAY_SIZE, NGX_HTTP_V2_GOAWAY_FRAME, NGX_HTTP_V2_NO_FLAG, 0); From takahiro.kujirai at it.zeus-enterprise.co.jp Tue Mar 22 03:38:22 2016 From: takahiro.kujirai at it.zeus-enterprise.co.jp (ZEUS-mgtGM KUJIRAI, Takahiro) Date: Tue, 22 Mar 2016 12:38:22 +0900 (JST) Subject: [PATCH]Translation to ja(LICENSE & README) Message-ID: <55542.153.214.79.8.1458617902.squirrel@www.info.zeus-enterprise.co.jp> Hi, Dounin Thank you for your response. I think needing translations to various languages. Because it is easy to understand licenses. By the way, is README too? And I think CHANGES needs to translate to various languages, not only Russian. What do you think? Best Regards, Takahiro Kujirai Hello! On Thu, Mar 17, 2016 at 03:01:45PM +0900, ZEUS-mgtGM KUJIRAI, Takahiro wrote: > # HG changeset patch > # User Takahiro Kujirai > # Date 1458193783 -32400 > # Thu Mar 17 14:49:43 2016 +0900 > # Node ID c08b49903ee70fb2fa4d9e133eadbd9ab8e4a12d > # Parent 81329f6a4254df3701b626d18cf8b9245e6d8aa1 > Translate to ja(LICENSE & README) Sorry, but we have no resources to maintain such translations to multiple languages. Additionally, license translations needs a lawyer - and this is not something we want to spend our time on. If you really need appropriate translation of the license, Wikipedia has translations to various languages: https://en.wikipedia.org/wiki/BSD_licenses#2-clause -- Maxim Dounin http://nginx.org/ From ru at nginx.com Tue Mar 22 13:32:11 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 22 Mar 2016 13:32:11 +0000 Subject: [nginx] Reconsidered server_tokens with an empty value. Message-ID: details: http://hg.nginx.org/nginx/rev/e5076b96fd01 branches: changeset: 6449:e5076b96fd01 user: Ruslan Ermilov date: Tue Mar 22 15:52:28 2016 +0300 description: Reconsidered server_tokens with an empty value. An empty value will be treated as "off". diffstat: src/http/ngx_http_header_filter_module.c | 8 ++++---- src/http/ngx_http_special_response.c | 15 +++------------ src/http/v2/ngx_http_v2_filter_module.c | 8 ++++---- 3 files changed, 11 insertions(+), 20 deletions(-) diffs (94 lines): diff -r 4d1d3c2530e0 -r e5076b96fd01 src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c Mon Mar 21 17:04:21 2016 +0300 +++ b/src/http/ngx_http_header_filter_module.c Tue Mar 22 15:52:28 2016 +0300 @@ -295,12 +295,12 @@ ngx_http_header_filter(ngx_http_request_ return NGX_ERROR; } - if (tokens.len == 3 - && ngx_strncmp(tokens.data, "off", 3) == 0) + if (tokens.len == 0 + || (tokens.len == 3 && ngx_strncmp(tokens.data, "off", 3) == 0)) { ngx_str_set(&tokens, ngx_http_server_string); - } else if (tokens.len) { + } else { ngx_str_set(&tokens, ngx_http_server_full_string); } } @@ -481,7 +481,7 @@ ngx_http_header_filter(ngx_http_request_ } *b->last++ = CR; *b->last++ = LF; - if (r->headers_out.server == NULL && tokens.len) { + if (r->headers_out.server == NULL) { b->last = ngx_cpymem(b->last, tokens.data, tokens.len); } diff -r 4d1d3c2530e0 -r e5076b96fd01 src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c Mon Mar 21 17:04:21 2016 +0300 +++ b/src/http/ngx_http_special_response.c Tue Mar 22 15:52:28 2016 +0300 @@ -32,12 +32,6 @@ static u_char ngx_http_error_tail[] = ; -static u_char ngx_http_error_no_tail[] = -"" CRLF -"" CRLF -; - - static u_char ngx_http_msie_padding[] = "" CRLF "" CRLF @@ -638,16 +632,13 @@ ngx_http_send_special_response(ngx_http_ return NGX_ERROR; } - if (tokens.len == 3 - && ngx_strncmp(tokens.data, "off", 3) == 0) + if (tokens.len == 0 + || (tokens.len == 3 && ngx_strncmp(tokens.data, "off", 3) == 0)) { ngx_str_set(&tail, ngx_http_error_tail); - } else if (tokens.len) { + } else { ngx_str_set(&tail, ngx_http_error_full_tail); - - } else { - ngx_str_set(&tail, ngx_http_error_no_tail); } } diff -r 4d1d3c2530e0 -r e5076b96fd01 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Mon Mar 21 17:04:21 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Tue Mar 22 15:52:28 2016 +0300 @@ -252,14 +252,14 @@ ngx_http_v2_header_filter(ngx_http_reque return NGX_ERROR; } - if (tokens.len == 3 - && ngx_strncmp(tokens.data, "off", 3) == 0) + if (tokens.len == 0 + || (tokens.len == 3 && ngx_strncmp(tokens.data, "off", 3) == 0)) { server_tokens = 0; len += 1 + sizeof(nginx); ngx_str_set(&tokens, "nginx"); - } else if (tokens.len) { + } else { server_tokens = 1; len += 1 + nginx_ver_len; ngx_str_set(&tokens, NGINX_VER); @@ -468,7 +468,7 @@ ngx_http_v2_header_filter(ngx_http_reque pos = ngx_sprintf(pos, "%03ui", r->headers_out.status); } - if (r->headers_out.server == NULL && tokens.len) { + if (r->headers_out.server == NULL) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, "http2 output header: \"server: %V\"", &tokens); From mdounin at mdounin.ru Tue Mar 22 15:37:55 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 22 Mar 2016 18:37:55 +0300 Subject: [PATCH]Translation to ja(LICENSE & README) In-Reply-To: <55542.153.214.79.8.1458617902.squirrel@www.info.zeus-enterprise.co.jp> References: <55542.153.214.79.8.1458617902.squirrel@www.info.zeus-enterprise.co.jp> Message-ID: <20160322153755.GK37718@mdounin.ru> Hello! On Tue, Mar 22, 2016 at 12:38:22PM +0900, ZEUS-mgtGM KUJIRAI, Takahiro wrote: > I think needing translations to various languages. > Because it is easy to understand licenses. Licenses need to be normative. For something "easy to understand" there are various other resources to explain details of various licenses, including Wikipedia. > By the way, is README too? Yes. There is no need to translate it as it can be easily understood by any person even if he/she don't know English, and it will require resources much like any other translation. > And I think CHANGES needs to translate to various languages, not only Russian. > What do you think? I think it's not going to work. We maintain Russian version of CHANGES only because many of the developers are Russians (including me) and can more or less easily write them while releasing a new version. We've already tried to maintain translations of the nginx.org site to various languages. The problem is that translations are [almost] not refreshed after an initial translation is done and quickly become stale, resulting in negative net effect. -- Maxim Dounin http://nginx.org/ From takahiro.kujirai at it.zeus-enterprise.co.jp Wed Mar 23 03:54:24 2016 From: takahiro.kujirai at it.zeus-enterprise.co.jp (ZEUS-mgtGM KUJIRAI, Takahiro) Date: Wed, 23 Mar 2016 12:54:24 +0900 (JST) Subject: [PATCH]Translation to ja(LICENSE & README) Message-ID: <53235.153.214.79.8.1458705264.squirrel@www.info.zeus-enterprise.co.jp> Hi, Dounin Thank you for your response. I understood about LICENSE & README. >I think it's not going to work. We maintain Russian version of >CHANGES only because many of the developers are Russians >(including me) and can more or less easily write them while >releasing a new version. > >We've already tried to maintain translations of the nginx.org site >to various languages. The problem is that translations are >[almost] not refreshed after an initial translation is done and >quickly become stale, resulting in negative net effect. I saw nginx.org, I found English site & Russian site. ------- http://nginx.org/en/ http://nginx.org/ru/ What other language site is it? And if there is a Japanese site, I want to translate. Best Regards, Takahiro Kujirai From maxim at nginx.com Wed Mar 23 09:09:31 2016 From: maxim at nginx.com (Maxim Konovalov) Date: Wed, 23 Mar 2016 09:09:31 +0000 Subject: [njs] An option how to build njs module dynamically provided. Message-ID: details: http://hg.nginx.org/njs/rev/4deb6b538b48 branches: changeset: 84:4deb6b538b48 user: Maxim Konovalov date: Wed Mar 23 12:10:44 2016 +0300 description: An option how to build njs module dynamically provided. diffstat: README | 8 ++++++++ 1 ?????? ????????, 8 ???????(+), 0 ????????(-) ???????? (18 ?????): diff -r 480849ab9e96 -r 4deb6b538b48 README --- a/README Fri Mar 04 14:57:21 2016 +0300 +++ b/README Wed Mar 23 12:10:44 2016 +0300 @@ -3,6 +3,14 @@ Configure nginx with HTTP JavaScript mod ./configure --add-module=/nginx +Alternatively, you can build a dynamic version of the njs module + + ./configure --add-dynamic-module=/nginx + +and add the following line to nginx.conf and reload nginx: + + load_module modules/ngx_http_js_module.so; + Please report your experiences to the NGINX development mailing list nginx-devel at nginx.org (http://mailman.nginx.org/mailman/listinfo/nginx-devel). From jadjay at rachetjay.fr Wed Mar 23 11:22:29 2016 From: jadjay at rachetjay.fr (Jadjay) Date: Wed, 23 Mar 2016 12:22:29 +0100 Subject: Nginx Overflow ? status 18446744073709551615 Message-ID: <56F27C75.6030602@rachetjay.fr> Hi, We have a problem with a front nginx acting as rproxy for 6 windows IIS6 backends, Sometimes it seems it overflows : In logs the status value is 18446744073709551615 (aka the max 64-bit value) e.g : 88.XXX.XXX.138 - - [23/Mar/2016:12:14:16 +0100] "GET /soin-amincissant-...XXX...-la-fontaine.aspx HTTP/1.1" 18446744073709551615 0 "http://www.___XXX___.fr/soin-amincissant-...XXX...-la-fontaine.aspx" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36" "-" "range:-" 151.XXX.221 - - [23/Mar/2016:08:15:11 +0100] "HEAD /Catalogue_XXXX-Bleu.aspx HTTP/1.1" 18446744073709551615 0 "-" "Java/1.8.0_60" "-" It's seems that one on 5 times it breaks nginx, by overflowing memory. Did you have any clue on that ? -- Jadjay jadjay at rachetjay.fr -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Wed Mar 23 11:42:48 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Wed, 23 Mar 2016 14:42:48 +0300 Subject: Nginx Overflow ? status 18446744073709551615 In-Reply-To: <56F27C75.6030602@rachetjay.fr> References: <56F27C75.6030602@rachetjay.fr> Message-ID: <2414170.LnzGcTHhKy@vbart-workstation> On Wednesday 23 March 2016 12:22:29 Jadjay wrote: > Hi, > > We have a problem with a front nginx acting as rproxy for 6 windows IIS6 > backends, > > Sometimes it seems it overflows : > > In logs the status value is 18446744073709551615 (aka the max 64-bit value) > > e.g : > > 88.XXX.XXX.138 - - [23/Mar/2016:12:14:16 +0100] "GET > /soin-amincissant-...XXX...-la-fontaine.aspx HTTP/1.1" > 18446744073709551615 0 > "http://www.___XXX___.fr/soin-amincissant-...XXX...-la-fontaine.aspx" > "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, > like Gecko) Chrome/49.0.2623.87 Safari/537.36" "-" "range:-" > > 151.XXX.221 - - [23/Mar/2016:08:15:11 +0100] "HEAD > /Catalogue_XXXX-Bleu.aspx HTTP/1.1" 18446744073709551615 0 "-" > "Java/1.8.0_60" "-" > > > It's seems that one on 5 times it breaks nginx, by overflowing memory. > > Did you have any clue on that ? > > Do you use any 3-rd party modules or patches? wbr, Valentin V. Bartenev From xeioex at nginx.com Wed Mar 23 12:01:17 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 23 Mar 2016 12:01:17 +0000 Subject: [nginx] Cache: fixed slots accounting error introduced in c9d680b00744. Message-ID: details: http://hg.nginx.org/nginx/rev/22c32937a41f branches: changeset: 6450:22c32937a41f user: Dmitry Volyntsev date: Wed Mar 23 14:16:31 2016 +0300 description: Cache: fixed slots accounting error introduced in c9d680b00744. diffstat: src/http/ngx_http_file_cache.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (18 lines): diff -r e5076b96fd01 -r 22c32937a41f src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c Tue Mar 22 15:52:28 2016 +0300 +++ b/src/http/ngx_http_file_cache.c Wed Mar 23 14:16:31 2016 +0300 @@ -2115,12 +2115,12 @@ ngx_http_file_cache_add(ngx_http_file_ca "could not allocate node%s", cache->shpool->log_ctx); } - cache->sh->count++; - ngx_shmtx_unlock(&cache->shpool->mutex); return NGX_ERROR; } + cache->sh->count++; + ngx_memcpy((u_char *) &fcn->node.key, c->key, sizeof(ngx_rbtree_key_t)); ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)], From jadjay at rachetjay.fr Wed Mar 23 12:35:53 2016 From: jadjay at rachetjay.fr (Jadjay) Date: Wed, 23 Mar 2016 13:35:53 +0100 Subject: Nginx Overflow ? status 18446744073709551615 Message-ID: <56F28DA9.0@rachetjay.fr> On Wednesday 23 March 2016 12:22:29 Jadjay wrote: > Hi, > > We have a problem with a front nginx acting as rproxy for 6 windows IIS6 > backends, > > Sometimes it seems it overflows : > > In logs the status value is 18446744073709551615 (aka the max 64-bit value) > > e.g : > > 88.XXX.XXX.138 - - [23/Mar/2016:12:14:16 +0100] "GET > /soin-amincissant-...XXX...-la-fontaine.aspx HTTP/1.1" > 18446744073709551615 0 > "http://www.___XXX___.fr/soin-amincissant-...XXX...-la-fontaine.aspx" > "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, > like Gecko) Chrome/49.0.2623.87 Safari/537.36" "-" "range:-" > > 151.XXX.221 - - [23/Mar/2016:08:15:11 +0100] "HEAD > /Catalogue_XXXX-Bleu.aspx HTTP/1.1" 18446744073709551615 0 "-" > "Java/1.8.0_60" "-" > > > It's seems that one on 5 times it breaks nginx, by overflowing memory. > > Did you have any clue on that ? > >> Do you use any 3-rd party modules or patches? >> >> wbr, Valentin V. Bartenev Yes we have some 3-rd party modules : /usr/local/usr/sbin/nginx -V nginx version: nginx/1.6.0 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) TLS SNI support enabled configure arguments: --prefix=/usr/local/ --sbin-path=/usr/local/usr/sbin/nginx --conf-path=/usr/local/etc/nginx/nginx.conf --error-log-path=/usr/local/var/log/nginx/error.log --http-log-path=/usr/local/var/log/nginx/access.log --http-client-body-temp-path=/usr/local/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/usr/local/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/usr/local/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/usr/local/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/usr/local/var/lib/nginx/tmp/scgi --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-pcre --with-debug --add-module=/root/rpmbuild//BUILD/nginx-1.6.0/modsecurity-2.8.0/nginx/modsecurity --add-module=/root/rpmbuild//BUILD/nginx-1.6.0/ngx_cache_purge-2.1 --add-module=/root/rpmbuild//BUILD/nginx-1.6.0/ngx_http_substitutions_filter_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=-Wl,-E But only modsecurity is used, -- Jadjay jadjay at rachetjay.fr From mdounin at mdounin.ru Wed Mar 23 12:46:52 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 23 Mar 2016 15:46:52 +0300 Subject: [PATCH]Translation to ja(LICENSE & README) In-Reply-To: <53235.153.214.79.8.1458705264.squirrel@www.info.zeus-enterprise.co.jp> References: <53235.153.214.79.8.1458705264.squirrel@www.info.zeus-enterprise.co.jp> Message-ID: <20160323124652.GQ37718@mdounin.ru> Hello! On Wed, Mar 23, 2016 at 12:54:24PM +0900, ZEUS-mgtGM KUJIRAI, Takahiro wrote: > Hi, Dounin > > > Thank you for your response. > I understood about LICENSE & README. > > > >I think it's not going to work. We maintain Russian version of > >CHANGES only because many of the developers are Russians > >(including me) and can more or less easily write them while > >releasing a new version. > > > >We've already tried to maintain translations of the nginx.org site > >to various languages. The problem is that translations are > >[almost] not refreshed after an initial translation is done and > >quickly become stale, resulting in negative net effect. > > I saw nginx.org, I found English site & Russian site. > ------- > http://nginx.org/en/ > http://nginx.org/ru/ > > What other language site is it? > > And if there is a Japanese site, I want to translate. There are various other languages, see here: http://hg.nginx.org/nginx.org/file/tip/xml Though all except English and Russian are stale and was deactivated. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Mar 23 13:51:07 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 23 Mar 2016 13:51:07 +0000 Subject: [nginx] Backed out server_tokens changes. Message-ID: details: http://hg.nginx.org/nginx/rev/155871d773cc branches: changeset: 6451:155871d773cc user: Maxim Dounin date: Tue Mar 22 16:58:38 2016 +0300 description: Backed out server_tokens changes. Backed out changesets: cf3e75cfa951, 6b72414dfb4f, 602dc42035fe, e5076b96fd01. diffstat: src/http/ngx_http_core_module.c | 56 ++----------------------------- src/http/ngx_http_core_module.h | 4 +- src/http/ngx_http_header_filter_module.c | 47 ++++++++------------------ src/http/ngx_http_special_response.c | 49 ++++++++------------------- src/http/v2/ngx_http_v2_filter_module.c | 52 +++++------------------------ 5 files changed, 45 insertions(+), 163 deletions(-) diffs (365 lines): diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -59,8 +59,6 @@ static char *ngx_http_core_set_aio(ngx_c void *conf); static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static char *ngx_http_core_server_tokens(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, @@ -594,10 +592,10 @@ static ngx_command_t ngx_http_core_comm NULL }, { ngx_string("server_tokens"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_core_server_tokens, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, - 0, + offsetof(ngx_http_core_loc_conf_t, server_tokens), NULL }, { ngx_string("if_modified_since"), @@ -3645,9 +3643,9 @@ ngx_http_core_create_loc_conf(ngx_conf_t clcf->log_not_found = NGX_CONF_UNSET; clcf->log_subrequest = NGX_CONF_UNSET; clcf->recursive_error_pages = NGX_CONF_UNSET; + clcf->server_tokens = NGX_CONF_UNSET; clcf->chunked_transfer_encoding = NGX_CONF_UNSET; clcf->etag = NGX_CONF_UNSET; - clcf->server_tokens = NGX_CONF_UNSET_UINT; clcf->types_hash_max_size = NGX_CONF_UNSET_UINT; clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT; @@ -3911,15 +3909,11 @@ ngx_http_core_merge_loc_conf(ngx_conf_t ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0); ngx_conf_merge_value(conf->recursive_error_pages, prev->recursive_error_pages, 0); + ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1); ngx_conf_merge_value(conf->chunked_transfer_encoding, prev->chunked_transfer_encoding, 1); ngx_conf_merge_value(conf->etag, prev->etag, 1); - if (conf->server_tokens == NGX_CONF_UNSET_UINT) { - ngx_conf_merge_uint_value(conf->server_tokens, prev->server_tokens, 1); - conf->server_tokens_value = prev->server_tokens_value; - } - ngx_conf_merge_ptr_value(conf->open_file_cache, prev->open_file_cache, NULL); @@ -4802,46 +4796,6 @@ ngx_http_core_directio(ngx_conf_t *cf, n static char * -ngx_http_core_server_tokens(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_http_core_loc_conf_t *clcf = conf; - - ngx_str_t *value; - ngx_http_compile_complex_value_t ccv; - - if (clcf->server_tokens != NGX_CONF_UNSET_UINT) { - return "is duplicate"; - } - - value = cf->args->elts; - - if (ngx_strcmp(value[1].data, "on") == 0) { - clcf->server_tokens = 1; - return NGX_CONF_OK; - } - - if (ngx_strcmp(value[1].data, "off") == 0) { - clcf->server_tokens = 0; - return NGX_CONF_OK; - } - - ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); - - ccv.cf = cf; - ccv.value = &value[1]; - ccv.complex_value = &clcf->server_tokens_value; - - if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; - } - - clcf->server_tokens = 2; - - return NGX_CONF_OK; -} - - -static char * ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf = conf; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -415,12 +415,10 @@ struct ngx_http_core_loc_conf_s { ngx_flag_t log_not_found; /* log_not_found */ ngx_flag_t log_subrequest; /* log_subrequest */ ngx_flag_t recursive_error_pages; /* recursive_error_pages */ + ngx_flag_t server_tokens; /* server_tokens */ ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */ ngx_flag_t etag; /* etag */ - ngx_uint_t server_tokens; /* server_tokens */ - ngx_http_complex_value_t server_tokens_value; - #if (NGX_HTTP_GZIP) ngx_flag_t gzip_vary; /* gzip_vary */ diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -46,8 +46,8 @@ ngx_module_t ngx_http_header_filter_mod }; -static u_char ngx_http_server_string[] = "Server: nginx" CRLF; -static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF; +static char ngx_http_server_string[] = "Server: nginx" CRLF; +static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF; static ngx_str_t ngx_http_status_lines[] = { @@ -152,7 +152,7 @@ ngx_http_header_filter(ngx_http_request_ { u_char *p; size_t len; - ngx_str_t host, *status_line, tokens; + ngx_str_t host, *status_line; ngx_buf_t *b; ngx_uint_t status, i, port; ngx_chain_t out; @@ -277,35 +277,9 @@ ngx_http_header_filter(ngx_http_request_ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); -#if (NGX_SUPPRESS_WARN) - ngx_str_null(&tokens); -#endif - if (r->headers_out.server == NULL) { - if (clcf->server_tokens == 0) { - ngx_str_set(&tokens, ngx_http_server_string); - - } else if (clcf->server_tokens == 1) { - ngx_str_set(&tokens, ngx_http_server_full_string); - - } else { - if (ngx_http_complex_value(r, &clcf->server_tokens_value, &tokens) - != NGX_OK) - { - return NGX_ERROR; - } - - if (tokens.len == 0 - || (tokens.len == 3 && ngx_strncmp(tokens.data, "off", 3) == 0)) - { - ngx_str_set(&tokens, ngx_http_server_string); - - } else { - ngx_str_set(&tokens, ngx_http_server_full_string); - } - } - - len += tokens.len; + len += clcf->server_tokens ? sizeof(ngx_http_server_full_string) - 1: + sizeof(ngx_http_server_string) - 1; } if (r->headers_out.date == NULL) { @@ -482,7 +456,16 @@ ngx_http_header_filter(ngx_http_request_ *b->last++ = CR; *b->last++ = LF; if (r->headers_out.server == NULL) { - b->last = ngx_cpymem(b->last, tokens.data, tokens.len); + if (clcf->server_tokens) { + p = (u_char *) ngx_http_server_full_string; + len = sizeof(ngx_http_server_full_string) - 1; + + } else { + p = (u_char *) ngx_http_server_string; + len = sizeof(ngx_http_server_string) - 1; + } + + b->last = ngx_cpymem(b->last, p, len); } if (r->headers_out.date == NULL) { diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -609,42 +609,26 @@ static ngx_int_t ngx_http_send_special_response(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf, ngx_uint_t err) { + u_char *tail; + size_t len; ngx_int_t rc; - ngx_str_t tail, tokens; ngx_buf_t *b; ngx_uint_t msie_padding; ngx_chain_t out[3]; + if (clcf->server_tokens) { + len = sizeof(ngx_http_error_full_tail) - 1; + tail = ngx_http_error_full_tail; + + } else { + len = sizeof(ngx_http_error_tail) - 1; + tail = ngx_http_error_tail; + } + msie_padding = 0; if (ngx_http_error_pages[err].len) { - - if (clcf->server_tokens == 0) { - ngx_str_set(&tail, ngx_http_error_tail); - - } else if (clcf->server_tokens == 1) { - ngx_str_set(&tail, ngx_http_error_full_tail); - - } else { - if (ngx_http_complex_value(r, &clcf->server_tokens_value, &tokens) - != NGX_OK) - { - return NGX_ERROR; - } - - if (tokens.len == 0 - || (tokens.len == 3 && ngx_strncmp(tokens.data, "off", 3) == 0)) - { - ngx_str_set(&tail, ngx_http_error_tail); - - } else { - ngx_str_set(&tail, ngx_http_error_full_tail); - } - } - - r->headers_out.content_length_n = ngx_http_error_pages[err].len - + tail.len; - + r->headers_out.content_length_n = ngx_http_error_pages[err].len + len; if (clcf->msie_padding && (r->headers_in.msie || r->headers_in.chrome) && r->http_version >= NGX_HTTP_VERSION_10 @@ -661,10 +645,6 @@ ngx_http_send_special_response(ngx_http_ } else { r->headers_out.content_length_n = 0; - -#if (NGX_SUPPRESS_WARN) - ngx_str_null(&tail); -#endif } if (r->headers_out.content_length) { @@ -704,8 +684,9 @@ ngx_http_send_special_response(ngx_http_ } b->memory = 1; - b->pos = tail.data; - b->last = tail.data + tail.len; + + b->pos = tail; + b->last = tail + len; out[1].buf = b; out[1].next = NULL; diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -128,8 +128,8 @@ ngx_http_v2_header_filter(ngx_http_reque { u_char status, *pos, *start, *p, *tmp; size_t len, tmp_len; - ngx_str_t host, location, tokens; - ngx_uint_t i, port, server_tokens; + ngx_str_t host, location; + ngx_uint_t i, port; ngx_list_part_t *part; ngx_table_elt_t *header; ngx_connection_t *fc; @@ -229,42 +229,8 @@ ngx_http_v2_header_filter(ngx_http_reque clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - server_tokens = clcf->server_tokens; - -#if (NGX_SUPPRESS_WARN) - ngx_str_null(&tokens); -#endif - if (r->headers_out.server == NULL) { - - if (server_tokens == 0) { - len += 1 + sizeof(nginx); - ngx_str_set(&tokens, "nginx"); - - } else if (server_tokens == 1) { - len += 1 + nginx_ver_len; - ngx_str_set(&tokens, NGINX_VER); - - } else { - if (ngx_http_complex_value(r, &clcf->server_tokens_value, &tokens) - != NGX_OK) - { - return NGX_ERROR; - } - - if (tokens.len == 0 - || (tokens.len == 3 && ngx_strncmp(tokens.data, "off", 3) == 0)) - { - server_tokens = 0; - len += 1 + sizeof(nginx); - ngx_str_set(&tokens, "nginx"); - - } else { - server_tokens = 1; - len += 1 + nginx_ver_len; - ngx_str_set(&tokens, NGINX_VER); - } - } + len += 1 + (clcf->server_tokens ? nginx_ver_len : sizeof(nginx)); } if (r->headers_out.date == NULL) { @@ -470,15 +436,12 @@ ngx_http_v2_header_filter(ngx_http_reque if (r->headers_out.server == NULL) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, - "http2 output header: \"server: %V\"", - &tokens); + "http2 output header: \"server: %s\"", + clcf->server_tokens ? NGINX_VER : "nginx"); *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX); - if (server_tokens == 0) { - pos = ngx_cpymem(pos, nginx, sizeof(nginx)); - - } else { + if (clcf->server_tokens) { if (nginx_ver[0] == '\0') { p = ngx_http_v2_write_value(nginx_ver, (u_char *) NGINX_VER, sizeof(NGINX_VER) - 1, tmp); @@ -486,6 +449,9 @@ ngx_http_v2_header_filter(ngx_http_reque } pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len); + + } else { + pos = ngx_cpymem(pos, nginx, sizeof(nginx)); } } From vbart at nginx.com Wed Mar 23 13:51:41 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Wed, 23 Mar 2016 16:51:41 +0300 Subject: Nginx Overflow ? status 18446744073709551615 In-Reply-To: <56F28DA9.0@rachetjay.fr> References: <56F28DA9.0@rachetjay.fr> Message-ID: <1831037.Z2ZUEIq2Ov@vbart-workstation> On Wednesday 23 March 2016 13:35:53 Jadjay wrote: [..] > Yes we have some 3-rd party modules : > > /usr/local/usr/sbin/nginx -V > > nginx version: nginx/1.6.0 [..] You are using outdated unsupported version of nginx. At first, you should update to actual version. [..] > --add-module=/root/rpmbuild//BUILD/nginx-1.6.0/modsecurity-2.8.0/nginx/modsecurity > > --add-module=/root/rpmbuild//BUILD/nginx-1.6.0/ngx_cache_purge-2.1 > --add-module=/root/rpmbuild//BUILD/nginx-1.6.0/ngx_http_substitutions_filter_module > > > --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions > -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' > --with-ld-opt=-Wl,-E > > But only modsecurity is used, > Any of 3rd-party modules (including modsecurity) can introduce bugs. wbr, Valentin V. Bartenev From vbart at nginx.com Wed Mar 23 14:45:36 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 23 Mar 2016 14:45:36 +0000 Subject: [nginx] Core: moved logging before freeing large blocks of pool. Message-ID: details: http://hg.nginx.org/nginx/rev/6be7e59fdd2c branches: changeset: 6452:6be7e59fdd2c user: Valentin Bartenev date: Wed Mar 23 17:44:04 2016 +0300 description: Core: moved logging before freeing large blocks of pool. This fixes use-after-free memory access with enabled debug log when pool->log is allocated as a large block. diffstat: src/core/ngx_palloc.c | 19 ++++++++++--------- 1 files changed, 10 insertions(+), 9 deletions(-) diffs (43 lines): diff -r 155871d773cc -r 6be7e59fdd2c src/core/ngx_palloc.c --- a/src/core/ngx_palloc.c Tue Mar 22 16:58:38 2016 +0300 +++ b/src/core/ngx_palloc.c Wed Mar 23 17:44:04 2016 +0300 @@ -56,15 +56,6 @@ ngx_destroy_pool(ngx_pool_t *pool) } } - for (l = pool->large; l; l = l->next) { - - ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc); - - if (l->alloc) { - ngx_free(l->alloc); - } - } - #if (NGX_DEBUG) /* @@ -72,6 +63,10 @@ ngx_destroy_pool(ngx_pool_t *pool) * so we cannot use this log while free()ing the pool */ + for (l = pool->large; l; l = l->next) { + ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc); + } + for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) { ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p, unused: %uz", p, p->d.end - p->d.last); @@ -83,6 +78,12 @@ ngx_destroy_pool(ngx_pool_t *pool) #endif + for (l = pool->large; l; l = l->next) { + if (l->alloc) { + ngx_free(l->alloc); + } + } + for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) { ngx_free(p); From vbart at nginx.com Wed Mar 23 14:45:39 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 23 Mar 2016 14:45:39 +0000 Subject: [nginx] Core: introduced the ngx_palloc_small() function. Message-ID: details: http://hg.nginx.org/nginx/rev/12248fe20689 branches: changeset: 6453:12248fe20689 user: Valentin Bartenev date: Wed Mar 23 17:44:04 2016 +0300 description: Core: introduced the ngx_palloc_small() function. It deduplicates some code for allocations from memory pool. No functional changes. diffstat: src/core/ngx_palloc.c | 61 ++++++++++++++++++++++---------------------------- 1 files changed, 27 insertions(+), 34 deletions(-) diffs (96 lines): diff -r 6be7e59fdd2c -r 12248fe20689 src/core/ngx_palloc.c --- a/src/core/ngx_palloc.c Wed Mar 23 17:44:04 2016 +0300 +++ b/src/core/ngx_palloc.c Wed Mar 23 17:44:04 2016 +0300 @@ -9,6 +9,8 @@ #include +static ngx_inline void *ngx_palloc_small(ngx_pool_t *pool, size_t size, + ngx_uint_t align); static void *ngx_palloc_block(ngx_pool_t *pool, size_t size); static void *ngx_palloc_large(ngx_pool_t *pool, size_t size); @@ -120,27 +122,8 @@ ngx_reset_pool(ngx_pool_t *pool) void * ngx_palloc(ngx_pool_t *pool, size_t size) { - u_char *m; - ngx_pool_t *p; - if (size <= pool->max) { - - p = pool->current; - - do { - m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT); - - if ((size_t) (p->d.end - m) >= size) { - p->d.last = m + size; - - return m; - } - - p = p->d.next; - - } while (p); - - return ngx_palloc_block(pool, size); + return ngx_palloc_small(pool, size, 1); } return ngx_palloc_large(pool, size); @@ -150,30 +133,40 @@ ngx_palloc(ngx_pool_t *pool, size_t size void * ngx_pnalloc(ngx_pool_t *pool, size_t size) { + if (size <= pool->max) { + return ngx_palloc_small(pool, size, 0); + } + + return ngx_palloc_large(pool, size); +} + + +static ngx_inline void * +ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align) +{ u_char *m; ngx_pool_t *p; - if (size <= pool->max) { + p = pool->current; - p = pool->current; + do { + m = p->d.last; - do { - m = p->d.last; + if (align) { + m = ngx_align_ptr(m, NGX_ALIGNMENT); + } - if ((size_t) (p->d.end - m) >= size) { - p->d.last = m + size; + if ((size_t) (p->d.end - m) >= size) { + p->d.last = m + size; - return m; - } + return m; + } - p = p->d.next; + p = p->d.next; - } while (p); + } while (p); - return ngx_palloc_block(pool, size); - } - - return ngx_palloc_large(pool, size); + return ngx_palloc_block(pool, size); } From vbart at nginx.com Wed Mar 23 14:45:41 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 23 Mar 2016 14:45:41 +0000 Subject: [nginx] Core: use ngx_palloc_small() to allocate ngx_pool_large_t. Message-ID: details: http://hg.nginx.org/nginx/rev/f61472978419 branches: changeset: 6454:f61472978419 user: Valentin Bartenev date: Wed Mar 23 17:44:04 2016 +0300 description: Core: use ngx_palloc_small() to allocate ngx_pool_large_t. This structure cannot be allocated as a large block anyway, otherwise that will result in infinite recursion, since each large allocation requires to allocate another ngx_pool_large_t. The room for the structure is guaranteed by the NGX_MIN_POOL_SIZE constant. diffstat: src/core/ngx_palloc.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 12248fe20689 -r f61472978419 src/core/ngx_palloc.c --- a/src/core/ngx_palloc.c Wed Mar 23 17:44:04 2016 +0300 +++ b/src/core/ngx_palloc.c Wed Mar 23 17:44:04 2016 +0300 @@ -231,7 +231,7 @@ ngx_palloc_large(ngx_pool_t *pool, size_ } } - large = ngx_palloc(pool, sizeof(ngx_pool_large_t)); + large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1); if (large == NULL) { ngx_free(p); return NULL; @@ -256,7 +256,7 @@ ngx_pmemalign(ngx_pool_t *pool, size_t s return NULL; } - large = ngx_palloc(pool, sizeof(ngx_pool_large_t)); + large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1); if (large == NULL) { ngx_free(p); return NULL; From vbart at nginx.com Wed Mar 23 14:45:44 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 23 Mar 2016 14:45:44 +0000 Subject: [nginx] Core: introduced the NGX_DEBUG_PALLOC macro. Message-ID: details: http://hg.nginx.org/nginx/rev/ad2360782ecd branches: changeset: 6455:ad2360782ecd user: Valentin Bartenev date: Wed Mar 23 17:44:04 2016 +0300 description: Core: introduced the NGX_DEBUG_PALLOC macro. It allows to turn off accumulation of small pool allocations into a big preallocated chunk of memory. This is useful for debugging memory access with sanitizer, since such accumulation can cover buffer overruns from being detected. diffstat: src/core/ngx_palloc.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (27 lines): diff -r f61472978419 -r ad2360782ecd src/core/ngx_palloc.c --- a/src/core/ngx_palloc.c Wed Mar 23 17:44:04 2016 +0300 +++ b/src/core/ngx_palloc.c Wed Mar 23 17:44:04 2016 +0300 @@ -122,9 +122,11 @@ ngx_reset_pool(ngx_pool_t *pool) void * ngx_palloc(ngx_pool_t *pool, size_t size) { +#if !(NGX_DEBUG_PALLOC) if (size <= pool->max) { return ngx_palloc_small(pool, size, 1); } +#endif return ngx_palloc_large(pool, size); } @@ -133,9 +135,11 @@ ngx_palloc(ngx_pool_t *pool, size_t size void * ngx_pnalloc(ngx_pool_t *pool, size_t size) { +#if !(NGX_DEBUG_PALLOC) if (size <= pool->max) { return ngx_palloc_small(pool, size, 0); } +#endif return ngx_palloc_large(pool, size); } From xeioex at nginx.com Wed Mar 23 14:50:17 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 23 Mar 2016 14:50:17 +0000 Subject: [nginx] Resolver: introduced valid field in resolver responses. Message-ID: details: http://hg.nginx.org/nginx/rev/c94aba230a5a branches: changeset: 6456:c94aba230a5a user: Dmitry Volyntsev date: Wed Mar 23 17:44:36 2016 +0300 description: Resolver: introduced valid field in resolver responses. It hints the amount of time a response could be considered as valid. diffstat: src/core/ngx_resolver.c | 7 +++++++ src/core/ngx_resolver.h | 1 + 2 files changed, 8 insertions(+), 0 deletions(-) diffs (70 lines): diff -r ad2360782ecd -r c94aba230a5a src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Wed Mar 23 17:44:04 2016 +0300 +++ b/src/core/ngx_resolver.c Wed Mar 23 17:44:36 2016 +0300 @@ -551,6 +551,7 @@ ngx_resolve_name_locked(ngx_resolver_t * do { ctx->state = NGX_OK; + ctx->valid = rn->valid; ctx->naddrs = naddrs; if (addrs == NULL) { @@ -597,6 +598,7 @@ ngx_resolve_name_locked(ngx_resolver_t * do { ctx->state = NGX_RESOLVE_NXDOMAIN; + ctx->valid = ngx_time() + (r->valid ? r->valid : 10); next = ctx->next; ctx->handler(ctx); @@ -859,6 +861,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx /* unlock addr mutex */ ctx->state = NGX_OK; + ctx->valid = rn->valid; ctx->handler(ctx); @@ -1948,6 +1951,7 @@ ngx_resolver_process_a(ngx_resolver_t *r while (next) { ctx = next; ctx->state = code; + ctx->valid = ngx_time() + (r->valid ? r->valid : 10); next = ctx->next; ctx->handler(ctx); @@ -2262,6 +2266,7 @@ ngx_resolver_process_a(ngx_resolver_t *r while (next) { ctx = next; ctx->state = NGX_OK; + ctx->valid = rn->valid; ctx->naddrs = naddrs; if (addrs == NULL) { @@ -2541,6 +2546,7 @@ valid: while (next) { ctx = next; ctx->state = code; + ctx->valid = ngx_time() + (r->valid ? r->valid : 10); next = ctx->next; ctx->handler(ctx); @@ -2675,6 +2681,7 @@ ptr: while (next) { ctx = next; ctx->state = NGX_OK; + ctx->valid = rn->valid; ctx->name = name; next = ctx->next; diff -r ad2360782ecd -r c94aba230a5a src/core/ngx_resolver.h --- a/src/core/ngx_resolver.h Wed Mar 23 17:44:04 2016 +0300 +++ b/src/core/ngx_resolver.h Wed Mar 23 17:44:36 2016 +0300 @@ -164,6 +164,7 @@ struct ngx_resolver_ctx_s { ngx_int_t state; ngx_str_t name; + time_t valid; ngx_uint_t naddrs; ngx_addr_t *addrs; ngx_addr_t addr; From xeioex at nginx.com Wed Mar 23 14:50:20 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 23 Mar 2016 14:50:20 +0000 Subject: [nginx] Resolver: do not enable resolve timer if provided timeout is zero. Message-ID: details: http://hg.nginx.org/nginx/rev/a6711b85da83 branches: changeset: 6457:a6711b85da83 user: Dmitry Volyntsev date: Wed Mar 23 17:44:36 2016 +0300 description: Resolver: do not enable resolve timer if provided timeout is zero. diffstat: src/core/ngx_resolver.c | 48 ++++++++++++++++++++++++++---------------------- 1 files changed, 26 insertions(+), 22 deletions(-) diffs (83 lines): diff -r c94aba230a5a -r a6711b85da83 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Wed Mar 23 17:44:36 2016 +0300 +++ b/src/core/ngx_resolver.c Wed Mar 23 17:44:36 2016 +0300 @@ -611,7 +611,7 @@ ngx_resolve_name_locked(ngx_resolver_t * if (rn->waiting) { - if (ctx->event == NULL) { + if (ctx->event == NULL && ctx->timeout) { ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t)); if (ctx->event == NULL) { return NGX_ERROR; @@ -729,7 +729,7 @@ ngx_resolve_name_locked(ngx_resolver_t * goto failed; } - if (ctx->event == NULL) { + if (ctx->event == NULL && ctx->timeout) { ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t)); if (ctx->event == NULL) { goto failed; @@ -872,18 +872,20 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx if (rn->waiting) { - ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t)); - if (ctx->event == NULL) { - return NGX_ERROR; + if (ctx->event == NULL && ctx->timeout) { + ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t)); + if (ctx->event == NULL) { + return NGX_ERROR; + } + + ctx->event->handler = ngx_resolver_timeout_handler; + ctx->event->data = ctx; + ctx->event->log = r->log; + ctx->ident = -1; + + ngx_add_timer(ctx->event, ctx->timeout); } - ctx->event->handler = ngx_resolver_timeout_handler; - ctx->event->data = ctx; - ctx->event->log = r->log; - ctx->ident = -1; - - ngx_add_timer(ctx->event, ctx->timeout); - ctx->next = rn->waiting; rn->waiting = ctx; ctx->state = NGX_AGAIN; @@ -949,18 +951,20 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx goto failed; } - ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t)); - if (ctx->event == NULL) { - goto failed; + if (ctx->event == NULL && ctx->timeout) { + ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t)); + if (ctx->event == NULL) { + goto failed; + } + + ctx->event->handler = ngx_resolver_timeout_handler; + ctx->event->data = ctx; + ctx->event->log = r->log; + ctx->ident = -1; + + ngx_add_timer(ctx->event, ctx->timeout); } - ctx->event->handler = ngx_resolver_timeout_handler; - ctx->event->data = ctx; - ctx->event->log = r->log; - ctx->ident = -1; - - ngx_add_timer(ctx->event, ctx->timeout); - if (ngx_queue_empty(resend_queue)) { ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000)); } From xeioex at nginx.com Wed Mar 23 14:50:23 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 23 Mar 2016 14:50:23 +0000 Subject: [nginx] Resolver: added support for SRV records. Message-ID: details: http://hg.nginx.org/nginx/rev/384154fc634f branches: changeset: 6458:384154fc634f user: Dmitry Volyntsev date: Wed Mar 23 17:44:36 2016 +0300 description: Resolver: added support for SRV records. diffstat: src/core/ngx_resolver.c | 972 +++++++++++++++++++++++++++++++++++++++++- src/core/ngx_resolver.h | 47 +- src/http/ngx_http_upstream.h | 2 +- 3 files changed, 993 insertions(+), 28 deletions(-) diffs (truncated from 1371 to 1000 lines): diff -r a6711b85da83 -r 384154fc634f src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Wed Mar 23 17:44:36 2016 +0300 +++ b/src/core/ngx_resolver.c Wed Mar 23 17:44:36 2016 +0300 @@ -74,8 +74,10 @@ static ngx_int_t ngx_resolver_send_tcp_q ngx_resolver_connection_t *rec, u_char *query, u_short qlen); static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_t *r, ngx_resolver_node_t *rn, ngx_str_t *name); +static ngx_int_t ngx_resolver_create_srv_query(ngx_resolver_t *r, + ngx_resolver_node_t *rn, ngx_str_t *name); static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_t *r, - ngx_resolver_node_t *rn, ngx_addr_t *addr); + ngx_resolver_node_t *rn, ngx_resolver_addr_t *addr); static void ngx_resolver_resend_handler(ngx_event_t *ev); static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue); @@ -88,10 +90,15 @@ static void ngx_resolver_process_respons static void ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n, ngx_uint_t ident, ngx_uint_t code, ngx_uint_t qtype, ngx_uint_t nan, ngx_uint_t trunc, ngx_uint_t ans); +static void ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n, + ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, + ngx_uint_t trunc, ngx_uint_t ans); static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n, ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan); static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash); +static ngx_resolver_node_t *ngx_resolver_lookup_srv(ngx_resolver_t *r, + ngx_str_t *name, uint32_t hash); static ngx_resolver_node_t *ngx_resolver_lookup_addr(ngx_resolver_t *r, in_addr_t addr); static void ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp, @@ -105,9 +112,14 @@ static void *ngx_resolver_calloc(ngx_res static void ngx_resolver_free(ngx_resolver_t *r, void *p); static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p); static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size); -static ngx_addr_t *ngx_resolver_export(ngx_resolver_t *r, +static ngx_resolver_addr_t *ngx_resolver_export(ngx_resolver_t *r, ngx_resolver_node_t *rn, ngx_uint_t rotate); +static void ngx_resolver_report_srv(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx); static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len); +static void ngx_resolver_resolve_srv_names(ngx_resolver_ctx_t *ctx, + ngx_resolver_node_t *rn); +static void ngx_resolver_srv_names_handler(ngx_resolver_ctx_t *ctx); +static ngx_int_t ngx_resolver_cmp_srvs(const void *one, const void *two); #if (NGX_HAVE_INET6) static void ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp, @@ -149,13 +161,18 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_ ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel, ngx_resolver_rbtree_insert_value); + ngx_rbtree_init(&r->srv_rbtree, &r->srv_sentinel, + ngx_resolver_rbtree_insert_value); + ngx_rbtree_init(&r->addr_rbtree, &r->addr_sentinel, ngx_rbtree_insert_value); ngx_queue_init(&r->name_resend_queue); + ngx_queue_init(&r->srv_resend_queue); ngx_queue_init(&r->addr_resend_queue); ngx_queue_init(&r->name_expire_queue); + ngx_queue_init(&r->srv_expire_queue); ngx_queue_init(&r->addr_expire_queue); #if (NGX_HAVE_INET6) @@ -274,6 +291,8 @@ ngx_resolver_cleanup(void *data) ngx_resolver_cleanup_tree(r, &r->name_rbtree); + ngx_resolver_cleanup_tree(r, &r->srv_rbtree); + ngx_resolver_cleanup_tree(r, &r->addr_rbtree); #if (NGX_HAVE_INET6) @@ -383,7 +402,9 @@ ngx_resolve_start(ngx_resolver_t *r, ngx ngx_int_t ngx_resolve_name(ngx_resolver_ctx_t *ctx) { + size_t slen; ngx_int_t rc; + ngx_str_t name; ngx_resolver_t *r; r = ctx->resolver; @@ -400,9 +421,41 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx return NGX_OK; } - /* lock name mutex */ - - rc = ngx_resolve_name_locked(r, ctx, &ctx->name); + if (ctx->service.len) { + slen = ctx->service.len; + + if (ngx_strlchr(ctx->service.data, + ctx->service.data + ctx->service.len, '.') + == NULL) + { + slen += sizeof("_._tcp") - 1; + } + + name.len = slen + 1 + ctx->name.len; + + name.data = ngx_resolver_alloc(r, name.len); + if (name.data == NULL) { + return NGX_ERROR; + } + + if (slen == ctx->service.len) { + ngx_sprintf(name.data, "%V.%V", &ctx->service, &ctx->name); + + } else { + ngx_sprintf(name.data, "_%V._tcp.%V", &ctx->service, &ctx->name); + } + + /* lock name mutex */ + + rc = ngx_resolve_name_locked(r, ctx, &name); + + ngx_resolver_free(r, name.data); + + } else { + /* lock name mutex */ + + rc = ngx_resolve_name_locked(r, ctx, &ctx->name); + } if (rc == NGX_OK) { return NGX_OK; @@ -429,6 +482,7 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx void ngx_resolve_name_done(ngx_resolver_ctx_t *ctx) { + ngx_uint_t i; ngx_resolver_t *r; ngx_resolver_ctx_t *w, **p; ngx_resolver_node_t *rn; @@ -448,6 +502,23 @@ ngx_resolve_name_done(ngx_resolver_ctx_t /* lock name mutex */ + if (ctx->nsrvs) { + for (i = 0; i < ctx->nsrvs; i++) { + if (ctx->srvs[i].ctx) { + ngx_resolve_name_done(ctx->srvs[i].ctx); + } + + if (ctx->srvs[i].addrs) { + ngx_resolver_free(r, ctx->srvs[i].addrs->sockaddr); + ngx_resolver_free(r, ctx->srvs[i].addrs); + } + + ngx_resolver_free(r, ctx->srvs[i].name.data); + } + + ngx_resolver_free(r, ctx->srvs); + } + if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) { rn = ctx->node; @@ -466,15 +537,20 @@ ngx_resolve_name_done(ngx_resolver_ctx_t p = &w->next; w = w->next; } + + ngx_log_error(NGX_LOG_ALERT, r->log, 0, + "could not cancel %V resolving", &ctx->name); } - - ngx_log_error(NGX_LOG_ALERT, r->log, 0, - "could not cancel %V resolving", &ctx->name); } done: - ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue); + if (ctx->service.len) { + ngx_resolver_expire(r, &r->srv_rbtree, &r->srv_expire_queue); + + } else { + ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue); + } /* unlock name mutex */ @@ -501,16 +577,31 @@ ngx_resolve_name_locked(ngx_resolver_t * uint32_t hash; ngx_int_t rc; ngx_str_t cname; - ngx_uint_t naddrs; - ngx_addr_t *addrs; + ngx_uint_t i, naddrs; + ngx_queue_t *resend_queue, *expire_queue; + ngx_rbtree_t *tree; ngx_resolver_ctx_t *next, *last; + ngx_resolver_addr_t *addrs; ngx_resolver_node_t *rn; ngx_strlow(name->data, name->data, name->len); hash = ngx_crc32_short(name->data, name->len); - rn = ngx_resolver_lookup_name(r, name, hash); + if (ctx->service.len) { + rn = ngx_resolver_lookup_srv(r, name, hash); + + tree = &r->srv_rbtree; + resend_queue = &r->srv_resend_queue; + expire_queue = &r->srv_expire_queue; + + } else { + rn = ngx_resolver_lookup_name(r, name, hash); + + tree = &r->name_rbtree; + resend_queue = &r->name_resend_queue; + expire_queue = &r->name_expire_queue; + } if (rn) { @@ -525,7 +616,7 @@ ngx_resolve_name_locked(ngx_resolver_t * rn->expire = ngx_time() + r->expire; - ngx_queue_insert_head(&r->name_expire_queue, &rn->queue); + ngx_queue_insert_head(expire_queue, &rn->queue); naddrs = (rn->naddrs == (u_short) -1) ? 0 : rn->naddrs; #if (NGX_HAVE_INET6) @@ -581,6 +672,23 @@ ngx_resolve_name_locked(ngx_resolver_t * return NGX_OK; } + if (rn->nsrvs) { + last->next = rn->waiting; + rn->waiting = NULL; + + /* unlock name mutex */ + + do { + next = ctx->next; + + ngx_resolver_resolve_srv_names(ctx, rn); + + ctx = next; + } while (ctx); + + return NGX_OK; + } + /* NGX_RESOLVE_CNAME */ if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) { @@ -663,6 +771,16 @@ ngx_resolve_name_locked(ngx_resolver_t * } #endif + if (rn->nsrvs) { + for (i = 0; i < rn->nsrvs; i++) { + if (rn->u.srvs[i].name.data) { + ngx_resolver_free_locked(r, rn->u.srvs[i].name.data); + } + } + + ngx_resolver_free_locked(r, rn->u.srvs); + } + /* unlock alloc mutex */ } else { @@ -685,17 +803,22 @@ ngx_resolve_name_locked(ngx_resolver_t * rn->query6 = NULL; #endif - ngx_rbtree_insert(&r->name_rbtree, &rn->node); + ngx_rbtree_insert(tree, &rn->node); } - rc = ngx_resolver_create_name_query(r, rn, name); + if (ctx->service.len) { + rc = ngx_resolver_create_srv_query(r, rn, name); + + } else { + rc = ngx_resolver_create_name_query(r, rn, name); + } if (rc == NGX_ERROR) { goto failed; } if (rc == NGX_DECLINED) { - ngx_rbtree_delete(&r->name_rbtree, &rn->node); + ngx_rbtree_delete(tree, &rn->node); ngx_resolver_free(r, rn->query); ngx_resolver_free(r, rn->name); @@ -724,6 +847,7 @@ ngx_resolve_name_locked(ngx_resolver_t * rn->naddrs6 = r->ipv6 ? (u_short) -1 : 0; rn->tcp6 = 0; #endif + rn->nsrvs = 0; if (ngx_resolver_send_query(r, rn) != NGX_OK) { goto failed; @@ -743,13 +867,13 @@ ngx_resolve_name_locked(ngx_resolver_t * ngx_add_timer(ctx->event, ctx->timeout); } - if (ngx_queue_empty(&r->name_resend_queue)) { + if (ngx_queue_empty(resend_queue)) { ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000)); } rn->expire = ngx_time() + r->resend_timeout; - ngx_queue_insert_head(&r->name_resend_queue, &rn->queue); + ngx_queue_insert_head(resend_queue, &rn->queue); rn->code = 0; rn->cnlen = 0; @@ -768,7 +892,7 @@ ngx_resolve_name_locked(ngx_resolver_t * failed: - ngx_rbtree_delete(&r->name_rbtree, &rn->node); + ngx_rbtree_delete(tree, &rn->node); if (rn->query) { ngx_resolver_free(r, rn->query); @@ -946,6 +1070,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx rn->naddrs6 = (u_short) -1; rn->tcp6 = 0; #endif + rn->nsrvs = 0; if (ngx_resolver_send_query(r, rn) != NGX_OK) { goto failed; @@ -1301,7 +1426,7 @@ ngx_resolver_send_tcp_query(ngx_resolver static void ngx_resolver_resend_handler(ngx_event_t *ev) { - time_t timer, atimer, ntimer; + time_t timer, atimer, stimer, ntimer; #if (NGX_HAVE_INET6) time_t a6timer; #endif @@ -1316,6 +1441,8 @@ ngx_resolver_resend_handler(ngx_event_t ntimer = ngx_resolver_resend(r, &r->name_rbtree, &r->name_resend_queue); + stimer = ngx_resolver_resend(r, &r->srv_rbtree, &r->srv_resend_queue); + /* unlock name mutex */ /* lock addr mutex */ @@ -1343,6 +1470,13 @@ ngx_resolver_resend_handler(ngx_event_t timer = ngx_min(timer, atimer); } + if (timer == 0) { + timer = stimer; + + } else if (stimer) { + timer = ngx_min(timer, stimer); + } + #if (NGX_HAVE_INET6) if (timer == 0) { @@ -1703,6 +1837,13 @@ found: break; + case NGX_RESOLVE_SRV: + + ngx_resolver_process_srv(r, buf, n, ident, code, nan, trunc, + i + sizeof(ngx_resolver_qs_t)); + + break; + case NGX_RESOLVE_PTR: ngx_resolver_process_ptr(r, buf, n, ident, code, nan); @@ -1756,7 +1897,6 @@ ngx_resolver_process_a(ngx_resolver_t *r uint32_t hash; in_addr_t *addr; ngx_str_t name; - ngx_addr_t *addrs; ngx_uint_t type, class, qident, naddrs, a, i, j, start; #if (NGX_HAVE_INET6) struct in6_addr *addr6; @@ -1764,6 +1904,7 @@ ngx_resolver_process_a(ngx_resolver_t *r ngx_resolver_an_t *an; ngx_resolver_ctx_t *ctx, *next; ngx_resolver_node_t *rn; + ngx_resolver_addr_t *addrs; ngx_resolver_connection_t *rec; if (ngx_resolver_copy(r, &name, buf, @@ -2400,6 +2541,536 @@ next: static void +ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n, + ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, + ngx_uint_t trunc, ngx_uint_t ans) +{ + char *err; + u_char *cname; + size_t len; + int32_t ttl; + uint32_t hash; + ngx_str_t name; + ngx_uint_t type, qident, class, start, nsrvs, a, i, j; + ngx_resolver_an_t *an; + ngx_resolver_ctx_t *ctx, *next; + ngx_resolver_srv_t *srvs; + ngx_resolver_node_t *rn; + ngx_resolver_connection_t *rec; + + if (ngx_resolver_copy(r, &name, buf, + buf + sizeof(ngx_resolver_hdr_t), buf + n) + != NGX_OK) + { + return; + } + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name); + + hash = ngx_crc32_short(name.data, name.len); + + rn = ngx_resolver_lookup_srv(r, &name, hash); + + if (rn == NULL || rn->query == NULL) { + ngx_log_error(r->log_level, r->log, 0, + "unexpected response for %V", &name); + ngx_resolver_free(r, name.data); + goto failed; + } + + if (trunc && rn->tcp) { + ngx_resolver_free(r, name.data); + goto failed; + } + + qident = (rn->query[0] << 8) + rn->query[1]; + + if (ident != qident) { + ngx_log_error(r->log_level, r->log, 0, + "wrong ident %ui response for %V, expect %ui", + ident, &name, qident); + ngx_resolver_free(r, name.data); + goto failed; + } + + ngx_resolver_free(r, name.data); + + if (trunc) { + + ngx_queue_remove(&rn->queue); + + if (rn->waiting == NULL) { + ngx_rbtree_delete(&r->srv_rbtree, &rn->node); + ngx_resolver_free_node(r, rn); + return; + } + + rec = r->connections.elts; + rec = &rec[rn->last_connection]; + + rn->tcp = 1; + + (void) ngx_resolver_send_tcp_query(r, rec, rn->query, rn->qlen); + + rn->expire = ngx_time() + r->resend_timeout; + + ngx_queue_insert_head(&r->srv_resend_queue, &rn->queue); + + return; + } + + if (code == 0 && rn->code) { + code = rn->code; + } + + if (code == 0 && nan == 0) { + code = NGX_RESOLVE_NXDOMAIN; + } + + if (code) { + next = rn->waiting; + rn->waiting = NULL; + + ngx_queue_remove(&rn->queue); + + ngx_rbtree_delete(&r->srv_rbtree, &rn->node); + + while (next) { + ctx = next; + ctx->state = code; + ctx->valid = ngx_time() + (r->valid ? r->valid : 10); + next = ctx->next; + + ctx->handler(ctx); + } + + ngx_resolver_free_node(r, rn); + + return; + } + + i = ans; + nsrvs = 0; + cname = NULL; + + for (a = 0; a < nan; a++) { + + start = i; + + while (i < n) { + + if (buf[i] & 0xc0) { + i += 2; + goto found; + } + + if (buf[i] == 0) { + i++; + goto test_length; + } + + i += 1 + buf[i]; + } + + goto short_response; + + test_length: + + if (i - start < 2) { + err = "invalid name DNS response"; + goto invalid; + } + + found: + + if (i + sizeof(ngx_resolver_an_t) >= n) { + goto short_response; + } + + an = (ngx_resolver_an_t *) &buf[i]; + + type = (an->type_hi << 8) + an->type_lo; + class = (an->class_hi << 8) + an->class_lo; + len = (an->len_hi << 8) + an->len_lo; + ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16) + + (an->ttl[2] << 8) + (an->ttl[3]); + + if (class != 1) { + ngx_log_error(r->log_level, r->log, 0, + "unexpected RR class %ui", class); + goto failed; + } + + if (ttl < 0) { + ttl = 0; + } + + rn->ttl = ngx_min(rn->ttl, (uint32_t) ttl); + + i += sizeof(ngx_resolver_an_t); + + switch (type) { + + case NGX_RESOLVE_SRV: + + if (i + 6 > n) { + goto short_response; + } + + if (ngx_resolver_copy(r, NULL, buf, &buf[i + 6], buf + n) + != NGX_OK) + { + goto failed; + } + + nsrvs++; + + break; + + case NGX_RESOLVE_CNAME: + + cname = &buf[i]; + + break; + + case NGX_RESOLVE_DNAME: + + break; + + default: + + ngx_log_error(r->log_level, r->log, 0, + "unexpected RR type %ui", type); + } + + i += len; + } + + ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, + "resolver nsrvs:%ui cname:%p ttl:%uD", + nsrvs, cname, rn->ttl); + + if (nsrvs) { + + srvs = ngx_resolver_calloc(r, nsrvs * sizeof(ngx_resolver_srv_t)); + if (srvs == NULL) { + goto failed; + } + + rn->u.srvs = srvs; + rn->nsrvs = nsrvs; + + j = 0; + i = ans; + + for (a = 0; a < nan; a++) { + + for ( ;; ) { + + if (buf[i] & 0xc0) { + i += 2; + break; + } + + if (buf[i] == 0) { + i++; + break; + } + + i += 1 + buf[i]; + } + + an = (ngx_resolver_an_t *) &buf[i]; + + type = (an->type_hi << 8) + an->type_lo; + len = (an->len_hi << 8) + an->len_lo; + + i += sizeof(ngx_resolver_an_t); + + if (type == NGX_RESOLVE_SRV) { + + srvs[j].priority = (buf[i] << 8) + buf[i + 1]; + srvs[j].weight = (buf[i + 2] << 8) + buf[i + 3]; + + if (srvs[j].weight == 0) { + srvs[j].weight = 1; + } + + srvs[j].port = (buf[i + 4] << 8) + buf[i + 5]; + + if (ngx_resolver_copy(r, &srvs[j].name, buf, &buf[i + 6], + buf + n) + != NGX_OK) + { + goto failed; + } + + j++; + } + + i += len; + } + + ngx_sort(srvs, nsrvs, sizeof(ngx_resolver_srv_t), + ngx_resolver_cmp_srvs); + + ngx_resolver_free(r, rn->query); + rn->query = NULL; + + ngx_queue_remove(&rn->queue); + + rn->valid = ngx_time() + (r->valid ? r->valid : (time_t) rn->ttl); + rn->expire = ngx_time() + r->expire; + + ngx_queue_insert_head(&r->srv_expire_queue, &rn->queue); + + next = rn->waiting; + rn->waiting = NULL; + + while (next) { + ctx = next; + next = ctx->next; + + ngx_resolver_resolve_srv_names(ctx, rn); + } + + return; + } + + rn->nsrvs = 0; + + if (cname) { + + /* CNAME only */ + + if (ngx_resolver_copy(r, &name, buf, cname, buf + n) != NGX_OK) { + goto failed; + } + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, + "resolver cname:\"%V\"", &name); + + ngx_queue_remove(&rn->queue); + + rn->cnlen = (u_short) name.len; + rn->u.cname = name.data; + + rn->valid = ngx_time() + (r->valid ? r->valid : (time_t) rn->ttl); + rn->expire = ngx_time() + r->expire; + + ngx_queue_insert_head(&r->srv_expire_queue, &rn->queue); + + ngx_resolver_free(r, rn->query); + rn->query = NULL; +#if (NGX_HAVE_INET6) + rn->query6 = NULL; +#endif + + ctx = rn->waiting; + rn->waiting = NULL; + + if (ctx) { + + if (ctx->recursion++ >= NGX_RESOLVER_MAX_RECURSION) { + + /* unlock name mutex */ + + do { + ctx->state = NGX_RESOLVE_NXDOMAIN; + next = ctx->next; + + ctx->handler(ctx); + + ctx = next; + } while (ctx); + + return; + } + + for (next = ctx; next; next = next->next) { + next->node = NULL; + } + + (void) ngx_resolve_name_locked(r, ctx, &name); + } + + /* unlock name mutex */ + + return; + } + + ngx_log_error(r->log_level, r->log, 0, "no SRV type in DNS response"); + + return; + +short_response: + + err = "short DNS response"; + +invalid: + + /* unlock name mutex */ + + ngx_log_error(r->log_level, r->log, 0, err); + + return; + +failed: + + /* unlock name mutex */ + + return; +} + + +static void +ngx_resolver_resolve_srv_names(ngx_resolver_ctx_t *ctx, ngx_resolver_node_t *rn) +{ + ngx_uint_t i; + ngx_resolver_t *r; + ngx_resolver_ctx_t *cctx; + ngx_resolver_srv_name_t *srvs; + + r = ctx->resolver; + + ctx->node = NULL; + ctx->state = NGX_OK; + ctx->valid = rn->valid; + ctx->count = rn->nsrvs; + + srvs = ngx_resolver_calloc(r, rn->nsrvs * sizeof(ngx_resolver_srv_name_t)); + if (srvs == NULL) { + goto failed; + } + + ctx->srvs = srvs; + ctx->nsrvs = rn->nsrvs; + + for (i = 0; i < rn->nsrvs; i++) { + srvs[i].name.data = ngx_resolver_alloc(r, rn->u.srvs[i].name.len); + if (srvs[i].name.data == NULL) { + goto failed; + } + + srvs[i].name.len = rn->u.srvs[i].name.len; + ngx_memcpy(srvs[i].name.data, rn->u.srvs[i].name.data, + srvs[i].name.len); + + cctx = ngx_resolve_start(r, NULL); + if (cctx == NULL) { + goto failed; + } + + cctx->name = srvs[i].name; + cctx->handler = ngx_resolver_srv_names_handler; + cctx->data = ctx; + cctx->srvs = &srvs[i]; + cctx->timeout = 0; + + srvs[i].priority = rn->u.srvs[i].priority; + srvs[i].weight = rn->u.srvs[i].weight; + srvs[i].port = rn->u.srvs[i].port; + srvs[i].ctx = cctx; + + if (ngx_resolve_name(cctx) == NGX_ERROR) { + srvs[i].ctx = NULL; + goto failed; + } + } + + return; + +failed: + + ctx->state = NGX_ERROR; + ctx->valid = ngx_time() + (r->valid ? r->valid : 10); + + ctx->handler(ctx); +} + + +static void +ngx_resolver_srv_names_handler(ngx_resolver_ctx_t *cctx) +{ + ngx_uint_t i; + u_char (*sockaddr)[NGX_SOCKADDRLEN]; + ngx_addr_t *addrs; + ngx_resolver_t *r; + struct sockaddr_in *sin; + ngx_resolver_ctx_t *ctx; + ngx_resolver_srv_name_t *srv; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif + + r = cctx->resolver; + ctx = cctx->data; + srv = cctx->srvs; + + ctx->count--; + + srv->ctx = NULL; + + if (cctx->naddrs) { + + ctx->valid = ngx_min(ctx->valid, cctx->valid); + + addrs = ngx_resolver_calloc(r, cctx->naddrs * sizeof(ngx_addr_t)); + if (addrs == NULL) { + ngx_resolve_name_done(cctx); + + ctx->state = NGX_ERROR; + ctx->valid = ngx_time() + (r->valid ? r->valid : 10); + + ctx->handler(ctx); + return; + } + + sockaddr = ngx_resolver_alloc(r, cctx->naddrs * NGX_SOCKADDRLEN); + if (sockaddr == NULL) { + ngx_resolver_free(r, addrs); + ngx_resolve_name_done(cctx); + + ctx->state = NGX_ERROR; + ctx->valid = ngx_time() + (r->valid ? r->valid : 10); + + ctx->handler(ctx); + return; + } + + for (i = 0; i < cctx->naddrs; i++) { + addrs[i].sockaddr = (struct sockaddr *) sockaddr[i]; + addrs[i].socklen = cctx->addrs[i].socklen; + + ngx_memcpy(sockaddr[i], cctx->addrs[i].sockaddr, + addrs[i].socklen); + + switch (addrs[i].sockaddr->sa_family) { +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) addrs[i].sockaddr; + sin6->sin6_port = htons(srv->port); + break; +#endif + default: /* AF_INET */ + sin = (struct sockaddr_in *) addrs[i].sockaddr; + sin->sin_port = htons(srv->port); + } + } + + srv->addrs = addrs; + srv->naddrs = cctx->naddrs; + } + + ngx_resolve_name_done(cctx); + + if (ctx->count == 0) { + ngx_resolver_report_srv(r, ctx); + } +} + + +static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n, ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan) { @@ -2758,6 +3429,47 @@ ngx_resolver_lookup_name(ngx_resolver_t static ngx_resolver_node_t * +ngx_resolver_lookup_srv(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash) +{ + ngx_int_t rc; + ngx_rbtree_node_t *node, *sentinel; + ngx_resolver_node_t *rn; + + node = r->srv_rbtree.root; + sentinel = r->srv_rbtree.sentinel; + + while (node != sentinel) { + + if (hash < node->key) { + node = node->left; + continue; + } + + if (hash > node->key) { + node = node->right; + continue; + } + + /* hash == node->key */ + + rn = ngx_resolver_node(node); + + rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen); + + if (rc == 0) { + return rn; + } + + node = (rc < 0) ? node->left : node->right; + } + + /* not found */ + + return NULL; +} + + +static ngx_resolver_node_t * ngx_resolver_lookup_addr(ngx_resolver_t *r, in_addr_t addr) { ngx_rbtree_node_t *node, *sentinel; @@ -3045,8 +3757,96 @@ ngx_resolver_create_name_query(ngx_resol static ngx_int_t +ngx_resolver_create_srv_query(ngx_resolver_t *r, ngx_resolver_node_t *rn, + ngx_str_t *name) +{ + u_char *p, *s; + size_t len, nlen; + ngx_uint_t ident; + ngx_resolver_qs_t *qs; + ngx_resolver_hdr_t *query; + + nlen = name->len ? (1 + name->len + 1) : 1; From arut at nginx.com Wed Mar 23 14:52:31 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Wed, 23 Mar 2016 14:52:31 +0000 Subject: [nginx] Stream: detect port absence in proxy_pass with IP literal. Message-ID: details: http://hg.nginx.org/nginx/rev/78fc2dce69e7 branches: changeset: 6459:78fc2dce69e7 user: Roman Arutyunyan date: Wed Mar 23 17:45:15 2016 +0300 description: Stream: detect port absence in proxy_pass with IP literal. This is a clone of http commit 26c127bab5ef. diffstat: src/stream/ngx_stream_upstream.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 384154fc634f -r 78fc2dce69e7 src/stream/ngx_stream_upstream.c --- a/src/stream/ngx_stream_upstream.c Wed Mar 23 17:44:36 2016 +0300 +++ b/src/stream/ngx_stream_upstream.c Wed Mar 23 17:45:15 2016 +0300 @@ -388,7 +388,7 @@ ngx_stream_upstream_add(ngx_conf_t *cf, uscf->port = u->port; uscf->no_port = u->no_port; - if (u->naddrs == 1) { + if (u->naddrs == 1 && (u->port || u->family == AF_UNIX)) { uscf->servers = ngx_array_create(cf->pool, 1, sizeof(ngx_stream_upstream_server_t)); if (uscf->servers == NULL) { From xeioex at nginx.com Wed Mar 23 17:27:29 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 23 Mar 2016 17:27:29 +0000 Subject: [nginx] Win32: fixed build after 384154fc634f. Message-ID: details: http://hg.nginx.org/nginx/rev/034329824dd3 branches: changeset: 6460:034329824dd3 user: Dmitry Volyntsev date: Wed Mar 23 18:34:05 2016 +0300 description: Win32: fixed build after 384154fc634f. diffstat: src/core/ngx_resolver.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diffs (22 lines): diff -r 78fc2dce69e7 -r 034329824dd3 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Wed Mar 23 17:45:15 2016 +0300 +++ b/src/core/ngx_resolver.c Wed Mar 23 18:34:05 2016 +0300 @@ -2758,7 +2758,7 @@ ngx_resolver_process_srv(ngx_resolver_t } rn->u.srvs = srvs; - rn->nsrvs = nsrvs; + rn->nsrvs = (u_short) nsrvs; j = 0; i = ans; @@ -4243,8 +4243,7 @@ ngx_resolver_export(ngx_resolver_t *r, n static void ngx_resolver_report_srv(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) { - u_short nsrvs; - ngx_uint_t naddrs, nw, i, j, k, l, m, n, w; + ngx_uint_t naddrs, nsrvs, nw, i, j, k, l, m, n, w; ngx_resolver_addr_t *addrs; ngx_resolver_srv_name_t *srvs; From takahiro.kujirai at it.zeus-enterprise.co.jp Thu Mar 24 00:18:14 2016 From: takahiro.kujirai at it.zeus-enterprise.co.jp (ZEUS-mgtGM KUJIRAI, Takahiro) Date: Thu, 24 Mar 2016 09:18:14 +0900 (JST) Subject: [PATCH]Translation to ja(LICENSE & README) Message-ID: <49676.153.214.79.8.1458778694.squirrel@www.info.zeus-enterprise.co.jp> Hi, Dounin Thank you for your response. I understand it. >There are various other languages, see here: > >http://hg.nginx.org/nginx.org/file/tip/xml > >Though all except English and Russian are stale and was deactivated. > >-- >Maxim Dounin >http://nginx.org/> Best Regards, Takahiro Kujirai From vl at nginx.com Thu Mar 24 05:57:06 2016 From: vl at nginx.com (Vladimir Homutov) Date: Thu, 24 Mar 2016 05:57:06 +0000 Subject: [nginx] Stream: additional logging for UDP. Message-ID: details: http://hg.nginx.org/nginx/rev/a01e315b3a78 branches: changeset: 6461:a01e315b3a78 user: Vladimir Homutov date: Fri Mar 18 19:53:22 2016 +0300 description: Stream: additional logging for UDP. diffstat: src/stream/ngx_stream_handler.c | 8 +++++--- src/stream/ngx_stream_proxy_module.c | 7 +++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diffs (51 lines): diff -r 034329824dd3 -r a01e315b3a78 src/stream/ngx_stream_handler.c --- a/src/stream/ngx_stream_handler.c Wed Mar 23 18:34:05 2016 +0300 +++ b/src/stream/ngx_stream_handler.c Fri Mar 18 19:53:22 2016 +0300 @@ -137,8 +137,9 @@ ngx_stream_init_connection(ngx_connectio len = ngx_sock_ntop(c->sockaddr, c->socklen, text, NGX_SOCKADDR_STRLEN, 1); - ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA client %*s connected to %V", - c->number, len, text, &addr_conf->addr_text); + ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA %sclient %*s connected to %V", + c->number, c->type == SOCK_DGRAM ? "udp " : "", + len, text, &addr_conf->addr_text); c->log->connection = c->number; c->log->handler = ngx_stream_log_error; @@ -328,7 +329,8 @@ ngx_stream_log_error(ngx_log_t *log, u_c s = log->data; - p = ngx_snprintf(buf, len, ", client: %V, server: %V", + p = ngx_snprintf(buf, len, ", %sclient: %V, server: %V", + s->connection->type == SOCK_DGRAM ? "udp " : "", &s->connection->addr_text, &s->connection->listening->addr_text); len -= p - buf; diff -r 034329824dd3 -r a01e315b3a78 src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Wed Mar 23 18:34:05 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Fri Mar 18 19:53:22 2016 +0300 @@ -552,7 +552,9 @@ ngx_stream_proxy_init_upstream(ngx_strea handler = c->log->handler; c->log->handler = NULL; - ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxy %V connected to %V", + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "%sproxy %V connected to %V", + pc->type == SOCK_DGRAM ? "udp " : "", &str, u->peer.name); c->log->handler = handler; @@ -1222,9 +1224,10 @@ ngx_stream_proxy_process(ngx_stream_sess c->log->handler = NULL; ngx_log_error(NGX_LOG_INFO, c->log, 0, - "%s disconnected" + "%s%s disconnected" ", bytes from/to client:%O/%O" ", bytes from/to upstream:%O/%O", + src->type == SOCK_DGRAM ? "udp " : "", from_upstream ? "upstream" : "client", s->received, c->sent, u->received, pc ? pc->sent : 0); From igor at sysoev.ru Thu Mar 24 15:16:56 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 24 Mar 2016 15:16:56 +0000 Subject: [njs] Style and small miscellaneous fixes. Message-ID: details: http://hg.nginx.org/njs/rev/5995bd7637ff branches: changeset: 85:5995bd7637ff user: Igor Sysoev date: Wed Mar 23 15:27:10 2016 +0300 description: Style and small miscellaneous fixes. diffstat: njs/njs_string.c | 6 ++++++ njs/njs_string.h | 2 +- njs/njs_vm.c | 1 - njs/njs_vm.h | 5 ++++- njs/test/njs_unit_test.c | 15 +++++++++++++++ nxt/test/lvlhsh_unit_test.c | 10 +++++----- nxt/test/rbtree_unit_test.c | 6 +++--- nxt/test/utf8_unit_test.c | 10 +++++----- 8 files changed, 39 insertions(+), 16 deletions(-) diffs (196 lines): diff -r 4deb6b538b48 -r 5995bd7637ff njs/njs_string.c --- a/njs/njs_string.c Wed Mar 23 12:10:44 2016 +0300 +++ b/njs/njs_string.c Wed Mar 23 15:27:10 2016 +0300 @@ -547,6 +547,7 @@ njs_string_prototype_concat(njs_vm_t *vm /* * String.fromUTF8(start[, end]). + * The method converts an UTF-8 encoded byte string to an Unicode string. */ static njs_ret_t @@ -599,6 +600,7 @@ njs_string_prototype_from_utf8(njs_vm_t /* * String.toUTF8(start[, end]). + * The method serializes Unicode string to an UTF-8 encoded byte string. */ static njs_ret_t @@ -621,6 +623,7 @@ njs_string_prototype_to_utf8(njs_vm_t *v /* * String.fromBytes(start[, end]). + * The method converts a byte string to an Unicode string. */ static njs_ret_t @@ -676,6 +679,9 @@ njs_string_prototype_from_bytes(njs_vm_t /* * String.toBytes(start[, end]). + * The method serializes an Unicode string to a byte string. + * The method returns null if a character larger than 255 is + * encountered in the Unicode string. */ static njs_ret_t diff -r 4deb6b538b48 -r 5995bd7637ff njs/njs_string.h --- a/njs/njs_string.h Wed Mar 23 12:10:44 2016 +0300 +++ b/njs/njs_string.h Wed Mar 23 15:27:10 2016 +0300 @@ -55,7 +55,7 @@ * 3) if the length is less than NJS_STRING_MAP_OFFSET. * * The current implementation does not support Unicode surrogate pairs. - * If offset in map points to surrogate pair, it the previous offset + * If offset in map points to surrogate pair then the previous offset * should be used and so on until start of the string. */ diff -r 4deb6b538b48 -r 5995bd7637ff njs/njs_vm.c --- a/njs/njs_vm.c Wed Mar 23 12:10:44 2016 +0300 +++ b/njs/njs_vm.c Wed Mar 23 15:27:10 2016 +0300 @@ -133,7 +133,6 @@ const njs_value_t njs_string_nan = const njs_value_t njs_string_string = njs_string("string"); const njs_value_t njs_string_object = njs_string("object"); const njs_value_t njs_string_function = njs_string("function"); -const njs_value_t njs_string_native = njs_string("[native code]"); const njs_value_t njs_exception_syntax_error = njs_string("SyntaxError"); const njs_value_t njs_exception_reference_error = njs_string("ReferenceError"); diff -r 4deb6b538b48 -r 5995bd7637ff njs/njs_vm.h --- a/njs/njs_vm.h Wed Mar 23 12:10:44 2016 +0300 +++ b/njs/njs_vm.h Wed Mar 23 15:27:10 2016 +0300 @@ -41,7 +41,10 @@ #define NJS_APPLIED NXT_DONE -/* The order of the enum is used in njs_vmcode_typeof() */ +/* + * The order of the enum is used in njs_vmcode_typeof() + * and njs_object_prototype_to_string(). + */ typedef enum { NJS_NULL = 0x00, diff -r 4deb6b538b48 -r 5995bd7637ff njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Mar 23 12:10:44 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Mar 23 15:27:10 2016 +0300 @@ -404,6 +404,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("'3' -+-+-+ '1' + '1' / '3' * '6' + '2'"), nxt_string("42") }, + { nxt_string("((+!![])+(+!![])+(+!![])+(+!![])+[])+((+!![])+(+!![])+[])"), + nxt_string("42") }, + + { nxt_string("1+[[]+[]]-[]+[[]-[]]-1"), + nxt_string("9") }, + + { nxt_string("[[]+[]]-[]+[[]-[]]"), + nxt_string("00") }, + { nxt_string("'true' == true"), nxt_string("false") }, @@ -3796,6 +3805,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("Function.constructor === Function"), nxt_string("true") }, + { nxt_string("function f() {} f.__proto__ === Function.prototype"), + nxt_string("true") }, + { nxt_string("RegExp()"), nxt_string("/(?:)/") }, @@ -3823,6 +3835,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("RegExp.constructor === Function"), nxt_string("true") }, + { nxt_string("/./.__proto__ === RegExp.prototype"), + nxt_string("true") }, + { nxt_string("Object.prototype.toString.call()"), nxt_string("[object Undefined]") }, diff -r 4deb6b538b48 -r 5995bd7637ff nxt/test/lvlhsh_unit_test.c --- a/nxt/test/lvlhsh_unit_test.c Wed Mar 23 12:10:44 2016 +0300 +++ b/nxt/test/lvlhsh_unit_test.c Wed Mar 23 15:27:10 2016 +0300 @@ -193,16 +193,16 @@ static const nxt_mem_proto_t mem_cache_ static nxt_int_t lvlhsh_unit_test(nxt_uint_t n) { - uintptr_t key; + uintptr_t key; nxt_uint_t i; nxt_lvlhsh_t lh; nxt_lvlhsh_each_t lhe; nxt_mem_cache_pool_t *pool; - const size_t min_chunk_size = 32; - const size_t page_size = 1024; - const size_t page_alignment = 128; - const size_t cluster_size = 4096; + const size_t min_chunk_size = 32; + const size_t page_size = 1024; + const size_t page_alignment = 128; + const size_t cluster_size = 4096; pool = nxt_mem_cache_pool_create(&mem_cache_pool_proto, NULL, NULL, cluster_size, page_alignment, diff -r 4deb6b538b48 -r 5995bd7637ff nxt/test/rbtree_unit_test.c --- a/nxt/test/rbtree_unit_test.c Wed Mar 23 12:10:44 2016 +0300 +++ b/nxt/test/rbtree_unit_test.c Wed Mar 23 15:27:10 2016 +0300 @@ -16,7 +16,7 @@ typedef struct { NXT_RBTREE_NODE (node); - uint32_t key; + uint32_t key; } nxt_rbtree_test_t; @@ -30,8 +30,8 @@ static int nxt_cdecl rbtree_unit_test_so static nxt_int_t rbtree_unit_test(nxt_uint_t n) { - void *mark; - uint32_t key, *keys; + void *mark; + uint32_t key, *keys; nxt_uint_t i; nxt_rbtree_t tree; nxt_rbtree_node_t *node; diff -r 4deb6b538b48 -r 5995bd7637ff nxt/test/utf8_unit_test.c --- a/nxt/test/utf8_unit_test.c Wed Mar 23 12:10:44 2016 +0300 +++ b/nxt/test/utf8_unit_test.c Wed Mar 23 15:27:10 2016 +0300 @@ -49,7 +49,7 @@ utf8_overlong(u_char *overlong, size_t l u_char *p, utf8[4]; size_t size; uint32_t u, d; - nxt_uint_t i; + nxt_uint_t i; const u_char *pp; pp = overlong; @@ -88,7 +88,7 @@ utf8_unit_test(void) size_t len; int32_t n; uint32_t u, d; - nxt_uint_t i, k, l, m; + nxt_uint_t i, k, l, m; const u_char *pp; printf("utf8 unit test started\n"); @@ -175,9 +175,9 @@ utf8_unit_test(void) } n = nxt_utf8_casecmp((u_char *) "ABC ??? ???", - (u_char *) "abc ??? ???", - sizeof("ABC ??? ???") - 1, - sizeof("abc ??? ???") - 1); + (u_char *) "abc ??? ???", + sizeof("ABC ??? ???") - 1, + sizeof("abc ??? ???") - 1); if (n != 0) { printf("nxt_utf8_casecmp() failed\n"); From igor at sysoev.ru Thu Mar 24 15:16:58 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 24 Mar 2016 15:16:58 +0000 Subject: [njs] Math object. Message-ID: details: http://hg.nginx.org/njs/rev/e3bc4f6f3480 branches: changeset: 86:e3bc4f6f3480 user: Igor Sysoev date: Wed Mar 23 15:27:14 2016 +0300 description: Math object. diffstat: Makefile | 14 + njs/njs_array.c | 1 + njs/njs_builtin.c | 22 +- njs/njs_disassembler.c | 4 +- njs/njs_function.c | 15 +- njs/njs_generator.c | 42 +++- njs/njs_lexer_keyword.c | 1 + njs/njs_math.c | 554 +++++++++++++++++++++++++++++++++++++++++++++++ njs/njs_math.h | 17 + njs/njs_object.c | 28 ++- njs/njs_object.h | 2 + njs/njs_parser.c | 37 +++- njs/njs_parser.h | 4 + njs/njs_regexp.c | 1 + njs/njs_vm.c | 64 +++-- njs/njs_vm.h | 26 +- njs/test/njs_unit_test.c | 62 +++++ 17 files changed, 841 insertions(+), 53 deletions(-) diffs (truncated from 1256 to 1000 lines): diff -r 5995bd7637ff -r e3bc4f6f3480 Makefile --- a/Makefile Wed Mar 23 15:27:10 2016 +0300 +++ b/Makefile Wed Mar 23 15:27:14 2016 +0300 @@ -18,6 +18,7 @@ NXT_BUILDDIR = build $(NXT_BUILDDIR)/njs_array.o \ $(NXT_BUILDDIR)/njs_function.o \ $(NXT_BUILDDIR)/njs_regexp.o \ + $(NXT_BUILDDIR)/njs_math.o \ $(NXT_BUILDDIR)/njs_extern.o \ $(NXT_BUILDDIR)/njs_variable.o \ $(NXT_BUILDDIR)/njs_builtin.o \ @@ -46,6 +47,7 @@ NXT_BUILDDIR = build $(NXT_BUILDDIR)/njs_array.o \ $(NXT_BUILDDIR)/njs_function.o \ $(NXT_BUILDDIR)/njs_regexp.o \ + $(NXT_BUILDDIR)/njs_math.o \ $(NXT_BUILDDIR)/njs_extern.o \ $(NXT_BUILDDIR)/njs_variable.o \ $(NXT_BUILDDIR)/njs_builtin.o \ @@ -220,6 +222,18 @@ tarball: -I$(NXT_LIB) -Injs $(NXT_PCRE_CFLAGS) \ njs/njs_regexp.c +$(NXT_BUILDDIR)/njs_math.o: \ + $(NXT_BUILDDIR)/libnxt.a \ + njs/njscript.h \ + njs/njs_vm.h \ + njs/njs_object.h \ + njs/njs_math.h \ + njs/njs_math.c \ + + $(NXT_CC) -c -o $(NXT_BUILDDIR)/njs_math.o $(NXT_CFLAGS) \ + -I$(NXT_LIB) -Injs \ + njs/njs_math.c + $(NXT_BUILDDIR)/njs_extern.o: \ $(NXT_BUILDDIR)/libnxt.a \ njs/njscript.h \ diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_array.c --- a/njs/njs_array.c Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_array.c Wed Mar 23 15:27:14 2016 +0300 @@ -129,6 +129,7 @@ njs_array_alloc(njs_vm_t *vm, uint32_t l nxt_lvlhsh_init(&array->object.hash); nxt_lvlhsh_init(&array->object.shared_hash); array->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_ARRAY]; + array->object.shared = 0; array->size = size; array->length = length; diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_builtin.c --- a/njs/njs_builtin.c Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_builtin.c Wed Mar 23 15:27:14 2016 +0300 @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -33,7 +34,7 @@ njs_builtin_objects_create(njs_vm_t *vm) { nxt_int_t ret; nxt_uint_t i; - njs_object_t *prototypes; + njs_object_t *objects, *prototypes; njs_function_t *functions; static const njs_object_init_t *prototype_init[] = { @@ -71,6 +72,10 @@ njs_builtin_objects_create(njs_vm_t *vm) { njs_eval_function, { 0 } }, }; + static const njs_object_init_t *objects_init[] = { + &njs_math_object_init, + }; + static const njs_object_prop_t null_proto_property = { .type = NJS_WHITEOUT, .name = njs_string("__proto__"), @@ -83,6 +88,19 @@ njs_builtin_objects_create(njs_vm_t *vm) return NXT_ERROR; } + objects = vm->shared->objects; + + for (i = NJS_OBJECT_MATH; i < NJS_OBJECT_MAX; i++) { + ret = njs_object_hash_create(vm, &objects[i].shared_hash, + objects_init[i]->properties, + objects_init[i]->items); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + objects[i].shared = 1; + } + prototypes = vm->shared->prototypes; for (i = NJS_PROTOTYPE_OBJECT; i < NJS_PROTOTYPE_MAX; i++) { @@ -99,9 +117,9 @@ njs_builtin_objects_create(njs_vm_t *vm) functions = vm->shared->functions; for (i = NJS_FUNCTION_OBJECT; i < NJS_FUNCTION_MAX; i++) { + functions[i].object.shared = 0; functions[i].native = 1; functions[i].args_offset = 1; - functions[i].shared = 0; functions[i].u.native = native_functions[i].native; functions[i].args_types[0] = native_functions[i].args_types[0]; functions[i].args_types[1] = native_functions[i].args_types[1]; diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_disassembler.c --- a/njs/njs_disassembler.c Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_disassembler.c Wed Mar 23 15:27:14 2016 +0300 @@ -35,10 +35,10 @@ static njs_code_name_t code_names[] = { nxt_string("OBJECT ") }, { njs_vmcode_function, sizeof(njs_vmcode_function_t), nxt_string("FUNCTION ") }, - { njs_vmcode_function_copy, sizeof(njs_vmcode_function_copy_t), - nxt_string("FUNCTION COPY ") }, { njs_vmcode_regexp, sizeof(njs_vmcode_regexp_t), nxt_string("REGEXP ") }, + { njs_vmcode_object_copy, sizeof(njs_vmcode_object_copy_t), + nxt_string("OBJECT COPY ") }, { njs_vmcode_property_get, sizeof(njs_vmcode_prop_get_t), nxt_string("PROPERTY GET ") }, diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_function.c --- a/njs/njs_function.c Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_function.c Wed Mar 23 15:27:14 2016 +0300 @@ -31,8 +31,15 @@ njs_function_alloc(njs_vm_t *vm) function = nxt_mem_cache_zalloc(vm->mem_cache_pool, sizeof(njs_function_t)); if (nxt_fast_path(function != NULL)) { + /* + * nxt_mem_cache_zalloc() does also: + * nxt_lvlhsh_init(&function->object.hash); + * nxt_lvlhsh_init(&function->object.shared_hash); + * function->object.__proto__ = NULL; + */ + + function->object.shared = 1; function->args_offset = 1; - function->shared = 1; function->u.lambda = nxt_mem_cache_zalloc(vm->mem_cache_pool, sizeof(njs_function_lambda_t)); @@ -52,7 +59,7 @@ njs_function_value_copy(njs_vm_t *vm, nj function = value->data.u.function; - if (!function->shared) { + if (!function->object.shared) { return function; } @@ -61,7 +68,7 @@ njs_function_value_copy(njs_vm_t *vm, nj if (nxt_fast_path(function != NULL)) { *function = *value->data.u.function; function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION]; - function->shared = 0; + function->object.shared = 0; value->data.u.function = function; } @@ -458,7 +465,7 @@ njs_function_prototype_bind(njs_vm_t *vm *function = *args[0].data.u.function; function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION]; - function->shared = 0; + function->object.shared = 0; if (nargs == 1) { args = (njs_value_t *) &njs_value_void; diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_generator.c --- a/njs/njs_generator.c Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_generator.c Wed Mar 23 15:27:14 2016 +0300 @@ -25,6 +25,8 @@ static nxt_int_t njs_generator(njs_vm_t njs_parser_node_t *node); static nxt_int_t njs_generate_name(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node); +static nxt_int_t njs_generate_builtin_object(njs_vm_t *vm, njs_parser_t *parser, + njs_parser_node_t *node); static nxt_int_t njs_generate_variable(njs_parser_t *parser, njs_parser_node_t *node); static nxt_int_t njs_generate_if_statement(njs_vm_t *vm, njs_parser_t *parser, @@ -289,6 +291,9 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_NAME: return njs_generate_name(vm, parser, node); + case NJS_TOKEN_MATH: + return njs_generate_builtin_object(vm, parser, node); + case NJS_TOKEN_FUNCTION: return njs_generate_function_declaration(vm, parser, node); @@ -319,9 +324,9 @@ njs_generator(njs_vm_t *vm, njs_parser_t static nxt_int_t njs_generate_name(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node) { - njs_index_t index; - njs_value_t *value; - njs_vmcode_function_copy_t *copy; + njs_index_t index; + njs_value_t *value; + njs_vmcode_object_copy_t *copy; index = node->u.variable->index; value = njs_variable_value(parser, index); @@ -333,12 +338,12 @@ njs_generate_name(njs_vm_t *vm, njs_pars return node->index; } - njs_generate_code(parser, njs_vmcode_function_copy_t, copy); - copy->code.operation = njs_vmcode_function_copy; + njs_generate_code(parser, njs_vmcode_object_copy_t, copy); + copy->code.operation = njs_vmcode_object_copy; copy->code.operands = NJS_VMCODE_2OPERANDS; copy->code.retval = NJS_VMCODE_RETVAL; copy->retval = node->index; - copy->function = index; + copy->object = index; return NXT_OK; } @@ -348,6 +353,31 @@ njs_generate_name(njs_vm_t *vm, njs_pars static nxt_int_t +njs_generate_builtin_object(njs_vm_t *vm, njs_parser_t *parser, + njs_parser_node_t *node) +{ + njs_index_t index; + njs_vmcode_object_copy_t *copy; + + index = node->index; + + node->index = njs_generator_dest_index(vm, parser, node); + if (nxt_slow_path(node->index == NJS_INDEX_ERROR)) { + return node->index; + } + + njs_generate_code(parser, njs_vmcode_object_copy_t, copy); + copy->code.operation = njs_vmcode_object_copy; + copy->code.operands = NJS_VMCODE_2OPERANDS; + copy->code.retval = NJS_VMCODE_RETVAL; + copy->retval = node->index; + copy->object = index; + + return NXT_OK; +} + + +static nxt_int_t njs_generate_variable(njs_parser_t *parser, njs_parser_node_t *node) { njs_value_t *value; diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_lexer_keyword.c Wed Mar 23 15:27:14 2016 +0300 @@ -73,6 +73,7 @@ static const njs_keyword_t njs_keywords /* Builtin objects. */ { nxt_string("this"), NJS_TOKEN_THIS, 0 }, + { nxt_string("Math"), NJS_TOKEN_MATH, 0 }, /* Builtin functions. */ diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_math.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/njs/njs_math.c Wed Mar 23 15:27:14 2016 +0300 @@ -0,0 +1,554 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static njs_ret_t +njs_object_math_abs(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, fabs(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_acos(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, acos(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_asin(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, asin(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_atan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, atan(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_atan2(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double y, x; + + y = NJS_NAN; + x = NJS_NAN; + + if (nargs > 1) { + y = args[1].data.u.number; + } + + if (nargs > 2) { + x = args[2].data.u.number; + } + + njs_number_set(&vm->retval, atan2(y, x)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_ceil(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, ceil(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_cos(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, cos(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_exp(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, exp(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_floor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, floor(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_log(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, log(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_max(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + nxt_uint_t i; + + if (nargs > 1) { + for (i = 1; i < nargs; i++) { + if (!njs_is_numeric(&args[i])) { + vm->frame->trap_scratch.data.u.value = &args[i]; + return NJS_TRAP_NUMBER_ARG; + } + } + + num = args[1].data.u.number; + + for (i = 2; i < nargs; i++) { + num = fmax(num, args[i].data.u.number); + } + + } else { + num = -NJS_INFINITY; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_min(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + nxt_uint_t i; + + if (nargs > 1) { + for (i = 1; i < nargs; i++) { + if (!njs_is_numeric(&args[i])) { + vm->frame->trap_scratch.data.u.value = &args[i]; + return NJS_TRAP_NUMBER_ARG; + } + } + + num = args[1].data.u.number; + + for (i = 2; i < nargs; i++) { + num = fmin(num, args[i].data.u.number); + } + + } else { + num = NJS_INFINITY; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_pow(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double base, exponent; + + base = NJS_NAN; + exponent = NJS_NAN; + + if (nargs > 1) { + base = args[1].data.u.number; + } + + if (nargs > 2) { + exponent = args[2].data.u.number; + } + + njs_number_set(&vm->retval, pow(base, exponent)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_round(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, round(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_sin(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, sin(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_sqrt(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, sqrt(num)); + + return NXT_OK; +} + + +static njs_ret_t +njs_object_math_tan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + if (nargs > 1) { + num = args[1].data.u.number; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, tan(num)); + + return NXT_OK; +} + + +static const njs_object_prop_t njs_math_object_properties[] = +{ + { + .type = NJS_PROPERTY, + .name = njs_string("E"), + .value = njs_value(NJS_NUMBER, 1, 2.718281828459045), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("LN10"), + .value = njs_value(NJS_NUMBER, 1, 2.302585092994046), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("LN2"), + .value = njs_value(NJS_NUMBER, 1, 0.6931471805599453), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("LOG10E"), + .value = njs_value(NJS_NUMBER, 1, 0.4342944819032518), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("LOG2E"), + .value = njs_value(NJS_NUMBER, 1, 1.4426950408889634), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("PI"), + .value = njs_value(NJS_NUMBER, 1, 3.141592653589793), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("SQRT1_2"), + .value = njs_value(NJS_NUMBER, 1, 0.7071067811865476), + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("SQRT2"), + .value = njs_value(NJS_NUMBER, 1, 1.4142135623730951), + }, + + { + .type = NJS_NATIVE_GETTER, + .name = njs_string("__proto__"), + .value = njs_native_getter(njs_object_prototype_get_proto), + }, + + { + .type = NJS_METHOD, + .name = njs_string("abs"), + .value = njs_native_function(njs_object_math_abs, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("acos"), + .value = njs_native_function(njs_object_math_acos, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("asin"), + .value = njs_native_function(njs_object_math_asin, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("atan"), + .value = njs_native_function(njs_object_math_atan, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("atan2"), + .value = njs_native_function(njs_object_math_atan2, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("ceil"), + .value = njs_native_function(njs_object_math_ceil, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("cos"), + .value = njs_native_function(njs_object_math_cos, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("exp"), + .value = njs_native_function(njs_object_math_exp, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("floor"), + .value = njs_native_function(njs_object_math_floor, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("log"), + .value = njs_native_function(njs_object_math_log, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("max"), + .value = njs_native_function(njs_object_math_max, 0, 0), + }, + + { + .type = NJS_METHOD, + .name = njs_string("min"), + .value = njs_native_function(njs_object_math_min, 0, 0), + }, + + { + .type = NJS_METHOD, + .name = njs_string("pow"), + .value = njs_native_function(njs_object_math_pow, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("round"), + .value = njs_native_function(njs_object_math_round, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("sin"), + .value = njs_native_function(njs_object_math_sin, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("sqrt"), + .value = njs_native_function(njs_object_math_sqrt, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + + { + .type = NJS_METHOD, + .name = njs_string("tan"), + .value = njs_native_function(njs_object_math_tan, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, +}; + + +const njs_object_init_t njs_math_object_init = { + njs_math_object_properties, + nxt_nitems(njs_math_object_properties), +}; diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_math.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/njs/njs_math.h Wed Mar 23 15:27:14 2016 +0300 @@ -0,0 +1,17 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NJS_MATH_H_INCLUDED_ +#define _NJS_MATH_H_INCLUDED_ + + +#include + + +extern const njs_object_init_t njs_math_object_init; + + +#endif /* _NJS_MATH_H_INCLUDED_ */ diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_object.c --- a/njs/njs_object.c Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_object.c Wed Mar 23 15:27:14 2016 +0300 @@ -34,6 +34,31 @@ njs_object_alloc(njs_vm_t *vm) nxt_lvlhsh_init(&object->hash); nxt_lvlhsh_init(&object->shared_hash); object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT]; + object->shared = 0; + } + + return object; +} + + +njs_object_t * +njs_object_value_copy(njs_vm_t *vm, njs_value_t *value) +{ + njs_object_t *object; + + object = value->data.u.object; + + if (!object->shared) { + return object; + } + + object = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_object_t)); + + if (nxt_fast_path(object != NULL)) { + *object = *value->data.u.object; + object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT]; + object->shared = 0; + value->data.u.object = object; } return object; @@ -51,6 +76,7 @@ njs_object_value_alloc(njs_vm_t *vm, con if (nxt_fast_path(ov != NULL)) { nxt_lvlhsh_init(&ov->object.hash); nxt_lvlhsh_init(&ov->object.shared_hash); + ov->object.shared = 0; index = njs_primitive_prototype_index(type); ov->object.__proto__ = &vm->prototypes[index]; @@ -413,7 +439,7 @@ const njs_object_init_t njs_object_cons }; -static njs_ret_t +njs_ret_t njs_object_prototype_get_proto(njs_vm_t *vm, njs_value_t *value) { njs_object_t *proto; diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_object.h --- a/njs/njs_object.h Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_object.h Wed Mar 23 15:27:14 2016 +0300 @@ -44,6 +44,7 @@ struct njs_object_init_s { njs_object_t *njs_object_alloc(njs_vm_t *vm); +njs_object_t *njs_object_value_copy(njs_vm_t *vm, njs_value_t *value); njs_object_t *njs_object_value_alloc(njs_vm_t *vm, const njs_value_t *value, nxt_uint_t type); njs_object_prop_t *njs_object_property(njs_vm_t *vm, njs_object_t *obj, @@ -55,6 +56,7 @@ njs_ret_t njs_object_constructor(njs_vm_ njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name); njs_ret_t njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_value_t *value); njs_ret_t njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value); +njs_ret_t njs_object_prototype_get_proto(njs_vm_t *vm, njs_value_t *value); njs_ret_t njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_parser.c --- a/njs/njs_parser.c Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_parser.c Wed Mar 23 15:27:14 2016 +0300 @@ -68,6 +68,8 @@ static njs_token_t njs_parser_throw_stat njs_parser_t *parser); static njs_token_t njs_parser_grouping_expression(njs_vm_t *vm, njs_parser_t *parser); +static njs_token_t njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser, + njs_parser_node_t *node); static njs_token_t njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj); static njs_token_t njs_parser_array(njs_vm_t *vm, njs_parser_t *parser, @@ -1470,7 +1472,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa break; } - parser->code_size += sizeof(njs_vmcode_function_copy_t); + parser->code_size += sizeof(njs_vmcode_object_copy_t); node->lvalue = NJS_LVALUE_ENABLED; node->u.variable = var; break; @@ -1588,6 +1590,9 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa node->index = NJS_INDEX_THIS; break; + case NJS_TOKEN_MATH: + return njs_parser_builtin_object(vm, parser, node); + case NJS_TOKEN_OBJECT_CONSTRUCTOR: node->index = NJS_INDEX_OBJECT; break; @@ -1632,6 +1637,36 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa static njs_token_t +njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser, + njs_parser_node_t *node) +{ + nxt_uint_t index, level; + njs_value_t *value; + njs_variable_t *var; + + var = njs_parser_variable(vm, parser, &level); + if (nxt_slow_path(var == NULL)) { + return NJS_TOKEN_ERROR; + } + + var->state = NJS_VARIABLE_DECLARED; + node->index = var->index; + + value = njs_variable_value(parser, node->index); + + index = node->token - NJS_TOKEN_FIRST_OBJECT; + value->data.u.object = &vm->shared->objects[index]; + value->type = NJS_OBJECT; + value->data.truth = 1; + + parser->node = node; + parser->code_size += sizeof(njs_vmcode_object_copy_t); + + return njs_lexer_token(parser->lexer); +} + + +static njs_token_t njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj) { njs_token_t token; diff -r 5995bd7637ff -r e3bc4f6f3480 njs/njs_parser.h --- a/njs/njs_parser.h Wed Mar 23 15:27:10 2016 +0300 +++ b/njs/njs_parser.h Wed Mar 23 15:27:14 2016 +0300 @@ -159,6 +159,10 @@ typedef enum { NJS_TOKEN_THIS, +#define NJS_TOKEN_FIRST_OBJECT NJS_TOKEN_MATH + + NJS_TOKEN_MATH, + NJS_TOKEN_OBJECT_CONSTRUCTOR, NJS_TOKEN_ARRAY_CONSTRUCTOR, NJS_TOKEN_FUNCTION_CONSTRUCTOR, From igor at sysoev.ru Thu Mar 24 15:16:59 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 24 Mar 2016 15:16:59 +0000 Subject: [njs] Math.random() method. Message-ID: details: http://hg.nginx.org/njs/rev/7ad8820b9c74 branches: changeset: 87:7ad8820b9c74 user: Igor Sysoev date: Wed Mar 23 15:49:46 2016 +0300 description: Math.random() method. diffstat: Makefile | 6 +- njs/njs_array.c | 1 + njs/njs_boolean.c | 1 + njs/njs_builtin.c | 1 + njs/njs_disassembler.c | 1 + njs/njs_extern.c | 1 + njs/njs_function.c | 1 + njs/njs_generator.c | 1 + njs/njs_lexer.c | 1 + njs/njs_lexer_keyword.c | 1 + njs/njs_math.c | 21 ++++ njs/njs_nonrecursive_parser.c | 1 + njs/njs_number.c | 15 ++- njs/njs_object.c | 1 + njs/njs_parser.c | 1 + njs/njs_parser_expression.c | 1 + njs/njs_regexp.c | 1 + njs/njs_string.c | 1 + njs/njs_variable.c | 1 + njs/njs_vm.c | 1 + njs/njs_vm.h | 2 + njs/njscript.c | 1 + njs/test/njs_unit_test.c | 9 +- nxt/Makefile | 12 ++ nxt/auto/configure | 1 + nxt/auto/getrandom | 24 +++++ nxt/nxt_random.c | 179 ++++++++++++++++++++++++++++++++++++++++++ nxt/nxt_random.h | 37 ++++++++ nxt/nxt_types.h | 3 + nxt/test/Makefile | 11 ++ nxt/test/random_unit_test.c | 60 ++++++++++++++ 31 files changed, 387 insertions(+), 11 deletions(-) diffs (757 lines): diff -r e3bc4f6f3480 -r 7ad8820b9c74 Makefile --- a/Makefile Wed Mar 23 15:27:14 2016 +0300 +++ b/Makefile Wed Mar 23 15:49:46 2016 +0300 @@ -34,6 +34,7 @@ NXT_BUILDDIR = build $(NXT_BUILDDIR)/nxt_array.o \ $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ + $(NXT_BUILDDIR)/nxt_random.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ @@ -63,6 +64,7 @@ NXT_BUILDDIR = build $(NXT_BUILDDIR)/nxt_array.o \ $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ + $(NXT_BUILDDIR)/nxt_random.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ @@ -370,12 +372,14 @@ tarball: njs/njs_disassembler.c $(NXT_BUILDDIR)/njs_unit_test: \ + $(NXT_BUILDDIR)/libnxt.a \ $(NXT_BUILDDIR)/libnjs.a \ njs/test/njs_unit_test.c \ $(NXT_CC) -o $(NXT_BUILDDIR)/njs_unit_test $(NXT_CFLAGS) \ -I$(NXT_LIB) -Injs \ njs/test/njs_unit_test.c \ - $(NXT_BUILDDIR)/libnjs.a -lm $(NXT_PCRE_LIB) + $(NXT_BUILDDIR)/libnjs.a \ + -lm $(NXT_PCRE_LIB) include $(NXT_LIB)/Makefile diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_array.c --- a/njs/njs_array.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_array.c Wed Mar 23 15:49:46 2016 +0300 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_boolean.c --- a/njs/njs_boolean.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_boolean.c Wed Mar 23 15:49:46 2016 +0300 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_builtin.c --- a/njs/njs_builtin.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_builtin.c Wed Mar 23 15:49:46 2016 +0300 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_disassembler.c --- a/njs/njs_disassembler.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_disassembler.c Wed Mar 23 15:49:46 2016 +0300 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_extern.c --- a/njs/njs_extern.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_extern.c Wed Mar 23 15:49:46 2016 +0300 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_function.c --- a/njs/njs_function.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_function.c Wed Mar 23 15:49:46 2016 +0300 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_generator.c --- a/njs/njs_generator.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_generator.c Wed Mar 23 15:49:46 2016 +0300 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_lexer.c --- a/njs/njs_lexer.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_lexer.c Wed Mar 23 15:49:46 2016 +0300 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_lexer_keyword.c Wed Mar 23 15:49:46 2016 +0300 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_math.c --- a/njs/njs_math.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_math.c Wed Mar 23 15:49:46 2016 +0300 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -298,6 +299,20 @@ njs_object_math_pow(njs_vm_t *vm, njs_va static njs_ret_t +njs_object_math_random(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + num = nxt_random(&vm->random) / 4294967296.0; + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_round(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -520,6 +535,12 @@ static const njs_object_prop_t njs_math { .type = NJS_METHOD, + .name = njs_string("random"), + .value = njs_native_function(njs_object_math_random, 0, ), + }, + + { + .type = NJS_METHOD, .name = njs_string("round"), .value = njs_native_function(njs_object_math_round, 0, NJS_SKIP_ARG, NJS_NUMBER_ARG), diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_nonrecursive_parser.c --- a/njs/njs_nonrecursive_parser.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_nonrecursive_parser.c Wed Mar 23 15:49:46 2016 +0300 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_number.c --- a/njs/njs_number.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_number.c Wed Mar 23 15:49:46 2016 +0300 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -163,7 +164,7 @@ njs_number_to_string(njs_vm_t *vm, njs_v const njs_value_t *number) { u_char *p; - double num; + double n, num; size_t size; const char *fmt; const njs_value_t *value; @@ -184,10 +185,18 @@ njs_number_to_string(njs_vm_t *vm, njs_v } } else { - if (fabs(num) < 1000000) { + n = fabs(num); + + if (n == 0) { fmt = "%g"; - } else if (fabs(num) < 1e20) { + } else if (n < 1) { + fmt = "%f"; + + } else if (n < 1000000) { + fmt = "%g"; + + } else if (n < 1e20) { fmt = "%1.f"; } else { diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_object.c --- a/njs/njs_object.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_object.c Wed Mar 23 15:49:46 2016 +0300 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_parser.c --- a/njs/njs_parser.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_parser.c Wed Mar 23 15:49:46 2016 +0300 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_parser_expression.c Wed Mar 23 15:49:46 2016 +0300 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_regexp.c --- a/njs/njs_regexp.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_regexp.c Wed Mar 23 15:49:46 2016 +0300 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_string.c --- a/njs/njs_string.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_string.c Wed Mar 23 15:49:46 2016 +0300 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_variable.c --- a/njs/njs_variable.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_variable.c Wed Mar 23 15:49:46 2016 +0300 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_vm.c --- a/njs/njs_vm.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_vm.c Wed Mar 23 15:49:46 2016 +0300 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njs_vm.h --- a/njs/njs_vm.h Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njs_vm.h Wed Mar 23 15:49:46 2016 +0300 @@ -774,6 +774,8 @@ struct njs_vm_s { njs_regexp_pattern_t *pattern; nxt_array_t *code; /* of njs_vm_code_t */ + + nxt_random_t random; }; diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/njscript.c --- a/njs/njscript.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/njscript.c Wed Mar 23 15:49:46 2016 +0300 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff -r e3bc4f6f3480 -r 7ad8820b9c74 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Mar 23 15:27:14 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Mar 23 15:49:46 2016 +0300 @@ -3919,12 +3919,6 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.PI"), nxt_string("3.14159") }, - { nxt_string("Math.E"), - nxt_string("2.71828") }, - - { nxt_string("Math.SQRT2"), - nxt_string("1.41421") }, - { nxt_string("Math.abs(5)"), nxt_string("5") }, @@ -3970,7 +3964,8 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.pow()"), nxt_string("NaN") }, - /* ES5: Must be "[object Math]". */ + /* ES5FIX: "[object Math]". */ + { nxt_string("Math"), nxt_string("[object Object]") }, diff -r e3bc4f6f3480 -r 7ad8820b9c74 nxt/Makefile --- a/nxt/Makefile Wed Mar 23 15:27:14 2016 +0300 +++ b/nxt/Makefile Wed Mar 23 15:49:46 2016 +0300 @@ -9,6 +9,7 @@ NXT_LIB = nxt $(NXT_BUILDDIR)/nxt_queue.o \ $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ + $(NXT_BUILDDIR)/nxt_random.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ @@ -19,6 +20,7 @@ NXT_LIB = nxt $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ + $(NXT_BUILDDIR)/nxt_random.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ $(NXT_BUILDDIR)/nxt_murmur_hash.o: \ @@ -102,6 +104,16 @@ NXT_LIB = nxt -I$(NXT_LIB) \ $(NXT_LIB)/nxt_malloc.c +$(NXT_BUILDDIR)/nxt_random.o: \ + $(NXT_LIB)/nxt_types.h \ + $(NXT_LIB)/nxt_clang.h \ + $(NXT_LIB)/nxt_random.h \ + $(NXT_LIB)/nxt_random.c \ + + $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_random.o $(NXT_CFLAGS) \ + -I$(NXT_LIB) \ + $(NXT_LIB)/nxt_random.c + $(NXT_BUILDDIR)/nxt_mem_cache_pool.o: \ $(NXT_LIB)/nxt_types.h \ $(NXT_LIB)/nxt_clang.h \ diff -r e3bc4f6f3480 -r 7ad8820b9c74 nxt/auto/configure --- a/nxt/auto/configure Wed Mar 23 15:27:14 2016 +0300 +++ b/nxt/auto/configure Wed Mar 23 15:49:46 2016 +0300 @@ -52,4 +52,5 @@ END . ${NXT_AUTO}os . ${NXT_AUTO}clang . ${NXT_AUTO}memalign +. ${NXT_AUTO}getrandom . ${NXT_AUTO}pcre diff -r e3bc4f6f3480 -r 7ad8820b9c74 nxt/auto/getrandom --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/auto/getrandom Wed Mar 23 15:49:46 2016 +0300 @@ -0,0 +1,24 @@ + +# Copyright (C) Igor Sysoev +# Copyright (C) NGINX, Inc. + + +# Linux 3.17 getrandom(). + +nxt_feature="getrandom()" +nxt_feature_name=NXT_HAVE_GETRANDOM +nxt_feature_run= +nxt_feature_incs= +nxt_feature_libs= +nxt_feature_test="#include + #include + #include + + int main() { + char buf[4]; + + (void) syscall(SYS_getrandom, buf, 4, 0); + + return 0; + }" +. ${NXT_AUTO}feature diff -r e3bc4f6f3480 -r 7ad8820b9c74 nxt/nxt_random.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_random.c Wed Mar 23 15:49:46 2016 +0300 @@ -0,0 +1,179 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + + +#include +#include +#include +#include +#include +#include +#if (NXT_HAVE_GETRANDOM) +#include +#include +#endif + + +/* + * The pseudorandom generator based on OpenBSD arc4random. Although + * it is usually stated that arc4random uses RC4 pseudorandom generation + * algorithm they are actually different in nxt_random_add(). + */ + + +#define NXT_RANDOM_KEY_SIZE 128 + + +nxt_inline uint8_t nxt_random_byte(nxt_random_t *r); + + +void +nxt_random_init(nxt_random_t *r, nxt_pid_t pid) +{ + nxt_uint_t i; + + r->count = 0; + r->pid = pid; + r->i = 0; + r->j = 0; + + for (i = 0; i < 256; i++) { + r->s[i] = i; + } +} + + +void +nxt_random_stir(nxt_random_t *r, nxt_pid_t pid) +{ + int fd; + ssize_t n; + struct timeval tv; + union { + uint32_t value[3]; + u_char bytes[NXT_RANDOM_KEY_SIZE]; + } key; + + if (r->pid == 0) { + nxt_random_init(r, pid); + } + + r->pid = pid; + + n = 0; + +#if (NXT_HAVE_GETRANDOM) + + /* Linux 3.17 getrandom(), it is not available in Glibc. */ + + n = syscall(SYS_getrandom, key, NXT_RANDOM_KEY_SIZE, 0)); + +#endif + + if (n != NXT_RANDOM_KEY_SIZE) { + fd = open("/dev/urandom", O_RDONLY); + + if (fd >= 0) { + n = read(fd, &key, NXT_RANDOM_KEY_SIZE); + (void) close(fd); + } + } + + if (n != NXT_RANDOM_KEY_SIZE) { + (void) gettimeofday(&tv, NULL); + + /* XOR with stack garbage. */ + + key.value[0] ^= tv.tv_usec; + key.value[1] ^= tv.tv_sec; + key.value[2] ^= getpid(); + } + + nxt_random_add(r, key.bytes, NXT_RANDOM_KEY_SIZE); + + /* Drop the first 3072 bytes. */ + for (n = 3072; n != 0; n--) { + (void) nxt_random_byte(r); + } + + /* Stir again after 1,600,000 bytes. */ + r->count = 400000; +} + + +void +nxt_random_add(nxt_random_t *r, const u_char *key, uint32_t len) +{ + uint8_t val; + uint32_t n; + + for (n = 0; n < 256; n++) { + val = r->s[r->i]; + r->j += val + key[n % len]; + + r->s[r->i] = r->s[r->j]; + r->s[r->j] = val; + + r->i++; + } + + /* This index is not decremented in RC4 algorithm. */ + r->i--; + + r->j = r->i; +} + + +uint32_t +nxt_random(nxt_random_t *r) +{ + uint32_t val; + nxt_pid_t pid; + nxt_bool_t new_pid; + + new_pid = 0; + pid = r->pid; + + if (pid != -1) { + pid = getpid(); + + if (pid != r->pid) { + new_pid = 1; + } + } + + r->count--; + + if (r->count <= 0 || new_pid) { + nxt_random_stir(r, pid); + } + + val = nxt_random_byte(r) << 24; + val |= nxt_random_byte(r) << 16; + val |= nxt_random_byte(r) << 8; + val |= nxt_random_byte(r); + + return val; +} + + +nxt_inline uint8_t +nxt_random_byte(nxt_random_t *r) +{ + uint8_t si, sj; + + r->i++; + si = r->s[r->i]; + r->j += si; + + sj = r->s[r->j]; + r->s[r->i] = sj; + r->s[r->j] = si; + + si += sj; + + return r->s[si]; +} diff -r e3bc4f6f3480 -r 7ad8820b9c74 nxt/nxt_random.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_random.h Wed Mar 23 15:49:46 2016 +0300 @@ -0,0 +1,37 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NXT_RANDOM_H_INCLUDED_ +#define _NXT_RANDOM_H_INCLUDED_ + + +typedef struct { + int32_t count; + nxt_pid_t pid; + uint8_t i; + uint8_t j; + uint8_t s[256]; +} nxt_random_t; + + +/* + * The nxt_random_t structure must be either initialized with zeros + * or initialized by nxt_random_init() function. The later is intended + * mainly for unit test. nxt_random() automatically stirs itself if + * process pid changed after fork(). This pid testing can be disabled by + * passing -1 as the pid argument to nxt_random_init() or nxt_random_stir() + * functions. The testing can be later enabled by passing any positive + * number, for example, a real pid number. + */ + +NXT_EXPORT void nxt_random_init(nxt_random_t *r, nxt_pid_t pid); +NXT_EXPORT void nxt_random_stir(nxt_random_t *r, nxt_pid_t pid); +NXT_EXPORT void nxt_random_add(nxt_random_t *r, const u_char *key, + uint32_t len); +NXT_EXPORT uint32_t nxt_random(nxt_random_t *r); + + +#endif /* _NXT_RANDOM_H_INCLUDED_ */ diff -r e3bc4f6f3480 -r 7ad8820b9c74 nxt/nxt_types.h --- a/nxt/nxt_types.h Wed Mar 23 15:27:14 2016 +0300 +++ b/nxt/nxt_types.h Wed Mar 23 15:49:46 2016 +0300 @@ -90,4 +90,7 @@ typedef time_t nxt_time_t; #endif +typedef pid_t nxt_pid_t; + + #endif /* _NXT_TYPES_H_INCLUDED_ */ diff -r e3bc4f6f3480 -r 7ad8820b9c74 nxt/test/Makefile --- a/nxt/test/Makefile Wed Mar 23 15:27:14 2016 +0300 +++ b/nxt/test/Makefile Wed Mar 23 15:49:46 2016 +0300 @@ -1,9 +1,11 @@ lib_test: \ + $(NXT_BUILDDIR)/random_unit_test \ $(NXT_BUILDDIR)/rbtree_unit_test \ $(NXT_BUILDDIR)/lvlhsh_unit_test \ $(NXT_BUILDDIR)/utf8_unit_test \ + $(NXT_BUILDDIR)/random_unit_test $(NXT_BUILDDIR)/rbtree_unit_test $(NXT_BUILDDIR)/lvlhsh_unit_test $(NXT_BUILDDIR)/utf8_unit_test @@ -43,3 +45,12 @@ lib_test: \ $(NXT_BUILDDIR)/nxt_murmur_hash.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ $(NXT_BUILDDIR)/nxt_malloc.o + +$(NXT_BUILDDIR)/random_unit_test: \ + $(NXT_BUILDDIR)/nxt_random.o \ + $(NXT_LIB)/test/random_unit_test.c \ + + $(NXT_CC) -o $(NXT_BUILDDIR)/random_unit_test $(NXT_CFLAGS) \ + -I$(NXT_LIB) \ + $(NXT_LIB)/test/random_unit_test.c \ + $(NXT_BUILDDIR)/nxt_random.o diff -r e3bc4f6f3480 -r 7ad8820b9c74 nxt/test/random_unit_test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/test/random_unit_test.c Wed Mar 23 15:49:46 2016 +0300 @@ -0,0 +1,60 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + + +static nxt_int_t +random_unit_test() +{ + nxt_uint_t n; + nxt_random_t r; + + nxt_random_init(&r, -1); + + r.count = 400000; + + nxt_random_add(&r, (u_char *) "arc4random", sizeof("arc4random") - 1); + + /* + * Test arc4random() numbers. + * RC4 pseudorandom numbers would be 0x4642AFC3 and 0xBAF0FFF0. + */ + + if (nxt_random(&r) == 0xD6270B27) { + + for (n = 100000; n != 0; n--) { + (void) nxt_random(&r); + } + + if (nxt_random(&r) == 0x6FCAE186) { + printf("random unit test passed\n"); + + nxt_random_stir(&r, getpid()); + + printf("random unit test: 0x%08X\n", nxt_random(&r)); + + return NXT_OK; + } + } + + printf("random unit test failed\n"); + + return NXT_ERROR; +} + + +int +main(void) +{ + return random_unit_test(); +} From igor at sysoev.ru Thu Mar 24 15:17:01 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 24 Mar 2016 15:17:01 +0000 Subject: [njs] User defined function prototype. Message-ID: details: http://hg.nginx.org/njs/rev/6e70fe1e0a47 branches: changeset: 88:6e70fe1e0a47 user: Igor Sysoev date: Wed Mar 23 15:49:49 2016 +0300 description: User defined function prototype. diffstat: njs/njs_builtin.c | 18 ++++++-- njs/njs_function.c | 63 ++++++++++++++++++++++++++++- njs/njs_function.h | 3 + njs/njs_object.c | 101 ++++++++++++++++++++++++++++++++-------------- njs/njs_object.h | 4 + njs/njs_vm.c | 45 ++++++++++++++++++++- njs/njs_vm.h | 1 + njs/test/njs_unit_test.c | 14 ++++++ 8 files changed, 209 insertions(+), 40 deletions(-) diffs (438 lines): diff -r 7ad8820b9c74 -r 6e70fe1e0a47 njs/njs_builtin.c --- a/njs/njs_builtin.c Wed Mar 23 15:49:46 2016 +0300 +++ b/njs/njs_builtin.c Wed Mar 23 15:49:49 2016 +0300 @@ -77,18 +77,30 @@ njs_builtin_objects_create(njs_vm_t *vm) &njs_math_object_init, }; - static const njs_object_prop_t null_proto_property = { + static const njs_object_prop_t null_proto_property = { .type = NJS_WHITEOUT, .name = njs_string("__proto__"), .value = njs_value(NJS_NULL, 0, 0.0), }; + static const njs_object_prop_t function_prototype_property = { + .type = NJS_NATIVE_GETTER, + .name = njs_string("prototype"), + .value = njs_native_getter(njs_function_prototype_create), + }; + ret = njs_object_hash_create(vm, &vm->shared->null_proto_hash, &null_proto_property, 1); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } + ret = njs_object_hash_create(vm, &vm->shared->function_prototype_hash, + &function_prototype_property, 1); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + objects = vm->shared->objects; for (i = NJS_OBJECT_MATH; i < NJS_OBJECT_MAX; i++) { @@ -105,8 +117,6 @@ njs_builtin_objects_create(njs_vm_t *vm) prototypes = vm->shared->prototypes; for (i = NJS_PROTOTYPE_OBJECT; i < NJS_PROTOTYPE_MAX; i++) { - /* TODO: shared hash: prototype & constructor getters, methods */ - ret = njs_object_hash_create(vm, &prototypes[i].shared_hash, prototype_init[i]->properties, prototype_init[i]->items); @@ -134,8 +144,6 @@ njs_builtin_objects_create(njs_vm_t *vm) } } - /* TODO: create function shared hash: prototype+contructor getter */ - return NXT_OK; } diff -r 7ad8820b9c74 -r 6e70fe1e0a47 njs/njs_function.c --- a/njs/njs_function.c Wed Mar 23 15:49:46 2016 +0300 +++ b/njs/njs_function.c Wed Mar 23 15:49:49 2016 +0300 @@ -35,10 +35,10 @@ njs_function_alloc(njs_vm_t *vm) /* * nxt_mem_cache_zalloc() does also: * nxt_lvlhsh_init(&function->object.hash); - * nxt_lvlhsh_init(&function->object.shared_hash); * function->object.__proto__ = NULL; */ + function->object.shared_hash = vm->shared->function_prototype_hash; function->object.shared = 1; function->args_offset = 1; @@ -305,6 +305,67 @@ njs_function_call(njs_vm_t *vm, njs_inde } +/* + * The "prototype" property of user defined functions is created on + * demand in private hash of the functions by the "prototype" getter. + * The getter creates a copy of function which is private to nJSVM, + * adds a "prototype" object property to the copy, and then adds a + * "constructor" property in the prototype object. The "constructor" + * property points to the copy of function: + * "F.prototype.constructor === F" + */ + +njs_ret_t +njs_function_prototype_create(njs_vm_t *vm, njs_value_t *value) +{ + njs_value_t *proto; + + proto = njs_function_property_prototype_create(vm, value); + + if (nxt_fast_path(proto != NULL)) { + vm->retval = *proto; + return NXT_OK; + } + + return NXT_ERROR; +} + + +njs_value_t * +njs_function_property_prototype_create(njs_vm_t *vm, njs_value_t *value) +{ + njs_value_t *proto, *cons; + njs_object_t *prototype; + njs_function_t *function; + + prototype = njs_object_alloc(vm); + + if (nxt_slow_path(prototype == NULL)) { + return NULL; + } + + function = njs_function_value_copy(vm, value); + + if (nxt_slow_path(function == NULL)) { + return NULL; + } + + proto = njs_property_prototype_create(vm, &function->object.hash, + prototype); + if (nxt_slow_path(proto == NULL)) { + return NULL; + } + + cons = njs_property_constructor_create(vm, &prototype->hash, value); + + if (nxt_fast_path(cons != NULL)) { + return proto; + } + + return NULL; +} + + njs_ret_t njs_function_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) diff -r 7ad8820b9c74 -r 6e70fe1e0a47 njs/njs_function.h --- a/njs/njs_function.h Wed Mar 23 15:49:46 2016 +0300 +++ b/njs/njs_function.h Wed Mar 23 15:49:49 2016 +0300 @@ -122,6 +122,9 @@ typedef struct { njs_function_t *njs_function_alloc(njs_vm_t *vm); njs_function_t *njs_function_value_copy(njs_vm_t *vm, njs_value_t *value); njs_native_frame_t *njs_function_frame_alloc(njs_vm_t *vm, size_t size); +njs_ret_t njs_function_prototype_create(njs_vm_t *vm, njs_value_t *value); +njs_value_t *njs_function_property_prototype_create(njs_vm_t *vm, + njs_value_t *value); njs_ret_t njs_function_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_function_apply(njs_vm_t *vm, njs_function_t *function, diff -r 7ad8820b9c74 -r 6e70fe1e0a47 njs/njs_object.c --- a/njs/njs_object.c Wed Mar 23 15:49:46 2016 +0300 +++ b/njs/njs_object.c Wed Mar 23 15:49:49 2016 +0300 @@ -353,28 +353,47 @@ njs_primitive_prototype_get_proto(njs_vm njs_ret_t njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value) { - int32_t index; + int32_t index; + njs_value_t *proto; + njs_function_t *function; + + proto = NULL; + function = value->data.u.function; + index = function - vm->functions; + + if (index >= 0 && index < NJS_PROTOTYPE_MAX) { + proto = njs_property_prototype_create(vm, &function->object.hash, + &vm->prototypes[index]); + } + + if (proto == NULL) { + proto = (njs_value_t *) &njs_value_void; + } + + vm->retval = *proto; + + return NXT_OK; +} + + +njs_value_t * +njs_property_prototype_create(njs_vm_t *vm, nxt_lvlhsh_t *hash, + njs_object_t *prototype) +{ nxt_int_t ret; - njs_function_t *function; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; - static const njs_value_t prototype = njs_string("prototype"); + static const njs_value_t prototype_string = njs_string("prototype"); - function = value->data.u.function; - index = function - vm->functions; - - if (index < 0 && index > NJS_PROTOTYPE_MAX) { - vm->retval = njs_value_void; - return NXT_OK; + prop = njs_object_prop_alloc(vm, &prototype_string); + if (nxt_slow_path(prop == NULL)) { + return NULL; } - prop = njs_object_prop_alloc(vm, &prototype); - if (nxt_slow_path(prop == NULL)) { - return NXT_ERROR; - } + /* GC */ - prop->value.data.u.object = &vm->prototypes[index]; + prop->value.data.u.object = prototype; prop->value.type = NJS_OBJECT; prop->value.data.truth = 1; @@ -390,15 +409,16 @@ njs_object_prototype_create(njs_vm_t *vm lhq.pool = vm->mem_cache_pool; lhq.proto = &njs_object_hash_proto; - ret = nxt_lvlhsh_insert(&function->object.hash, &lhq); + ret = nxt_lvlhsh_insert(hash, &lhq); if (nxt_fast_path(ret == NXT_OK)) { - vm->retval = prop->value; + return &prop->value; } - /* TODO: exception NXT_ERROR. */ + /* Memory allocation or NXT_DECLINED error. */ + vm->exception = &njs_exception_internal_error; - return ret; + return NULL; } @@ -469,14 +489,9 @@ njs_object_prototype_get_proto(njs_vm_t static njs_ret_t njs_object_prototype_create_constructor(njs_vm_t *vm, njs_value_t *value) { - int32_t index; - nxt_int_t ret; - njs_value_t *constructor; - njs_object_t *prototype; - njs_object_prop_t *prop; - nxt_lvlhsh_query_t lhq; - - static const njs_value_t constructor_string = njs_string("constructor"); + int32_t index; + njs_value_t *cons; + njs_object_t *prototype; if (njs_is_object(value)) { prototype = value->data.u.object; @@ -503,16 +518,35 @@ njs_object_prototype_create_constructor( found: + cons = njs_property_constructor_create(vm, &prototype->hash, + &vm->scopes[NJS_SCOPE_GLOBAL][index]); + if (nxt_fast_path(cons != NULL)) { + vm->retval = *cons; + return NXT_OK; + } + + return NXT_ERROR; +} + + +njs_value_t * +njs_property_constructor_create(njs_vm_t *vm, nxt_lvlhsh_t *hash, + njs_value_t *constructor) +{ + nxt_int_t ret; + njs_object_prop_t *prop; + nxt_lvlhsh_query_t lhq; + + static const njs_value_t constructor_string = njs_string("constructor"); + prop = njs_object_prop_alloc(vm, &constructor_string); if (nxt_slow_path(prop == NULL)) { - return NXT_ERROR; + return NULL; } /* GC */ - constructor = &vm->scopes[NJS_SCOPE_GLOBAL][index]; prop->value = *constructor; - prop->enumerable = 0; lhq.value = prop; @@ -523,13 +557,16 @@ found: lhq.pool = vm->mem_cache_pool; lhq.proto = &njs_object_hash_proto; - ret = nxt_lvlhsh_insert(&prototype->hash, &lhq); + ret = nxt_lvlhsh_insert(hash, &lhq); if (nxt_fast_path(ret == NXT_OK)) { - vm->retval = *constructor; + return &prop->value; } - return ret; + /* Memory allocation or NXT_DECLINED error. */ + vm->exception = &njs_exception_internal_error; + + return NULL; } diff -r 7ad8820b9c74 -r 6e70fe1e0a47 njs/njs_object.h --- a/njs/njs_object.h Wed Mar 23 15:49:46 2016 +0300 +++ b/njs/njs_object.h Wed Mar 23 15:49:49 2016 +0300 @@ -56,7 +56,11 @@ njs_ret_t njs_object_constructor(njs_vm_ njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name); njs_ret_t njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_value_t *value); njs_ret_t njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value); +njs_value_t *njs_property_prototype_create(njs_vm_t *vm, nxt_lvlhsh_t *hash, + njs_object_t *prototype); njs_ret_t njs_object_prototype_get_proto(njs_vm_t *vm, njs_value_t *value); +njs_value_t *njs_property_constructor_create(njs_vm_t *vm, nxt_lvlhsh_t *hash, + njs_value_t *constructor); njs_ret_t njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); diff -r 7ad8820b9c74 -r 6e70fe1e0a47 njs/njs_vm.c --- a/njs/njs_vm.c Wed Mar 23 15:49:46 2016 +0300 +++ b/njs/njs_vm.c Wed Mar 23 15:49:49 2016 +0300 @@ -82,6 +82,7 @@ static nxt_noinline njs_ret_t njs_values njs_value_t *val2); static nxt_noinline nxt_bool_t njs_values_strict_equal(njs_value_t *val1, njs_value_t *val2); +static njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *value); static njs_ret_t njs_vmcode_continuation(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2); static njs_native_frame_t * @@ -118,6 +119,7 @@ const njs_value_t njs_value_true = const njs_value_t njs_value_zero = njs_value(NJS_NUMBER, 0, 0.0); const njs_value_t njs_value_nan = njs_value(NJS_NUMBER, 0, NJS_NAN); + const njs_value_t njs_string_empty = njs_string(""); const njs_value_t njs_string_comma = njs_string(","); const njs_value_t njs_string_null = njs_string("null"); @@ -2151,8 +2153,7 @@ njs_vmcode_function_frame(njs_vm_t *vm, } if (func->code.ctor) { - object = njs_object_alloc(vm); - + object = njs_function_new_object(vm, value); if (nxt_slow_path(object == NULL)) { return NXT_ERROR; } @@ -2182,6 +2183,46 @@ njs_vmcode_function_frame(njs_vm_t *vm, } +static njs_object_t * +njs_function_new_object(njs_vm_t *vm, njs_value_t *value) +{ + nxt_int_t ret; + njs_value_t *proto; + njs_object_t *object; + njs_function_t *function; + njs_object_prop_t *prop; + nxt_lvlhsh_query_t lhq; + + object = njs_object_alloc(vm); + + if (nxt_fast_path(object != NULL)) { + + lhq.key_hash = NJS_PROTOTYPE_HASH; + lhq.key.len = sizeof("prototype") - 1; + lhq.key.data = (u_char *) "prototype"; + lhq.proto = &njs_object_hash_proto; + function = value->data.u.function; + + ret = nxt_lvlhsh_find(&function->object.hash, &lhq); + + if (ret == NXT_OK) { + prop = lhq.value; + proto = &prop->value; + + } else { + proto = njs_function_property_prototype_create(vm, value); + } + + if (nxt_fast_path(proto != NULL)) { + object->__proto__ = proto->data.u.object; + return object; + } + } + + return NULL; +} + + njs_ret_t njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name) { diff -r 7ad8820b9c74 -r 6e70fe1e0a47 njs/njs_vm.h --- a/njs/njs_vm.h Wed Mar 23 15:49:46 2016 +0300 +++ b/njs/njs_vm.h Wed Mar 23 15:49:49 2016 +0300 @@ -789,6 +789,7 @@ struct njs_vm_shared_s { nxt_lvlhsh_t keywords_hash; nxt_lvlhsh_t values_hash; nxt_lvlhsh_t null_proto_hash; + nxt_lvlhsh_t function_prototype_hash; njs_object_t objects[NJS_OBJECT_MAX]; diff -r 7ad8820b9c74 -r 6e70fe1e0a47 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Mar 23 15:49:46 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Mar 23 15:49:49 2016 +0300 @@ -3248,6 +3248,20 @@ static njs_unit_test_t njs_test[] = "o.a"), nxt_string("7") }, + { nxt_string("function F(a, b) { return }" + "F.prototype.constructor === F"), + nxt_string("true") }, + + { nxt_string("function F() { return }" + "F.prototype.ok = 'OK';" + "var o = new F(); o.ok"), + nxt_string("OK") }, + + { nxt_string("function F() { return }" + "var o = new F();" + "o.constructor === F"), + nxt_string("true") }, + { nxt_string("function a() { return function(x) { return x + 1 } }" "b = a(); b(2)"), nxt_string("3") }, From igor at sysoev.ru Thu Mar 24 15:17:03 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 24 Mar 2016 15:17:03 +0000 Subject: [njs] Issues found by Coverity Scan in String.match() have been ... Message-ID: details: http://hg.nginx.org/njs/rev/425cf63a7283 branches: changeset: 89:425cf63a7283 user: Igor Sysoev date: Thu Mar 24 13:57:06 2016 +0300 description: Issues found by Coverity Scan in String.match() have been fixed. diffstat: njs/njs_string.c | 28 ++++++++++++++++------------ njs/test/njs_unit_test.c | 8 ++++++++ 2 files changed, 24 insertions(+), 12 deletions(-) diffs (97 lines): diff -r 6e70fe1e0a47 -r 425cf63a7283 njs/njs_string.c --- a/njs/njs_string.c Wed Mar 23 15:49:49 2016 +0300 +++ b/njs/njs_string.c Thu Mar 24 13:57:06 2016 +0300 @@ -1351,14 +1351,17 @@ njs_string_prototype_match(njs_vm_t *vm, (void) njs_string_prop(&string, &args[0]); + /* Byte string. */ utf8 = 0; n = 0; if (string.length != 0) { + /* ASCII string. */ utf8 = 1; n = 1; if (string.length != string.size) { + /* UTF-8 string. */ utf8 = 2; } } @@ -1366,16 +1369,6 @@ njs_string_prototype_match(njs_vm_t *vm, if (pattern->code[n] != NULL) { array = NULL; - if (n != 0) { - utf8 = 2; - - } else if (string.length != 0) { - utf8 = 1; - - } else { - utf8 = 1; - } - do { ret = pcre_exec(pattern->code[n], pattern->extra[n], (char *) string.start, string.size, @@ -1412,11 +1405,17 @@ njs_string_prototype_match(njs_vm_t *vm, case 0: length = 0; break; + case 1: length = size; break; + default: length = nxt_utf8_length(start, size); + if (nxt_slow_path(length < 0)) { + goto error; + } + break; } @@ -1432,8 +1431,7 @@ njs_string_prototype_match(njs_vm_t *vm, break; } else { - vm->exception = &njs_exception_internal_error; - return NXT_ERROR; + goto error; } } while (string.size > 0); @@ -1445,6 +1443,12 @@ njs_string_prototype_match(njs_vm_t *vm, return NXT_OK; +error: + + vm->exception = &njs_exception_internal_error; + + return NXT_ERROR; + empty: array = njs_array_alloc(vm, 1, 0); diff -r 6e70fe1e0a47 -r 425cf63a7283 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Mar 23 15:49:49 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Mar 24 13:57:06 2016 +0300 @@ -2823,6 +2823,14 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abc ABC aBc'.match(/abc/ig)"), nxt_string("abc,ABC,aBc") }, + { nxt_string("var a = '?'.match(/?/g)[0] + '?';" + "a +' '+ a.length"), + nxt_string("?? 2") }, + + { nxt_string("var a = '\\u00CE\\u00B1'.toBytes().match(/?/g)[0] + '?';" + "a +' '+ a.length"), + nxt_string("?? 4") }, + /* Functions. */ { nxt_string("function f() { } f()"), From igor at sysoev.ru Thu Mar 24 15:17:04 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 24 Mar 2016 15:17:04 +0000 Subject: [njs] Issues found by Coverity Scan in Regex have been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/027e0e8e7f61 branches: changeset: 90:027e0e8e7f61 user: Igor Sysoev date: Thu Mar 24 14:22:08 2016 +0300 description: Issues found by Coverity Scan in Regex have been fixed. diffstat: njs/njs_regexp.c | 22 +++++++++++++++++++--- 1 files changed, 19 insertions(+), 3 deletions(-) diffs (60 lines): diff -r 425cf63a7283 -r 027e0e8e7f61 njs/njs_regexp.c --- a/njs/njs_regexp.c Thu Mar 24 13:57:06 2016 +0300 +++ b/njs/njs_regexp.c Thu Mar 24 14:22:08 2016 +0300 @@ -36,6 +36,8 @@ static int njs_regexp_pattern_compile(pc u_char *source, int options); static njs_ret_t njs_regexp_exec_result(njs_vm_t *vm, njs_regexp_t *regexp, u_char *string, int *captures, nxt_uint_t utf8); +static njs_ret_t njs_regexp_string_create(njs_vm_t *vm, njs_value_t *value, + u_char *start, uint32_t size, int32_t length); njs_ret_t @@ -436,7 +438,7 @@ njs_regexp_prototype_source(njs_vm_t *vm size = strlen((char *) source) - pattern->flags; length = nxt_utf8_length(source, size); - return njs_string_create(vm, &vm->retval, source, size, length); + return njs_regexp_string_create(vm, &vm->retval, source, size, length); } @@ -454,7 +456,7 @@ njs_regexp_prototype_to_string(njs_vm_t size = strlen((char *) source); length = nxt_utf8_length(source, size); - return njs_string_create(vm, &vm->retval, source, size, length); + return njs_regexp_string_create(vm, &vm->retval, source, size, length); } @@ -621,7 +623,8 @@ njs_regexp_exec_result(njs_vm_t *vm, njs break; } - ret = njs_string_create(vm, &array->start[i], start, size, length); + ret = njs_regexp_string_create(vm, &array->start[i], + start, size, length); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } @@ -684,6 +687,19 @@ njs_regexp_exec_result(njs_vm_t *vm, njs } +static njs_ret_t +njs_regexp_string_create(njs_vm_t *vm, njs_value_t *value, u_char *start, + uint32_t size, int32_t length) +{ + if (nxt_fast_path(length >= 0)) { + return njs_string_create(vm, value, start, size, length); + } + + vm->exception = &njs_exception_internal_error; + return NXT_ERROR; +} + + static const njs_object_prop_t njs_regexp_constructor_properties[] = { /* RegExp.name == "RegExp". */ From igor at sysoev.ru Thu Mar 24 15:17:05 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 24 Mar 2016 15:17:05 +0000 Subject: [njs] Miscellaneous issues found by Coverity Scan have been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/0354cdd7d114 branches: changeset: 91:0354cdd7d114 user: Igor Sysoev date: Thu Mar 24 17:13:27 2016 +0300 description: Miscellaneous issues found by Coverity Scan have been fixed. diffstat: njs/njs_variable.c | 6 +- njs/njs_vm.c | 226 ++++++++++++++++++++++++++-------------------------- 2 files changed, 117 insertions(+), 115 deletions(-) diffs (279 lines): diff -r 027e0e8e7f61 -r 0354cdd7d114 njs/njs_variable.c --- a/njs/njs_variable.c Thu Mar 24 14:22:08 2016 +0300 +++ b/njs/njs_variable.c Thu Mar 24 17:13:27 2016 +0300 @@ -62,7 +62,7 @@ njs_parser_variable(njs_vm_t *vm, njs_pa njs_variable_t *var; nxt_lvlhsh_query_t lhq; - level = 0; + *level = 0; lhq.key_hash = parser->lexer->key_hash; lhq.key = parser->lexer->text; @@ -90,11 +90,11 @@ njs_parser_variable(njs_vm_t *vm, njs_pa } scope = scope->parent; - level++; + (*level)++; } while (scope != NULL); - level = 0; + *level = 0; if (nxt_lvlhsh_find(&vm->variables_hash, &lhq) == NXT_OK) { return lhq.value; diff -r 027e0e8e7f61 -r 0354cdd7d114 njs/njs_vm.c --- a/njs/njs_vm.c Thu Mar 24 14:22:08 2016 +0300 +++ b/njs/njs_vm.c Thu Mar 24 17:13:27 2016 +0300 @@ -161,128 +161,128 @@ njs_vmcode_interpreter(njs_vm_t *vm) njs_native_frame_t *previous; njs_vmcode_generic_t *vmcode; + start: + for ( ;; ) { - again: + vmcode = (njs_vmcode_generic_t *) vm->current; + + /* + * The first operand is passed as is in value2 to + * njs_vmcode_jump(), + * njs_vmcode_if_true_jump(), + * njs_vmcode_if_false_jump(), + * njs_vmcode_validate(), + * njs_vmcode_function_frame(), + * njs_vmcode_function_call(), + * njs_vmcode_return(), + * njs_vmcode_try_start(), + * njs_vmcode_try_next(), + * njs_vmcode_try_end(), + * njs_vmcode_catch(). + * njs_vmcode_throw(). + * njs_vmcode_stop(). + */ + value2 = (njs_value_t *) vmcode->operand1; + value1 = NULL; + + switch (vmcode->code.operands) { + + case NJS_VMCODE_3OPERANDS: + value2 = njs_vmcode_operand(vm, vmcode->operand3); + + /* Fall through. */ + + case NJS_VMCODE_2OPERANDS: + value1 = njs_vmcode_operand(vm, vmcode->operand2); + } + + ret = vmcode->code.operation(vm, value1, value2); + + /* + * On success an operation returns size of the bytecode, + * a jump offset or zero after the call or return operations. + * Jumps can return a negative offset. Compilers can generate + * (ret < 0 && ret >= NJS_PREEMPT) + * as a single unsigned comparision. + */ + + if (nxt_slow_path(ret < 0 && ret >= NJS_PREEMPT)) { + break; + } + + vm->current += ret; + + if (vmcode->code.retval) { + retval = njs_vmcode_operand(vm, vmcode->operand1); + //njs_release(vm, retval); + *retval = vm->retval; + } + } + + switch (ret) { + + case NJS_TRAP_NUMBER: + value2 = value1; + + /* Fall through. */ + + case NJS_TRAP_NUMBERS: + case NJS_TRAP_STRINGS: + case NJS_TRAP_INCDEC: + case NJS_TRAP_PROPERTY: + + njs_vm_trap(vm, ret - NJS_TRAP_BASE, value1, value2); + + goto start; + + case NJS_TRAP_NUMBER_ARG: + case NJS_TRAP_STRING_ARG: + + ret = njs_vm_trap_argument(vm, ret - NJS_TRAP_BASE); + if (nxt_fast_path(ret == NXT_OK)) { + goto start; + } + + break; + + default: + break; + } + + if (ret == NXT_ERROR) { + for ( ;; ) { - - vmcode = (njs_vmcode_generic_t *) vm->current; - - /* - * The first operand is passed as is in value2 to - * njs_vmcode_jump(), - * njs_vmcode_if_true_jump(), - * njs_vmcode_if_false_jump(), - * njs_vmcode_validate(), - * njs_vmcode_function_frame(), - * njs_vmcode_function_call(), - * njs_vmcode_return(), - * njs_vmcode_try_start(), - * njs_vmcode_try_next(), - * njs_vmcode_try_end(), - * njs_vmcode_catch(). - * njs_vmcode_throw(). - * njs_vmcode_stop(). - */ - value2 = (njs_value_t *) vmcode->operand1; - value1 = NULL; - - switch (vmcode->code.operands) { - - case NJS_VMCODE_3OPERANDS: - value2 = njs_vmcode_operand(vm, vmcode->operand3); - - case NJS_VMCODE_2OPERANDS: - value1 = njs_vmcode_operand(vm, vmcode->operand2); + frame = (njs_frame_t *) vm->frame; + catch = frame->native.exception.catch; + + if (catch != NULL) { + vm->current = catch; + goto start; } - ret = vmcode->code.operation(vm, value1, value2); - - /* - * On success an operation returns size of the bytecode, - * a jump offset or zero after the call or return operations. - * Jumps can return a negative offset. Compilers can generate - * (ret < 0 && ret >= NJS_PREEMPT) - * as a single unsigned comparision. - */ - - if (nxt_slow_path(ret < 0 && ret >= NJS_PREEMPT)) { - break; + previous = frame->native.previous; + if (previous == NULL) { + return NXT_ERROR; } - vm->current += ret; - - if (vmcode->code.retval) { - retval = njs_vmcode_operand(vm, vmcode->operand1); - //njs_release(vm, retval); - *retval = vm->retval; + vm->frame = previous; + + /* GC: NJS_SCOPE_ARGUMENTS and NJS_SCOPE_LOCAL. */ + + vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = previous->arguments; + vm->scopes[NJS_SCOPE_LOCAL] = frame->prev_local; + vm->scopes[NJS_SCOPE_ARGUMENTS] = frame->prev_arguments; + + if (frame->native.first) { + nxt_mem_cache_free(vm->mem_cache_pool, frame); } } - - switch (ret) { - - case NJS_TRAP_NUMBER: - value2 = value1; - - /* Fall through. */ - - case NJS_TRAP_NUMBERS: - case NJS_TRAP_STRINGS: - case NJS_TRAP_INCDEC: - case NJS_TRAP_PROPERTY: - - njs_vm_trap(vm, ret - NJS_TRAP_BASE, value1, value2); - - goto again; - - case NJS_TRAP_NUMBER_ARG: - case NJS_TRAP_STRING_ARG: - - ret = njs_vm_trap_argument(vm, ret - NJS_TRAP_BASE); - if (nxt_fast_path(ret == NXT_OK)) { - goto again; - } - - break; - - default: - break; - } - - if (ret == NXT_ERROR) { - - for ( ;; ) { - frame = (njs_frame_t *) vm->frame; - catch = frame->native.exception.catch; - - if (catch != NULL) { - vm->current = catch; - goto again; - } - - previous = frame->native.previous; - if (previous == NULL) { - return NXT_ERROR; - } - - vm->frame = previous; - - /* GC: NJS_SCOPE_ARGUMENTS and NJS_SCOPE_LOCAL. */ - - vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = previous->arguments; - vm->scopes[NJS_SCOPE_LOCAL] = frame->prev_local; - vm->scopes[NJS_SCOPE_ARGUMENTS] = frame->prev_arguments; - - if (frame->native.first) { - nxt_mem_cache_free(vm->mem_cache_pool, frame); - } - } - } - - /* NXT_AGAIN, NJS_STOP. */ - - return ret; } + + /* NXT_AGAIN, NJS_STOP. */ + + return ret; } @@ -517,6 +517,8 @@ njs_vmcode_property_get(njs_vm_t *vm, nj prop = pq.lhq.value; } + /* Fall through. */ + case NJS_PROPERTY: retval = &prop->value; break; From arut at nginx.com Fri Mar 25 11:11:51 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Fri, 25 Mar 2016 11:11:51 +0000 Subject: [nginx] Fixed socket inheritance on reload and binary upgrade. Message-ID: details: http://hg.nginx.org/nginx/rev/fd4b52e74f96 branches: changeset: 6462:fd4b52e74f96 user: Roman Arutyunyan date: Fri Mar 25 14:10:38 2016 +0300 description: Fixed socket inheritance on reload and binary upgrade. On nginx reload or binary upgrade, an attempt is made to inherit listen sockets from the previous configuration. Previously, no check for socket type was made and the inherited socket could have the wrong type. On binary upgrade, socket type was not detected at all. Wrong socket type could lead to errors on that socket due to different logic and unsupported syscalls. For example, a UDP socket, inherited as TCP, lead to the following error after arrival of a datagram: "accept() failed (102: Operation not supported on socket)". diffstat: src/core/ngx_connection.c | 16 ++++++++++++++++ src/core/ngx_cycle.c | 4 ++++ 2 files changed, 20 insertions(+), 0 deletions(-) diffs (47 lines): diff -r a01e315b3a78 -r fd4b52e74f96 src/core/ngx_connection.c --- a/src/core/ngx_connection.c Fri Mar 18 19:53:22 2016 +0300 +++ b/src/core/ngx_connection.c Fri Mar 25 14:10:38 2016 +0300 @@ -210,6 +210,18 @@ ngx_set_inherited_sockets(ngx_cycle_t *c olen = sizeof(int); + if (getsockopt(ls[i].fd, SOL_SOCKET, SO_TYPE, (void *) &ls[i].type, + &olen) + == -1) + { + ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, + "getsockopt(SO_TYPE) %V failed", &ls[i].addr_text); + ls[i].ignore = 1; + continue; + } + + olen = sizeof(int); + if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf, &olen) == -1) @@ -274,6 +286,10 @@ ngx_set_inherited_sockets(ngx_cycle_t *c #endif + if (ls[i].type != SOCK_STREAM) { + continue; + } + #if (NGX_HAVE_TCP_FASTOPEN) olen = sizeof(int); diff -r a01e315b3a78 -r fd4b52e74f96 src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Fri Mar 18 19:53:22 2016 +0300 +++ b/src/core/ngx_cycle.c Fri Mar 25 14:10:38 2016 +0300 @@ -512,6 +512,10 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) continue; } + if (ls[i].type != nls[n].type) { + continue; + } + if (ngx_cmp_sockaddr(nls[n].sockaddr, nls[n].socklen, ls[i].sockaddr, ls[i].socklen, 1) == NGX_OK) From vbart at nginx.com Fri Mar 25 13:05:31 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 25 Mar 2016 13:05:31 +0000 Subject: [nginx] Core: allow strings without null-termination in ngx_parse_url(). Message-ID: details: http://hg.nginx.org/nginx/rev/5df5d7d771f6 branches: changeset: 6463:5df5d7d771f6 user: Piotr Sikora date: Fri Feb 26 17:30:27 2016 -0800 description: Core: allow strings without null-termination in ngx_parse_url(). This fixes buffer over-read while using variables in the "proxy_pass", "fastcgi_pass", "scgi_pass", and "uwsgi_pass" directives, where result of string evaluation isn't null-terminated. Found with MemorySanitizer. Signed-off-by: Piotr Sikora diffstat: src/core/ngx_inet.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (22 lines): diff -r fd4b52e74f96 -r 5df5d7d771f6 src/core/ngx_inet.c --- a/src/core/ngx_inet.c Fri Mar 25 14:10:38 2016 +0300 +++ b/src/core/ngx_inet.c Fri Feb 26 17:30:27 2016 -0800 @@ -529,14 +529,16 @@ ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u) { u_char *p; + size_t len; p = u->url.data; + len = u->url.len; - if (ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) { + if (len >= 5 && ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) { return ngx_parse_unix_domain_url(pool, u); } - if (p[0] == '[') { + if (len && p[0] == '[') { return ngx_parse_inet6_url(pool, u); } From arut at nginx.com Mon Mar 28 10:36:47 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 28 Mar 2016 10:36:47 +0000 Subject: [nginx] Sub filter: fixed allocation alignment. Message-ID: details: http://hg.nginx.org/nginx/rev/088ef087a011 branches: changeset: 6464:088ef087a011 user: Roman Arutyunyan date: Mon Mar 28 13:35:25 2016 +0300 description: Sub filter: fixed allocation alignment. diffstat: src/http/modules/ngx_http_sub_filter_module.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (39 lines): diff -r 5df5d7d771f6 -r 088ef087a011 src/http/modules/ngx_http_sub_filter_module.c --- a/src/http/modules/ngx_http_sub_filter_module.c Fri Feb 26 17:30:27 2016 -0800 +++ b/src/http/modules/ngx_http_sub_filter_module.c Mon Mar 28 13:35:25 2016 +0300 @@ -229,7 +229,7 @@ ngx_http_sub_header_filter(ngx_http_requ return ngx_http_next_header_filter(r); } - ctx->matches = ngx_pnalloc(r->pool, sizeof(ngx_array_t)); + ctx->matches = ngx_palloc(r->pool, sizeof(ngx_array_t)); if (ctx->matches == NULL) { return NGX_ERROR; } @@ -237,7 +237,7 @@ ngx_http_sub_header_filter(ngx_http_requ ctx->matches->elts = matches; ctx->matches->nelts = j; - ctx->tables = ngx_pnalloc(r->pool, sizeof(ngx_http_sub_tables_t)); + ctx->tables = ngx_palloc(r->pool, sizeof(ngx_http_sub_tables_t)); if (ctx->tables == NULL) { return NGX_ERROR; } @@ -859,7 +859,7 @@ ngx_http_sub_merge_conf(ngx_conf_t *cf, pairs = conf->pairs->elts; n = conf->pairs->nelts; - matches = ngx_pnalloc(cf->pool, sizeof(ngx_http_sub_match_t) * n); + matches = ngx_palloc(cf->pool, sizeof(ngx_http_sub_match_t) * n); if (matches == NULL) { return NGX_CONF_ERROR; } @@ -869,7 +869,7 @@ ngx_http_sub_merge_conf(ngx_conf_t *cf, matches[i].value = &pairs[i].value; } - conf->matches = ngx_pnalloc(cf->pool, sizeof(ngx_array_t)); + conf->matches = ngx_palloc(cf->pool, sizeof(ngx_array_t)); if (conf->matches == NULL) { return NGX_CONF_ERROR; } From igor at sysoev.ru Mon Mar 28 14:38:26 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 28 Mar 2016 14:38:26 +0000 Subject: [njs] Fixed building on Solaris by SunC. Message-ID: details: http://hg.nginx.org/njs/rev/f674bd8a8b76 branches: changeset: 92:f674bd8a8b76 user: Igor Sysoev date: Mon Mar 28 17:34:42 2016 +0300 description: Fixed building on Solaris by SunC. diffstat: njs/njs_math.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 0354cdd7d114 -r f674bd8a8b76 njs/njs_math.c --- a/njs/njs_math.c Thu Mar 24 17:13:27 2016 +0300 +++ b/njs/njs_math.c Mon Mar 28 17:34:42 2016 +0300 @@ -536,7 +536,7 @@ static const njs_object_prop_t njs_math { .type = NJS_METHOD, .name = njs_string("random"), - .value = njs_native_function(njs_object_math_random, 0, ), + .value = njs_native_function(njs_object_math_random, 0, 0), }, { From ru at nginx.com Mon Mar 28 16:31:47 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 28 Mar 2016 16:31:47 +0000 Subject: [nginx] Fixed --test-build-*. Message-ID: details: http://hg.nginx.org/nginx/rev/9fd68d5009e3 branches: changeset: 6465:9fd68d5009e3 user: Ruslan Ermilov date: Mon Mar 28 19:29:18 2016 +0300 description: Fixed --test-build-*. Fixes various aspects of --test-build-devpoll, --test-build-eventport, and --test-build-epoll. In particular, if --test-build-devpoll was used on Linux, then "devpoll" event method would be preferred over "epoll". Also, wrong definitions of event macros were chosen. diffstat: src/event/ngx_event.c | 2 +- src/event/ngx_event.h | 5 +++-- src/os/unix/ngx_posix_config.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diffs (46 lines): diff -r 088ef087a011 -r 9fd68d5009e3 src/event/ngx_event.c --- a/src/event/ngx_event.c Mon Mar 28 13:35:25 2016 +0300 +++ b/src/event/ngx_event.c Mon Mar 28 19:29:18 2016 +0300 @@ -1208,7 +1208,7 @@ ngx_event_core_init_conf(ngx_cycle_t *cy #endif -#if (NGX_HAVE_DEVPOLL) +#if (NGX_HAVE_DEVPOLL) && !(NGX_TEST_BUILD_DEVPOLL) module = &ngx_devpoll_module; diff -r 088ef087a011 -r 9fd68d5009e3 src/event/ngx_event.h --- a/src/event/ngx_event.h Mon Mar 28 13:35:25 2016 +0300 +++ b/src/event/ngx_event.h Mon Mar 28 19:29:18 2016 +0300 @@ -343,7 +343,8 @@ extern ngx_event_actions_t ngx_event_a #define NGX_DISABLE_EVENT EV_DISABLE -#elif (NGX_HAVE_DEVPOLL || NGX_HAVE_EVENTPORT) +#elif (NGX_HAVE_DEVPOLL && !(NGX_TEST_BUILD_DEVPOLL)) \ + || (NGX_HAVE_EVENTPORT && !(NGX_TEST_BUILD_EVENTPORT)) #define NGX_READ_EVENT POLLIN #define NGX_WRITE_EVENT POLLOUT @@ -352,7 +353,7 @@ extern ngx_event_actions_t ngx_event_a #define NGX_ONESHOT_EVENT 1 -#elif (NGX_HAVE_EPOLL) +#elif (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL) #define NGX_READ_EVENT (EPOLLIN|EPOLLRDHUP) #define NGX_WRITE_EVENT EPOLLOUT diff -r 088ef087a011 -r 9fd68d5009e3 src/os/unix/ngx_posix_config.h --- a/src/os/unix/ngx_posix_config.h Mon Mar 28 13:35:25 2016 +0300 +++ b/src/os/unix/ngx_posix_config.h Mon Mar 28 19:29:18 2016 +0300 @@ -128,7 +128,7 @@ #endif -#if (NGX_HAVE_DEVPOLL) +#if (NGX_HAVE_DEVPOLL) && !(NGX_TEST_BUILD_DEVPOLL) #include #include #endif From mdounin at mdounin.ru Mon Mar 28 16:52:43 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 28 Mar 2016 16:52:43 +0000 Subject: [nginx] Upstream: cached connections now tested against next_upstream. Message-ID: details: http://hg.nginx.org/nginx/rev/984687f25998 branches: changeset: 6466:984687f25998 user: Maxim Dounin date: Mon Mar 28 19:49:52 2016 +0300 description: Upstream: cached connections now tested against next_upstream. Much like normal connections, cached connections are now tested against u->conf->next_upstream, and u->state->status is now always set. This allows to disable additional tries even with upstream keepalive by using "proxy_next_upstream off". diffstat: src/http/ngx_http_upstream.c | 115 ++++++++++++++++++++---------------------- 1 files changed, 54 insertions(+), 61 deletions(-) diffs (138 lines): diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -3947,42 +3947,36 @@ ngx_http_upstream_next(ngx_http_request_ "upstream timed out"); } - if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR - && (!u->request_sent || !r->request_body_no_buffering)) - { - status = 0; - + if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) { /* TODO: inform balancer instead */ - u->peer.tries++; - - } else { - switch (ft_type) { - - case NGX_HTTP_UPSTREAM_FT_TIMEOUT: - status = NGX_HTTP_GATEWAY_TIME_OUT; - break; - - case NGX_HTTP_UPSTREAM_FT_HTTP_500: - status = NGX_HTTP_INTERNAL_SERVER_ERROR; - break; - - case NGX_HTTP_UPSTREAM_FT_HTTP_403: - status = NGX_HTTP_FORBIDDEN; - break; - - case NGX_HTTP_UPSTREAM_FT_HTTP_404: - status = NGX_HTTP_NOT_FOUND; - break; - - /* - * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING - * never reach here - */ - - default: - status = NGX_HTTP_BAD_GATEWAY; - } + } + + switch (ft_type) { + + case NGX_HTTP_UPSTREAM_FT_TIMEOUT: + status = NGX_HTTP_GATEWAY_TIME_OUT; + break; + + case NGX_HTTP_UPSTREAM_FT_HTTP_500: + status = NGX_HTTP_INTERNAL_SERVER_ERROR; + break; + + case NGX_HTTP_UPSTREAM_FT_HTTP_403: + status = NGX_HTTP_FORBIDDEN; + break; + + case NGX_HTTP_UPSTREAM_FT_HTTP_404: + status = NGX_HTTP_NOT_FOUND; + break; + + /* + * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING + * never reach here + */ + + default: + status = NGX_HTTP_BAD_GATEWAY; } if (r->connection->error) { @@ -3991,37 +3985,36 @@ ngx_http_upstream_next(ngx_http_request_ return; } - if (status) { - u->state->status = status; - timeout = u->conf->next_upstream_timeout; - - if (u->peer.tries == 0 - || !(u->conf->next_upstream & ft_type) - || (u->request_sent && r->request_body_no_buffering) - || (timeout && ngx_current_msec - u->peer.start_time >= timeout)) + u->state->status = status; + + timeout = u->conf->next_upstream_timeout; + + if (u->peer.tries == 0 + || !(u->conf->next_upstream & ft_type) + || (u->request_sent && r->request_body_no_buffering) + || (timeout && ngx_current_msec - u->peer.start_time >= timeout)) + { +#if (NGX_HTTP_CACHE) + + if (u->cache_status == NGX_HTTP_CACHE_EXPIRED + && (u->conf->cache_use_stale & ft_type)) { -#if (NGX_HTTP_CACHE) - - if (u->cache_status == NGX_HTTP_CACHE_EXPIRED - && (u->conf->cache_use_stale & ft_type)) - { - ngx_int_t rc; - - rc = u->reinit_request(r); - - if (rc == NGX_OK) { - u->cache_status = NGX_HTTP_CACHE_STALE; - rc = ngx_http_upstream_cache_send(r, u); - } - - ngx_http_upstream_finalize_request(r, u, rc); - return; + ngx_int_t rc; + + rc = u->reinit_request(r); + + if (rc == NGX_OK) { + u->cache_status = NGX_HTTP_CACHE_STALE; + rc = ngx_http_upstream_cache_send(r, u); } + + ngx_http_upstream_finalize_request(r, u, rc); + return; + } #endif - ngx_http_upstream_finalize_request(r, u, status); - return; - } + ngx_http_upstream_finalize_request(r, u, status); + return; } if (u->peer.connection) { From mdounin at mdounin.ru Mon Mar 28 16:52:45 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 28 Mar 2016 16:52:45 +0000 Subject: [nginx] Upstream: proxy_next_upstream non_idempotent. Message-ID: details: http://hg.nginx.org/nginx/rev/91c8d990fb45 branches: changeset: 6467:91c8d990fb45 user: Maxim Dounin date: Mon Mar 28 19:50:19 2016 +0300 description: Upstream: proxy_next_upstream non_idempotent. By default, requests with non-idempotent methods (POST, LOCK, PATCH) are no longer retried in case of errors if a request was already sent to a backend. Previous behaviour can be restored by using "proxy_next_upstream ... non_idempotent". diffstat: src/http/modules/ngx_http_fastcgi_module.c | 1 + src/http/modules/ngx_http_proxy_module.c | 1 + src/http/modules/ngx_http_scgi_module.c | 1 + src/http/modules/ngx_http_uwsgi_module.c | 1 + src/http/ngx_http_upstream.c | 8 +++++++- src/http/ngx_http_upstream.h | 1 + 6 files changed, 12 insertions(+), 1 deletions(-) diffs (74 lines): diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -206,6 +206,7 @@ static ngx_conf_bitmask_t ngx_http_fast { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, + { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT }, { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 }, { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -213,6 +213,7 @@ static ngx_conf_bitmask_t ngx_http_prox { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, + { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT }, { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 }, { ngx_string("http_502"), NGX_HTTP_UPSTREAM_FT_HTTP_502 }, { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c @@ -77,6 +77,7 @@ static ngx_conf_bitmask_t ngx_http_scgi_ { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, + { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT }, { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 }, { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -109,6 +109,7 @@ static ngx_conf_bitmask_t ngx_http_uwsgi { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, + { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT }, { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 }, { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -3989,8 +3989,14 @@ ngx_http_upstream_next(ngx_http_request_ timeout = u->conf->next_upstream_timeout; + if (u->request_sent + && (r->method & (NGX_HTTP_POST|NGX_HTTP_LOCK|NGX_HTTP_PATCH))) + { + ft_type |= NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT; + } + if (u->peer.tries == 0 - || !(u->conf->next_upstream & ft_type) + || ((u->conf->next_upstream & ft_type) != ft_type) || (u->request_sent && r->request_body_no_buffering) || (timeout && ngx_current_msec - u->peer.start_time >= timeout)) { diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -29,6 +29,7 @@ #define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000400 #define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000800 #define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00001000 +#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00002000 #define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000 #define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000 From mdounin at mdounin.ru Tue Mar 29 06:54:32 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 29 Mar 2016 06:54:32 +0000 Subject: [nginx] Win32: additional error code NGX_EEXIST_FILE (ticket #910). Message-ID: details: http://hg.nginx.org/nginx/rev/a5897d360977 branches: changeset: 6468:a5897d360977 user: Maxim Dounin date: Tue Mar 29 09:51:46 2016 +0300 description: Win32: additional error code NGX_EEXIST_FILE (ticket #910). On Windows there are two possible error codes which correspond to the EEXIST error code: ERROR_FILE_EXISTS used by CreateFile(CREATE_NEW), and ERROR_ALREADY_EXISTS used by CreateDirectory(). MoveFile() seems to use both: ERROR_ALREADY_EXISTS when moving within one filesystem, and ERROR_FILE_EXISTS when copying a file to a different drive. diffstat: src/core/ngx_file.c | 4 ++-- src/os/unix/ngx_errno.h | 1 + src/os/win32/ngx_errno.h | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diffs (51 lines): diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -196,7 +196,7 @@ ngx_create_temp_file(ngx_file_t *file, n err = ngx_errno; - if (err == NGX_EEXIST) { + if (err == NGX_EEXIST_FILE) { n = (uint32_t) ngx_next_temp_number(1); continue; } @@ -692,7 +692,7 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_ #if (NGX_WIN32) - if (err == NGX_EEXIST) { + if (err == NGX_EEXIST || err == NGX_EEXIST_FILE) { err = ngx_win32_rename_file(src, to, ext->log); if (err == 0) { diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h --- a/src/os/unix/ngx_errno.h +++ b/src/os/unix/ngx_errno.h @@ -25,6 +25,7 @@ typedef int ngx_err_t; #define NGX_EACCES EACCES #define NGX_EBUSY EBUSY #define NGX_EEXIST EEXIST +#define NGX_EEXIST_FILE EEXIST #define NGX_EXDEV EXDEV #define NGX_ENOTDIR ENOTDIR #define NGX_EISDIR EISDIR diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h --- a/src/os/win32/ngx_errno.h +++ b/src/os/win32/ngx_errno.h @@ -25,8 +25,14 @@ typedef DWORD ngx_e #define NGX_ENOPATH ERROR_PATH_NOT_FOUND #define NGX_ENOMEM ERROR_NOT_ENOUGH_MEMORY #define NGX_EACCES ERROR_ACCESS_DENIED -/* it's seems that ERROR_FILE_EXISTS is not appropriate error code */ +/* + * there are two EEXIST error codes: + * ERROR_FILE_EXISTS used by CreateFile(CREATE_NEW), + * and ERROR_ALREADY_EXISTS used by CreateDirectory(); + * MoveFile() uses both + */ #define NGX_EEXIST ERROR_ALREADY_EXISTS +#define NGX_EEXIST_FILE ERROR_FILE_EXISTS /* * could not found cross volume directory move error code, * so use ERROR_WRONG_DISK as stub one From mdounin at mdounin.ru Tue Mar 29 06:54:35 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 29 Mar 2016 06:54:35 +0000 Subject: [nginx] Win32: replaced NGX_EXDEV with more appropriate error code. Message-ID: details: http://hg.nginx.org/nginx/rev/7cdf612fd58c branches: changeset: 6469:7cdf612fd58c user: Maxim Dounin date: Tue Mar 29 09:52:15 2016 +0300 description: Win32: replaced NGX_EXDEV with more appropriate error code. Correct error code for NGX_EXDEV on Windows is ERROR_NOT_SAME_DEVICE, "The system cannot move the file to a different disk drive". Previously used ERROR_WRONG_DISK is about wrong diskette in the drive and is not appropriate. There is no real difference though, as MoveFile() is able to copy files between disk drives, and will fail with ERROR_ACCESS_DENIED when asked to copy directories. The ERROR_NOT_SAME_DEVICE error is only used by MoveFileEx() when called without the MOVEFILE_COPY_ALLOWED flag. diffstat: src/os/win32/ngx_errno.h | 6 +----- 1 files changed, 1 insertions(+), 5 deletions(-) diffs (16 lines): diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h --- a/src/os/win32/ngx_errno.h +++ b/src/os/win32/ngx_errno.h @@ -33,11 +33,7 @@ typedef DWORD ngx_e */ #define NGX_EEXIST ERROR_ALREADY_EXISTS #define NGX_EEXIST_FILE ERROR_FILE_EXISTS -/* - * could not found cross volume directory move error code, - * so use ERROR_WRONG_DISK as stub one - */ -#define NGX_EXDEV ERROR_WRONG_DISK +#define NGX_EXDEV ERROR_NOT_SAME_DEVICE #define NGX_ENOTDIR ERROR_PATH_NOT_FOUND #define NGX_EISDIR ERROR_CANNOT_MAKE #define NGX_ENOSPC ERROR_DISK_FULL From mdounin at mdounin.ru Tue Mar 29 06:54:37 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 29 Mar 2016 06:54:37 +0000 Subject: [nginx] Updated OpenSSL used for win32 builds. Message-ID: details: http://hg.nginx.org/nginx/rev/62d950bc0f15 branches: changeset: 6470:62d950bc0f15 user: Maxim Dounin date: Tue Mar 29 09:54:11 2016 +0300 description: Updated OpenSSL used for win32 builds. diffstat: misc/GNUmakefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/misc/GNUmakefile b/misc/GNUmakefile --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -5,7 +5,7 @@ NGINX = nginx-$(VER) TEMP = tmp OBJS = objs.msvc8 -OPENSSL = openssl-1.0.2f +OPENSSL = openssl-1.0.2g ZLIB = zlib-1.2.8 PCRE = pcre-8.38 From igor at sysoev.ru Tue Mar 29 10:38:43 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 29 Mar 2016 10:38:43 +0000 Subject: [njs] A fast exit from argument normalization loop. Message-ID: details: http://hg.nginx.org/njs/rev/91543c86f412 branches: changeset: 93:91543c86f412 user: Igor Sysoev date: Tue Mar 29 13:38:18 2016 +0300 description: A fast exit from argument normalization loop. This also fixes an issue when SunC 5.9 does not set omitted array elements to a zero. diffstat: njs/njs_vm.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (15 lines): diff -r f674bd8a8b76 -r 91543c86f412 njs/njs_vm.c --- a/njs/njs_vm.c Mon Mar 28 17:34:42 2016 +0300 +++ b/njs/njs_vm.c Tue Mar 29 13:38:18 2016 +0300 @@ -2474,8 +2474,10 @@ njs_normalize_args(njs_vm_t *vm, njs_val break; case NJS_SKIP_ARG: - break; + + case 0: + return NJS_OK; } args++; From mdounin at mdounin.ru Tue Mar 29 15:13:12 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 29 Mar 2016 15:13:12 +0000 Subject: [nginx] nginx-1.9.13-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/5936b7ed9292 branches: changeset: 6471:5936b7ed9292 user: Maxim Dounin date: Tue Mar 29 18:09:30 2016 +0300 description: nginx-1.9.13-RELEASE diffstat: docs/xml/nginx/changes.xml | 166 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 166 insertions(+), 0 deletions(-) diffs (176 lines): diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,172 @@ + + + + +??????????????? ??????? (POST, LOCK, PATCH) +?????? ?? ????????? ?? ?????????? ?? ?????? ??????, +???? ?????? ??? ??? ????????? ?? ??????; +???????? non_idempotent ????????? proxy_next_upstream +???? ????????? ????????? ????? ???????. + + +non-idempotent requests (POST, LOCK, PATCH) +are no longer passed to the next server by default +if a request has been sent to a backend; +the "non_idempotent" parameter of the "proxy_next_upstream" directive +explicitly allows retrying such requests. + + + + + +?????? ngx_http_perl_module ?????? ????? ??????? ???????????. + + +the ngx_http_perl_module can be built dynamically. + + + + + +????????? UDP ? ?????? stream. + + +UDP support in the stream module. + + + + + +????????? aio_write. + + +the "aio_write" directive. + + + + + +?????? cache manager ?????? ?? ??????????? ????????? ? ???? +? ????????? ?? ????????? ???????????? ???? ??????????? ??????. + + +now cache manager monitors number of elements in caches +and tries to avoid cache keys zone overflows. + + + + + +??? ????????????? ???????? sendfile ? aio ? ???????????? +? ????? ????? ?????????? ????????? "task already active" ? "second aio post". + + + +"task already active" and "second aio post" alerts might appear in logs +when using the "sendfile" and "aio" directives with subrequests. + + + + + +??? ????????????? ??????????? +? ????? ????? ?????????? ????????? "zero size buf in output", +???? ?????? ???????? ?????????? ??????????????. + + +"zero size buf in output" alerts might appear in logs +if caching was used +and a client closed a connection prematurely. + + + + + +??? ????????????? ??????????? +?????????? ? ????????? ????? ??????????? ??? ?????????????.
+??????? Justin Li. +
+ +connections with clients might be closed needlessly +if caching was used.
+Thanks to Justin Li. +
+
+ + + +nginx ??? ????????? ????????? +??? ????????????? ????????? sendfile ?? Linux ? Solaris, +???? ???????????? ???? ??? ??????? ? ???????? ????????. + + +nginx might hog CPU +if the "sendfile" directive was used on Linux or Solaris +and a file being sent was changed during sending. + + + + + +??? ????????????? ???????? sendfile ? "aio threads" +?????????? ????? ????????. + + +connections might hang +when using the "sendfile" and "aio threads" directives. + + + + + +? ?????????? proxy_pass, fastcgi_pass, scgi_pass ? uwsgi_pass +??? ????????????? ??????????.
+??????? Piotr Sikora. +
+ +in the "proxy_pass", "fastcgi_pass", "scgi_pass", and "uwsgi_pass" directives +when using variables.
+Thanks to Piotr Sikora. +
+
+ + + +? ?????? ngx_http_sub_filter_module. + + +in the ngx_http_sub_filter_module. + + + + + +???? ? ?????????????? ?????????? ? ??????? ??????????? ??????, +?????? ??????????? ?? ?????? ?????? +??? ????? ????????? proxy_next_upstream. + + +if an error occurred in a cached backend connection, +the request was passed to the next server +regardless of the proxy_next_upstream directive. + + + + + +?????? "CreateFile() failed" ??? ???????? ????????? ?????? ?? Windows. + + +"CreateFile() failed" errors when creating temporary files on Windows. + + + +
+ + From mdounin at mdounin.ru Tue Mar 29 15:13:14 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 29 Mar 2016 15:13:14 +0000 Subject: [nginx] release-1.9.13 tag Message-ID: details: http://hg.nginx.org/nginx/rev/e3e3a6f1e8fd branches: changeset: 6472:e3e3a6f1e8fd user: Maxim Dounin date: Tue Mar 29 18:09:30 2016 +0300 description: release-1.9.13 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -395,3 +395,4 @@ ef107f3ddc237a3007e2769ec04adde0dcf627fa be00ca08e41a69e585b6aff70a725ed6c9e1a876 release-1.9.10 fe66cff450a95beed36a2515210eb2d7ef62c9d3 release-1.9.11 ead3907d74f90a14d1646f1b2b56ba01d3d11702 release-1.9.12 +5936b7ed929237f1a73b467f662611cdc0309e51 release-1.9.13 From ru at nginx.com Wed Mar 30 08:58:03 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 30 Mar 2016 08:58:03 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/9d7326d3f474 branches: changeset: 6473:9d7326d3f474 user: Ruslan Ermilov date: Wed Mar 30 11:52:07 2016 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r e3e3a6f1e8fd -r 9d7326d3f474 src/core/nginx.h --- a/src/core/nginx.h Tue Mar 29 18:09:30 2016 +0300 +++ b/src/core/nginx.h Wed Mar 30 11:52:07 2016 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1009013 -#define NGINX_VERSION "1.9.13" +#define nginx_version 1009014 +#define NGINX_VERSION "1.9.14" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From ru at nginx.com Wed Mar 30 08:58:06 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 30 Mar 2016 08:58:06 +0000 Subject: [nginx] Style. Message-ID: details: http://hg.nginx.org/nginx/rev/2cd019520210 branches: changeset: 6474:2cd019520210 user: Ruslan Ermilov date: Wed Mar 30 11:52:16 2016 +0300 description: Style. diffstat: src/core/ngx_conf_file.c | 6 +- src/core/ngx_connection.c | 36 ++++++++-------- src/core/ngx_connection.h | 22 ++++---- src/core/ngx_crypt.c | 4 +- src/core/ngx_cycle.h | 40 +++++++++--------- src/core/ngx_file.c | 2 +- src/core/ngx_inet.c | 20 ++++---- src/core/ngx_log.c | 18 ++++---- src/core/ngx_parse_time.c | 2 +- src/core/ngx_slab.c | 8 +- src/core/ngx_syslog.c | 6 +- src/event/modules/ngx_iocp_module.c | 38 ++++++++-------- src/event/ngx_event.h | 2 +- src/event/ngx_event_openssl.c | 6 +- src/event/ngx_event_pipe.c | 10 ++-- src/http/modules/ngx_http_dav_module.c | 10 ++-- src/http/modules/ngx_http_fastcgi_module.c | 10 ++-- src/http/modules/ngx_http_image_filter_module.c | 2 +- src/http/modules/ngx_http_mp4_module.c | 16 +++--- src/http/modules/ngx_http_range_filter_module.c | 2 +- src/http/modules/ngx_http_realip_module.c | 4 +- src/http/modules/ngx_http_referer_module.c | 2 +- src/http/modules/ngx_http_rewrite_module.c | 2 +- src/http/modules/ngx_http_scgi_module.c | 2 +- src/http/modules/ngx_http_ssl_module.c | 4 +- src/http/modules/ngx_http_upstream_least_conn_module.c | 2 +- src/http/ngx_http_core_module.c | 36 ++++++++-------- src/http/ngx_http_core_module.h | 8 +- src/http/ngx_http_script.c | 4 +- src/http/ngx_http_upstream.c | 30 ++++++------ src/http/ngx_http_upstream_round_robin.c | 2 +- src/http/v2/ngx_http_v2_module.c | 2 +- src/mail/ngx_mail.h | 2 +- src/mail/ngx_mail_smtp_handler.c | 2 +- src/mail/ngx_mail_ssl_module.c | 6 +- src/os/unix/ngx_atomic.h | 20 ++++---- src/os/unix/ngx_channel.h | 8 +- src/os/unix/ngx_sunpro_amd64.il | 6 +- src/os/unix/ngx_sunpro_x86.il | 6 +- src/os/win32/ngx_atomic.h | 8 +- src/os/win32/ngx_wsasend_chain.c | 10 ++-- src/stream/ngx_stream_upstream_least_conn_module.c | 2 +- src/stream/ngx_stream_upstream_round_robin.c | 2 +- 43 files changed, 215 insertions(+), 215 deletions(-) diffs (truncated from 1001 to 1000 lines): diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_conf_file.c Wed Mar 30 11:52:16 2016 +0300 @@ -613,9 +613,9 @@ ngx_conf_read_token(ngx_conf_t *cf) need_space = 0; } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unexpected \"%c\"", ch); - return NGX_ERROR; + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unexpected \"%c\"", ch); + return NGX_ERROR; } } diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_connection.c --- a/src/core/ngx_connection.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_connection.c Wed Mar 30 11:52:16 2016 +0300 @@ -47,21 +47,21 @@ ngx_create_listening(ngx_conf_t *cf, voi switch (ls->sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: - ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN; - break; + ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN; + break; #endif #if (NGX_HAVE_UNIX_DOMAIN) case AF_UNIX: - ls->addr_text_max_len = NGX_UNIX_ADDRSTRLEN; - len++; - break; + ls->addr_text_max_len = NGX_UNIX_ADDRSTRLEN; + len++; + break; #endif case AF_INET: - ls->addr_text_max_len = NGX_INET_ADDRSTRLEN; - break; + ls->addr_text_max_len = NGX_INET_ADDRSTRLEN; + break; default: - ls->addr_text_max_len = NGX_SOCKADDR_STRLEN; - break; + ls->addr_text_max_len = NGX_SOCKADDR_STRLEN; + break; } ls->addr_text.data = ngx_pnalloc(cf->pool, len); @@ -168,22 +168,22 @@ ngx_set_inherited_sockets(ngx_cycle_t *c #if (NGX_HAVE_INET6) case AF_INET6: - ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN; - len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1; - break; + ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN; + len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1; + break; #endif #if (NGX_HAVE_UNIX_DOMAIN) case AF_UNIX: - ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN; - len = NGX_UNIX_ADDRSTRLEN; - break; + ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN; + len = NGX_UNIX_ADDRSTRLEN; + break; #endif case AF_INET: - ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN; - len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1; - break; + ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN; + len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1; + break; default: ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_connection.h Wed Mar 30 11:52:16 2016 +0300 @@ -95,25 +95,25 @@ struct ngx_listening_s { typedef enum { - NGX_ERROR_ALERT = 0, - NGX_ERROR_ERR, - NGX_ERROR_INFO, - NGX_ERROR_IGNORE_ECONNRESET, - NGX_ERROR_IGNORE_EINVAL + NGX_ERROR_ALERT = 0, + NGX_ERROR_ERR, + NGX_ERROR_INFO, + NGX_ERROR_IGNORE_ECONNRESET, + NGX_ERROR_IGNORE_EINVAL } ngx_connection_log_error_e; typedef enum { - NGX_TCP_NODELAY_UNSET = 0, - NGX_TCP_NODELAY_SET, - NGX_TCP_NODELAY_DISABLED + NGX_TCP_NODELAY_UNSET = 0, + NGX_TCP_NODELAY_SET, + NGX_TCP_NODELAY_DISABLED } ngx_connection_tcp_nodelay_e; typedef enum { - NGX_TCP_NOPUSH_UNSET = 0, - NGX_TCP_NOPUSH_SET, - NGX_TCP_NOPUSH_DISABLED + NGX_TCP_NOPUSH_UNSET = 0, + NGX_TCP_NOPUSH_SET, + NGX_TCP_NOPUSH_DISABLED } ngx_connection_tcp_nopush_e; diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_crypt.c --- a/src/core/ngx_crypt.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_crypt.c Wed Mar 30 11:52:16 2016 +0300 @@ -165,8 +165,8 @@ ngx_crypt_to64(u_char *p, uint32_t v, si "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; while (n--) { - *p++ = itoa64[v & 0x3f]; - v >>= 6; + *p++ = itoa64[v & 0x3f]; + v >>= 6; } return p; diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_cycle.h Wed Mar 30 11:52:16 2016 +0300 @@ -79,35 +79,35 @@ struct ngx_cycle_s { typedef struct { - ngx_flag_t daemon; - ngx_flag_t master; + ngx_flag_t daemon; + ngx_flag_t master; - ngx_msec_t timer_resolution; + ngx_msec_t timer_resolution; - ngx_int_t worker_processes; - ngx_int_t debug_points; + ngx_int_t worker_processes; + ngx_int_t debug_points; - ngx_int_t rlimit_nofile; - off_t rlimit_core; + ngx_int_t rlimit_nofile; + off_t rlimit_core; - int priority; + int priority; - ngx_uint_t cpu_affinity_auto; - ngx_uint_t cpu_affinity_n; - ngx_cpuset_t *cpu_affinity; + ngx_uint_t cpu_affinity_auto; + ngx_uint_t cpu_affinity_n; + ngx_cpuset_t *cpu_affinity; - char *username; - ngx_uid_t user; - ngx_gid_t group; + char *username; + ngx_uid_t user; + ngx_gid_t group; - ngx_str_t working_directory; - ngx_str_t lock_file; + ngx_str_t working_directory; + ngx_str_t lock_file; - ngx_str_t pid; - ngx_str_t oldpid; + ngx_str_t pid; + ngx_str_t oldpid; - ngx_array_t env; - char **environment; + ngx_array_t env; + char **environment; } ngx_core_conf_t; diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_file.c --- a/src/core/ngx_file.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_file.c Wed Mar 30 11:52:16 2016 +0300 @@ -155,7 +155,7 @@ ngx_create_temp_file(ngx_file_t *file, n #if 0 for (i = 0; i < file->name.len; i++) { - file->name.data[i] = 'X'; + file->name.data[i] = 'X'; } #endif diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_inet.c --- a/src/core/ngx_inet.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_inet.c Wed Mar 30 11:52:16 2016 +0300 @@ -1242,19 +1242,19 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, s #if (NGX_HAVE_UNIX_DOMAIN) case AF_UNIX: - /* TODO length */ + /* TODO length */ - saun1 = (struct sockaddr_un *) sa1; - saun2 = (struct sockaddr_un *) sa2; + saun1 = (struct sockaddr_un *) sa1; + saun2 = (struct sockaddr_un *) sa2; - if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path, - sizeof(saun1->sun_path)) - != 0) - { - return NGX_DECLINED; - } + if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path, + sizeof(saun1->sun_path)) + != 0) + { + return NGX_DECLINED; + } - break; + break; #endif default: /* AF_INET */ diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_log.c --- a/src/core/ngx_log.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_log.c Wed Mar 30 11:52:16 2016 +0300 @@ -33,14 +33,14 @@ typedef struct { static ngx_command_t ngx_errlog_commands[] = { - {ngx_string("error_log"), - NGX_MAIN_CONF|NGX_CONF_1MORE, - ngx_error_log, - 0, - 0, - NULL}, + { ngx_string("error_log"), + NGX_MAIN_CONF|NGX_CONF_1MORE, + ngx_error_log, + 0, + 0, + NULL }, - ngx_null_command + ngx_null_command }; @@ -585,7 +585,7 @@ ngx_log_set_log(ngx_conf_t *cf, ngx_log_ return NGX_CONF_ERROR; } - } else if (ngx_strncmp(value[1].data, "memory:", 7) == 0) { + } else if (ngx_strncmp(value[1].data, "memory:", 7) == 0) { #if (NGX_DEBUG) size_t size, needed; @@ -644,7 +644,7 @@ ngx_log_set_log(ngx_conf_t *cf, ngx_log_ return NGX_CONF_ERROR; #endif - } else if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) { + } else if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) { peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t)); if (peer == NULL) { return NGX_CONF_ERROR; diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_parse_time.c --- a/src/core/ngx_parse_time.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_parse_time.c Wed Mar 30 11:52:16 2016 +0300 @@ -220,7 +220,7 @@ ngx_parse_http_time(u_char *value, size_ } if (hour > 23 || min > 59 || sec > 59) { - return NGX_ERROR; + return NGX_ERROR; } if (day == 29 && month == 1) { diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_slab.c --- a/src/core/ngx_slab.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_slab.c Wed Mar 30 11:52:16 2016 +0300 @@ -222,11 +222,11 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p if (bitmap[n] == NGX_SLAB_BUSY) { for (n = n + 1; n < map; n++) { - if (bitmap[n] != NGX_SLAB_BUSY) { - p = (uintptr_t) bitmap + i; + if (bitmap[n] != NGX_SLAB_BUSY) { + p = (uintptr_t) bitmap + i; - goto done; - } + goto done; + } } prev = (ngx_slab_page_t *) diff -r 9d7326d3f474 -r 2cd019520210 src/core/ngx_syslog.c --- a/src/core/ngx_syslog.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/core/ngx_syslog.c Wed Mar 30 11:52:16 2016 +0300 @@ -10,9 +10,9 @@ #define NGX_SYSLOG_MAX_STR \ - NGX_MAX_ERROR_STR + sizeof("<255>Jan 01 00:00:00 ") - 1 \ - + (NGX_MAXHOSTNAMELEN - 1) + 1 /* space */ \ - + 32 /* tag */ + 2 /* colon, space */ + NGX_MAX_ERROR_STR + sizeof("<255>Jan 01 00:00:00 ") - 1 \ + + (NGX_MAXHOSTNAMELEN - 1) + 1 /* space */ \ + + 32 /* tag */ + 2 /* colon, space */ static char *ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer); diff -r 9d7326d3f474 -r 2cd019520210 src/event/modules/ngx_iocp_module.c --- a/src/event/modules/ngx_iocp_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/event/modules/ngx_iocp_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -27,28 +27,28 @@ static ngx_str_t iocp_name = ngx_st static ngx_command_t ngx_iocp_commands[] = { - {ngx_string("iocp_threads"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_iocp_conf_t, threads), - NULL}, + { ngx_string("iocp_threads"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_iocp_conf_t, threads), + NULL }, - {ngx_string("post_acceptex"), - NGX_EVENT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - 0, - offsetof(ngx_iocp_conf_t, post_acceptex), - NULL}, + { ngx_string("post_acceptex"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_iocp_conf_t, post_acceptex), + NULL }, - {ngx_string("acceptex_read"), - NGX_EVENT_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - 0, - offsetof(ngx_iocp_conf_t, acceptex_read), - NULL}, + { ngx_string("acceptex_read"), + NGX_EVENT_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + 0, + offsetof(ngx_iocp_conf_t, acceptex_read), + NULL }, - ngx_null_command + ngx_null_command }; diff -r 9d7326d3f474 -r 2cd019520210 src/event/ngx_event.h --- a/src/event/ngx_event.h Wed Mar 30 11:52:07 2016 +0300 +++ b/src/event/ngx_event.h Wed Mar 30 11:52:16 2016 +0300 @@ -188,7 +188,7 @@ typedef struct { ngx_int_t (*notify)(ngx_event_handler_pt handler); ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer, - ngx_uint_t flags); + ngx_uint_t flags); ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer); void (*done)(ngx_cycle_t *cycle); diff -r 9d7326d3f474 -r 2cd019520210 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/event/ngx_event_openssl.c Wed Mar 30 11:52:16 2016 +0300 @@ -2542,9 +2542,9 @@ done: void ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) { - SSL_CTX_remove_session(ssl, sess); - - ngx_ssl_remove_session(ssl, sess); + SSL_CTX_remove_session(ssl, sess); + + ngx_ssl_remove_session(ssl, sess); } diff -r 9d7326d3f474 -r 2cd019520210 src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/event/ngx_event_pipe.c Wed Mar 30 11:52:16 2016 +0300 @@ -434,7 +434,7 @@ ngx_event_pipe_read_upstream(ngx_event_p /* STUB */ cl->buf->num = p->num++; if (p->input_filter(p, cl->buf) == NGX_ERROR) { - return NGX_ABORT; + return NGX_ABORT; } ngx_free_chain(p->pool, cl); @@ -801,12 +801,12 @@ ngx_event_pipe_write_chain_to_temp_file( } if (cl) { - p->in = cl; - *ll = NULL; + p->in = cl; + *ll = NULL; } else { - p->in = NULL; - p->last_in = &p->in; + p->in = NULL; + p->last_in = &p->in; } } else { diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_dav_module.c --- a/src/http/modules/ngx_http_dav_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_dav_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -621,11 +621,11 @@ destination_done: if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/') || (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/')) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "both URI \"%V\" and \"Destination\" URI \"%V\" " - "should be either collections or non-collections", - &r->uri, &dest->value); - return NGX_HTTP_CONFLICT; + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "both URI \"%V\" and \"Destination\" URI \"%V\" " + "should be either collections or non-collections", + &r->uri, &dest->value); + return NGX_HTTP_CONFLICT; } depth = ngx_http_dav_depth(r, NGX_HTTP_DAV_INFINITY_DEPTH); diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_fastcgi_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -751,7 +751,7 @@ ngx_http_fastcgi_eval(ngx_http_request_t url.no_resolve = 1; if (ngx_parse_url(r->pool, &url) != NGX_OK) { - if (url.err) { + if (url.err) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s in upstream \"%V\"", url.err, &url.url); } @@ -1800,7 +1800,7 @@ ngx_http_fastcgi_process_header(ngx_http } else { r->cache->header_start += u->buffer.pos - start - - sizeof(ngx_http_fastcgi_header_t); + - sizeof(ngx_http_fastcgi_header_t); } f->large_stderr = 0; @@ -2558,8 +2558,8 @@ ngx_http_fastcgi_process_record(ngx_http case NGX_HTTP_FASTCGI_STDOUT: case NGX_HTTP_FASTCGI_STDERR: case NGX_HTTP_FASTCGI_END_REQUEST: - f->type = (ngx_uint_t) ch; - break; + f->type = (ngx_uint_t) ch; + break; default: ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent invalid FastCGI " @@ -2654,7 +2654,7 @@ ngx_http_fastcgi_finalize_request(ngx_ht static ngx_int_t ngx_http_fastcgi_add_variables(ngx_conf_t *cf) { - ngx_http_variable_t *var, *v; + ngx_http_variable_t *var, *v; for (v = ngx_http_fastcgi_vars; v->name.len; v++) { var = ngx_http_add_variable(cf, &v->name, v->flags); diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_image_filter_module.c --- a/src/http/modules/ngx_http_image_filter_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_image_filter_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -144,7 +144,7 @@ static ngx_command_t ngx_http_image_fil offsetof(ngx_http_image_filter_conf_t, transparency), NULL }, - { ngx_string("image_filter_interlace"), + { ngx_string("image_filter_interlace"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_mp4_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -2555,14 +2555,14 @@ ngx_http_mp4_crop_ctts_data(ngx_http_mp4 "sample:%uD, count:%uD, offset:%uD", start_sample, count, ngx_mp4_get_32value(entry->offset)); - if (start_sample <= count) { - rest = start_sample - 1; - goto found; - } - - start_sample -= count; - entries--; - entry++; + if (start_sample <= count) { + rest = start_sample - 1; + goto found; + } + + start_sample -= count; + entries--; + entry++; } if (start) { diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_range_filter_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -665,7 +665,7 @@ ngx_http_range_test_overlapped(ngx_http_ range = ctx->ranges.elts; for (i = 0; i < ctx->ranges.nelts; i++) { if (start > range[i].start || last < range[i].end) { - goto overlapped; + goto overlapped; } } } diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_realip_module.c --- a/src/http/modules/ngx_http_realip_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_realip_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -328,8 +328,8 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx #if (NGX_HAVE_UNIX_DOMAIN) if (ngx_strcmp(value[1].data, "unix:") == 0) { - cidr->family = AF_UNIX; - return NGX_CONF_OK; + cidr->family = AF_UNIX; + return NGX_CONF_OK; } #endif diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_referer_module.c --- a/src/http/modules/ngx_http_referer_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_referer_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -109,7 +109,7 @@ ngx_module_t ngx_http_referer_module = static ngx_int_t ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, - uintptr_t data) + uintptr_t data) { u_char *p, *ref, *last; size_t len; diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_rewrite_module.c --- a/src/http/modules/ngx_http_rewrite_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_rewrite_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -571,7 +571,7 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_ mconf = module->create_loc_conf(cf); if (mconf == NULL) { - return NGX_CONF_ERROR; + return NGX_CONF_ERROR; } ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf; diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_scgi_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -876,7 +876,7 @@ ngx_http_scgi_create_request(ngx_http_re next: continue; - } + } } *b->last++ = (u_char) ','; diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_ssl_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -337,8 +337,8 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t #if (NGX_DEBUG) for (i = 0; i < inlen; i += in[i] + 1) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, - "SSL ALPN supported by client: %*s", in[i], &in[i + 1]); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "SSL ALPN supported by client: %*s", in[i], &in[i + 1]); } #endif diff -r 9d7326d3f474 -r 2cd019520210 src/http/modules/ngx_http_upstream_least_conn_module.c --- a/src/http/modules/ngx_http_upstream_least_conn_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/modules/ngx_http_upstream_least_conn_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -259,7 +259,7 @@ failed: / (8 * sizeof(uintptr_t)); for (i = 0; i < n; i++) { - rrp->tried[i] = 0; + rrp->tried[i] = 0; } ngx_http_upstream_rr_peers_unlock(peers); diff -r 9d7326d3f474 -r 2cd019520210 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/ngx_http_core_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -1222,7 +1222,7 @@ ngx_http_core_try_files_phase(ngx_http_r } name = path.data + root; - } + } if (tf->values == NULL) { @@ -3104,7 +3104,7 @@ ngx_http_core_location(ngx_conf_t *cf, n ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = module->create_loc_conf(cf); if (ctx->loc_conf[cf->cycle->modules[i]->ctx_index] == NULL) { - return NGX_CONF_ERROR; + return NGX_CONF_ERROR; } } } @@ -4540,21 +4540,21 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_c static ngx_http_method_name_t ngx_methods_names[] = { - { (u_char *) "GET", (uint32_t) ~NGX_HTTP_GET }, - { (u_char *) "HEAD", (uint32_t) ~NGX_HTTP_HEAD }, - { (u_char *) "POST", (uint32_t) ~NGX_HTTP_POST }, - { (u_char *) "PUT", (uint32_t) ~NGX_HTTP_PUT }, - { (u_char *) "DELETE", (uint32_t) ~NGX_HTTP_DELETE }, - { (u_char *) "MKCOL", (uint32_t) ~NGX_HTTP_MKCOL }, - { (u_char *) "COPY", (uint32_t) ~NGX_HTTP_COPY }, - { (u_char *) "MOVE", (uint32_t) ~NGX_HTTP_MOVE }, - { (u_char *) "OPTIONS", (uint32_t) ~NGX_HTTP_OPTIONS }, - { (u_char *) "PROPFIND", (uint32_t) ~NGX_HTTP_PROPFIND }, - { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH }, - { (u_char *) "LOCK", (uint32_t) ~NGX_HTTP_LOCK }, - { (u_char *) "UNLOCK", (uint32_t) ~NGX_HTTP_UNLOCK }, - { (u_char *) "PATCH", (uint32_t) ~NGX_HTTP_PATCH }, - { NULL, 0 } + { (u_char *) "GET", (uint32_t) ~NGX_HTTP_GET }, + { (u_char *) "HEAD", (uint32_t) ~NGX_HTTP_HEAD }, + { (u_char *) "POST", (uint32_t) ~NGX_HTTP_POST }, + { (u_char *) "PUT", (uint32_t) ~NGX_HTTP_PUT }, + { (u_char *) "DELETE", (uint32_t) ~NGX_HTTP_DELETE }, + { (u_char *) "MKCOL", (uint32_t) ~NGX_HTTP_MKCOL }, + { (u_char *) "COPY", (uint32_t) ~NGX_HTTP_COPY }, + { (u_char *) "MOVE", (uint32_t) ~NGX_HTTP_MOVE }, + { (u_char *) "OPTIONS", (uint32_t) ~NGX_HTTP_OPTIONS }, + { (u_char *) "PROPFIND", (uint32_t) ~NGX_HTTP_PROPFIND }, + { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH }, + { (u_char *) "LOCK", (uint32_t) ~NGX_HTTP_LOCK }, + { (u_char *) "UNLOCK", (uint32_t) ~NGX_HTTP_UNLOCK }, + { (u_char *) "PATCH", (uint32_t) ~NGX_HTTP_PATCH }, + { NULL, 0 } }; @@ -4627,7 +4627,7 @@ ngx_http_core_limit_except(ngx_conf_t *c mconf = module->create_loc_conf(cf); if (mconf == NULL) { - return NGX_CONF_ERROR; + return NGX_CONF_ERROR; } ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf; diff -r 9d7326d3f474 -r 2cd019520210 src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/ngx_http_core_module.h Wed Mar 30 11:52:16 2016 +0300 @@ -232,10 +232,10 @@ typedef struct { typedef struct { - ngx_hash_combined_t names; + ngx_hash_combined_t names; - ngx_uint_t nregex; - ngx_http_server_name_t *regex; + ngx_uint_t nregex; + ngx_http_server_name_t *regex; } ngx_http_virtual_names_t; @@ -544,7 +544,7 @@ typedef ngx_int_t (*ngx_http_request_bod ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *chain); ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *chain); ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r, - ngx_chain_t *chain); + ngx_chain_t *chain); ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r, diff -r 9d7326d3f474 -r 2cd019520210 src/http/ngx_http_script.c --- a/src/http/ngx_http_script.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/ngx_http_script.c Wed Mar 30 11:52:16 2016 +0300 @@ -19,10 +19,10 @@ static ngx_int_t ngx_http_script_add_var static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc); #if (NGX_PCRE) static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, - ngx_uint_t n); + ngx_uint_t n); #endif static ngx_int_t - ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc); + ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc); static size_t ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e); static void ngx_http_script_full_name_code(ngx_http_script_engine_t *e); diff -r 9d7326d3f474 -r 2cd019520210 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/ngx_http_upstream.c Wed Mar 30 11:52:16 2016 +0300 @@ -1883,17 +1883,17 @@ ngx_http_upstream_send_request_body(ngx_ if (!r->request_body_no_buffering) { - /* buffered request body */ - - if (!u->request_sent) { - u->request_sent = 1; - out = u->request_bufs; - - } else { - out = NULL; - } - - return ngx_output_chain(&u->output, out); + /* buffered request body */ + + if (!u->request_sent) { + u->request_sent = 1; + out = u->request_bufs; + + } else { + out = NULL; + } + + return ngx_output_chain(&u->output, out); } if (!u->request_sent) { @@ -4327,10 +4327,10 @@ ngx_http_upstream_process_cache_control( pa = &u->headers_in.cache_control; if (pa->elts == NULL) { - if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) - { - return NGX_ERROR; - } + if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) + { + return NGX_ERROR; + } } ph = ngx_array_push(pa); diff -r 9d7326d3f474 -r 2cd019520210 src/http/ngx_http_upstream_round_robin.c --- a/src/http/ngx_http_upstream_round_robin.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/ngx_http_upstream_round_robin.c Wed Mar 30 11:52:16 2016 +0300 @@ -480,7 +480,7 @@ failed: / (8 * sizeof(uintptr_t)); for (i = 0; i < n; i++) { - rrp->tried[i] = 0; + rrp->tried[i] = 0; } ngx_http_upstream_rr_peers_unlock(peers); diff -r 9d7326d3f474 -r 2cd019520210 src/http/v2/ngx_http_v2_module.c --- a/src/http/v2/ngx_http_v2_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/http/v2/ngx_http_v2_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -215,7 +215,7 @@ static ngx_http_variable_t ngx_http_v2_ static ngx_int_t ngx_http_v2_add_variables(ngx_conf_t *cf) { - ngx_http_variable_t *var, *v; + ngx_http_variable_t *var, *v; for (v = ngx_http_v2_vars; v->name.len; v++) { var = ngx_http_add_variable(cf, &v->name, v->flags); diff -r 9d7326d3f474 -r 2cd019520210 src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h Wed Mar 30 11:52:07 2016 +0300 +++ b/src/mail/ngx_mail.h Wed Mar 30 11:52:16 2016 +0300 @@ -342,7 +342,7 @@ typedef struct { void *(*create_srv_conf)(ngx_conf_t *cf); char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, - void *conf); + void *conf); } ngx_mail_module_t; diff -r 9d7326d3f474 -r 2cd019520210 src/mail/ngx_mail_smtp_handler.c --- a/src/mail/ngx_mail_smtp_handler.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/mail/ngx_mail_smtp_handler.c Wed Mar 30 11:52:16 2016 +0300 @@ -42,7 +42,7 @@ static u_char smtp_username[] = "334 VX static u_char smtp_password[] = "334 UGFzc3dvcmQ6" CRLF; static u_char smtp_invalid_command[] = "500 5.5.1 Invalid command" CRLF; static u_char smtp_invalid_pipelining[] = - "503 5.5.0 Improper use of SMTP command pipelining" CRLF; + "503 5.5.0 Improper use of SMTP command pipelining" CRLF; static u_char smtp_invalid_argument[] = "501 5.5.4 Invalid argument" CRLF; static u_char smtp_auth_required[] = "530 5.7.1 Authentication required" CRLF; static u_char smtp_bad_sequence[] = "503 5.5.1 Bad sequence of commands" CRLF; diff -r 9d7326d3f474 -r 2cd019520210 src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/mail/ngx_mail_ssl_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -312,13 +312,13 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, conf->ssl.log = cf->log; if (conf->enable) { - mode = "ssl"; + mode = "ssl"; } else if (conf->starttls != NGX_MAIL_STARTTLS_OFF) { - mode = "starttls"; + mode = "starttls"; } else { - mode = ""; + mode = ""; } if (conf->file == NULL) { diff -r 9d7326d3f474 -r 2cd019520210 src/os/unix/ngx_atomic.h --- a/src/os/unix/ngx_atomic.h Wed Mar 30 11:52:07 2016 +0300 +++ b/src/os/unix/ngx_atomic.h Wed Mar 30 11:52:16 2016 +0300 @@ -276,26 +276,26 @@ typedef volatile ngx_atomic_uint_t ngx_ static ngx_inline ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, - ngx_atomic_uint_t set) + ngx_atomic_uint_t set) { - if (*lock == old) { - *lock = set; - return 1; - } + if (*lock == old) { + *lock = set; + return 1; + } - return 0; + return 0; } static ngx_inline ngx_atomic_int_t ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) { - ngx_atomic_int_t old; + ngx_atomic_int_t old; - old = *value; - *value += add; + old = *value; + *value += add; - return old; + return old; } #define ngx_memory_barrier() diff -r 9d7326d3f474 -r 2cd019520210 src/os/unix/ngx_channel.h --- a/src/os/unix/ngx_channel.h Wed Mar 30 11:52:07 2016 +0300 +++ b/src/os/unix/ngx_channel.h Wed Mar 30 11:52:16 2016 +0300 @@ -15,10 +15,10 @@ typedef struct { - ngx_uint_t command; - ngx_pid_t pid; - ngx_int_t slot; - ngx_fd_t fd; + ngx_uint_t command; + ngx_pid_t pid; + ngx_int_t slot; + ngx_fd_t fd; } ngx_channel_t; diff -r 9d7326d3f474 -r 2cd019520210 src/os/unix/ngx_sunpro_amd64.il --- a/src/os/unix/ngx_sunpro_amd64.il Wed Mar 30 11:52:07 2016 +0300 +++ b/src/os/unix/ngx_sunpro_amd64.il Wed Mar 30 11:52:16 2016 +0300 @@ -38,6 +38,6 @@ / / ld.so.1: nginx: fatal: hardware capability unsupported: 0x2000 [ PAUSE ] - .inline ngx_cpu_pause,0 - rep; nop - .end + .inline ngx_cpu_pause,0 + rep; nop + .end diff -r 9d7326d3f474 -r 2cd019520210 src/os/unix/ngx_sunpro_x86.il --- a/src/os/unix/ngx_sunpro_x86.il Wed Mar 30 11:52:07 2016 +0300 +++ b/src/os/unix/ngx_sunpro_x86.il Wed Mar 30 11:52:16 2016 +0300 @@ -39,6 +39,6 @@ / / ld.so.1: nginx: fatal: hardware capability unsupported: 0x2000 [ PAUSE ] - .inline ngx_cpu_pause,0 - rep; nop - .end + .inline ngx_cpu_pause,0 + rep; nop + .end diff -r 9d7326d3f474 -r 2cd019520210 src/os/win32/ngx_atomic.h --- a/src/os/win32/ngx_atomic.h Wed Mar 30 11:52:07 2016 +0300 +++ b/src/os/win32/ngx_atomic.h Wed Mar 30 11:52:16 2016 +0300 @@ -27,16 +27,16 @@ typedef volatile ngx_atomic_uint_t ngx_ /* the new SDK headers */ #define ngx_atomic_cmp_set(lock, old, set) \ - ((ngx_atomic_uint_t) InterlockedCompareExchange((long *) lock, set, old) \ - == old) + ((ngx_atomic_uint_t) InterlockedCompareExchange((long *) lock, set, old) \ + == old) #else /* the old MS VC6.0SP2 SDK headers */ #define ngx_atomic_cmp_set(lock, old, set) \ - (InterlockedCompareExchange((void **) lock, (void *) set, (void *) old) \ - == (void *) old) + (InterlockedCompareExchange((void **) lock, (void *) set, (void *) old) \ + == (void *) old) #endif diff -r 9d7326d3f474 -r 2cd019520210 src/os/win32/ngx_wsasend_chain.c --- a/src/os/win32/ngx_wsasend_chain.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/os/win32/ngx_wsasend_chain.c Wed Mar 30 11:52:16 2016 +0300 @@ -233,11 +233,11 @@ ngx_overlapped_wsasend_chain(ngx_connect } else if (ngx_event_flags & NGX_USE_IOCP_EVENT) { - /* - * if a socket was bound with I/O completion port then - * GetQueuedCompletionStatus() would anyway return its status - * despite that WSASend() was already complete - */ + /* + * if a socket was bound with I/O completion port then + * GetQueuedCompletionStatus() would anyway return its status + * despite that WSASend() was already complete + */ wev->active = 1; return in; diff -r 9d7326d3f474 -r 2cd019520210 src/stream/ngx_stream_upstream_least_conn_module.c --- a/src/stream/ngx_stream_upstream_least_conn_module.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/stream/ngx_stream_upstream_least_conn_module.c Wed Mar 30 11:52:16 2016 +0300 @@ -254,7 +254,7 @@ failed: / (8 * sizeof(uintptr_t)); for (i = 0; i < n; i++) { - rrp->tried[i] = 0; + rrp->tried[i] = 0; } ngx_stream_upstream_rr_peers_unlock(peers); diff -r 9d7326d3f474 -r 2cd019520210 src/stream/ngx_stream_upstream_round_robin.c --- a/src/stream/ngx_stream_upstream_round_robin.c Wed Mar 30 11:52:07 2016 +0300 +++ b/src/stream/ngx_stream_upstream_round_robin.c Wed Mar 30 11:52:16 2016 +0300 @@ -356,7 +356,7 @@ failed: / (8 * sizeof(uintptr_t)); for (i = 0; i < n; i++) { - rrp->tried[i] = 0; + rrp->tried[i] = 0; } From ru at nginx.com Wed Mar 30 08:58:09 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 30 Mar 2016 08:58:09 +0000 Subject: [nginx] Events: fixed test building with eventport on OS X. Message-ID: details: http://hg.nginx.org/nginx/rev/7d6970ba5209 branches: changeset: 6475:7d6970ba5209 user: Ruslan Ermilov date: Wed Mar 30 11:57:28 2016 +0300 description: Events: fixed test building with eventport on OS X. Broken in d17f0584006f (1.9.13). diffstat: src/event/modules/ngx_eventport_module.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 2cd019520210 -r 7d6970ba5209 src/event/modules/ngx_eventport_module.c --- a/src/event/modules/ngx_eventport_module.c Wed Mar 30 11:52:16 2016 +0300 +++ b/src/event/modules/ngx_eventport_module.c Wed Mar 30 11:57:28 2016 +0300 @@ -49,7 +49,7 @@ typedef struct port_notify { void *portnfy_user; /* user defined */ } port_notify_t; -#if (__FreeBSD__) && (__FreeBSD_version < 700005) +#if (__FreeBSD__ && __FreeBSD_version < 700005) || (NGX_DARWIN) typedef struct itimerspec { /* definition per POSIX.4 */ struct timespec it_interval;/* timer period */ From ru at nginx.com Wed Mar 30 09:07:33 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 30 Mar 2016 09:07:33 +0000 Subject: [nginx] Fixed mistranslated phrase. Message-ID: details: http://hg.nginx.org/nginx/rev/5511e846dfc7 branches: changeset: 6476:5511e846dfc7 user: Ruslan Ermilov date: Wed Mar 30 12:07:19 2016 +0300 description: Fixed mistranslated phrase. diffstat: docs/xml/nginx/changes.xml | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 7d6970ba5209 -r 5511e846dfc7 docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml Wed Mar 30 11:57:28 2016 +0300 +++ b/docs/xml/nginx/changes.xml Wed Mar 30 12:07:19 2016 +0300 @@ -6365,7 +6365,7 @@ successfully respond to the request. ?????? ??????? 0x7F-0xFF ? access_log ???????????? ? ???? \xXX. -now the 0x7F-0x1F characters are escaped as \xXX in an access_log. +now the 0x7F-0xFF characters are escaped as \xXX in an access_log. From pluknet at nginx.com Wed Mar 30 23:35:03 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Wed, 30 Mar 2016 23:35:03 +0000 Subject: [nginx] Fixed logging in close error handling. Message-ID: details: http://hg.nginx.org/nginx/rev/47daf95d0138 branches: changeset: 6477:47daf95d0138 user: Sergey Kandaurov date: Thu Mar 31 02:33:50 2016 +0300 description: Fixed logging in close error handling. diffstat: src/core/ngx_open_file_cache.c | 2 +- src/http/modules/ngx_http_random_index_module.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff -r 5511e846dfc7 -r 47daf95d0138 src/core/ngx_open_file_cache.c --- a/src/core/ngx_open_file_cache.c Wed Mar 30 12:07:19 2016 +0300 +++ b/src/core/ngx_open_file_cache.c Thu Mar 31 02:33:50 2016 +0300 @@ -544,7 +544,7 @@ failed: if (ngx_close_file(fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - ngx_close_file_n " \"%V\" failed", name); + ngx_close_file_n " \"%s\" failed", name); } ngx_set_errno(err); diff -r 5511e846dfc7 -r 47daf95d0138 src/http/modules/ngx_http_random_index_module.c --- a/src/http/modules/ngx_http_random_index_module.c Wed Mar 30 12:07:19 2016 +0300 +++ b/src/http/modules/ngx_http_random_index_module.c Thu Mar 31 02:33:50 2016 +0300 @@ -230,7 +230,7 @@ ngx_http_random_index_handler(ngx_http_r if (ngx_close_dir(&dir) == NGX_ERROR) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, - ngx_close_dir_n " \"%s\" failed", &path); + ngx_close_dir_n " \"%V\" failed", &path); } n = names.nelts; From pluknet at nginx.com Wed Mar 30 23:35:05 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Wed, 30 Mar 2016 23:35:05 +0000 Subject: [nginx] Fixed logging with variable field width. Message-ID: details: http://hg.nginx.org/nginx/rev/3ef7bb882ad4 branches: changeset: 6478:3ef7bb882ad4 user: Sergey Kandaurov date: Thu Mar 31 02:33:53 2016 +0300 description: Fixed logging with variable field width. diffstat: src/core/ngx_resolver.c | 2 +- src/http/modules/ngx_http_mp4_module.c | 4 ++-- src/http/modules/ngx_http_ssl_module.c | 5 +++-- src/http/ngx_http_core_module.c | 3 ++- src/http/ngx_http_file_cache.c | 2 +- src/http/ngx_http_variables.c | 5 ++--- 6 files changed, 11 insertions(+), 10 deletions(-) diffs (95 lines): diff -r 47daf95d0138 -r 3ef7bb882ad4 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Thu Mar 31 02:33:50 2016 +0300 +++ b/src/core/ngx_resolver.c Thu Mar 31 02:33:53 2016 +0300 @@ -1873,7 +1873,7 @@ dns_error_name: ngx_log_error(r->log_level, r->log, 0, "DNS error (%ui: %s), query id:%ui, name:\"%*s\"", code, ngx_resolver_strerror(code), ident, - rn->nlen, rn->name); + (size_t) rn->nlen, rn->name); return; dns_error: diff -r 47daf95d0138 -r 3ef7bb882ad4 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Thu Mar 31 02:33:50 2016 +0300 +++ b/src/http/modules/ngx_http_mp4_module.c Thu Mar 31 02:33:53 2016 +0300 @@ -913,7 +913,7 @@ ngx_http_mp4_read_atom(ngx_http_mp4_file ngx_log_debug4(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 atom: %*s @%O:%uL", - 4, atom_name, mp4->offset, atom_size); + (size_t) 4, atom_name, mp4->offset, atom_size); if (atom_size > (uint64_t) (NGX_MAX_OFF_T_VALUE - mp4->offset) || mp4->offset + (off_t) atom_size > end) @@ -1958,7 +1958,7 @@ ngx_http_mp4_read_stsd_atom(ngx_http_mp4 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "stsd entries:%uD, media:%*s", ngx_mp4_get_32value(stsd_atom->entries), - 4, stsd_atom->media_name); + (size_t) 4, stsd_atom->media_name); trak = ngx_mp4_last_trak(mp4); diff -r 47daf95d0138 -r 3ef7bb882ad4 src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c Thu Mar 31 02:33:50 2016 +0300 +++ b/src/http/modules/ngx_http_ssl_module.c Thu Mar 31 02:33:53 2016 +0300 @@ -338,7 +338,8 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t #if (NGX_DEBUG) for (i = 0; i < inlen; i += in[i] + 1) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, - "SSL ALPN supported by client: %*s", in[i], &in[i + 1]); + "SSL ALPN supported by client: %*s", + (size_t) in[i], &in[i + 1]); } #endif @@ -365,7 +366,7 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, - "SSL ALPN selected: %*s", *outlen, *out); + "SSL ALPN selected: %*s", (size_t) *outlen, *out); return SSL_TLSEXT_ERR_OK; } diff -r 47daf95d0138 -r 3ef7bb882ad4 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Thu Mar 31 02:33:50 2016 +0300 +++ b/src/http/ngx_http_core_module.c Thu Mar 31 02:33:53 2016 +0300 @@ -1597,7 +1597,8 @@ ngx_http_core_find_static_location(ngx_h } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "test location: \"%*s\"", node->len, node->name); + "test location: \"%*s\"", + (size_t) node->len, node->name); n = (len <= (size_t) node->len) ? len : node->len; diff -r 47daf95d0138 -r 3ef7bb882ad4 src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c Thu Mar 31 02:33:50 2016 +0300 +++ b/src/http/ngx_http_file_cache.c Thu Mar 31 02:33:53 2016 +0300 @@ -1834,7 +1834,7 @@ ngx_http_file_cache_expire(ngx_http_file ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "ignore long locked inactive cache entry %*s, count:%d", - 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count); + (size_t) 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count); } ngx_shmtx_unlock(&cache->shpool->mutex); diff -r 47daf95d0138 -r 3ef7bb882ad4 src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c Thu Mar 31 02:33:50 2016 +0300 +++ b/src/http/ngx_http_variables.c Thu Mar 31 02:33:53 2016 +0300 @@ -2428,9 +2428,8 @@ ngx_http_regex_exec(ngx_http_request_t * v = cmcf->variables.elts; - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http regex set $%V to \"%*s\"", - &v[index].name, vv->len, vv->data); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http regex set $%V to \"%v\"", &v[index].name, vv); } #endif } From pluknet at nginx.com Wed Mar 30 23:35:08 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Wed, 30 Mar 2016 23:35:08 +0000 Subject: [nginx] Events: fixed logging. Message-ID: details: http://hg.nginx.org/nginx/rev/dc92298b1852 branches: changeset: 6479:dc92298b1852 user: Sergey Kandaurov date: Thu Mar 31 02:33:55 2016 +0300 description: Events: fixed logging. diffstat: src/event/modules/ngx_eventport_module.c | 8 ++++---- src/event/modules/ngx_kqueue_module.c | 23 +++++++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diffs (74 lines): diff -r 3ef7bb882ad4 -r dc92298b1852 src/event/modules/ngx_eventport_module.c --- a/src/event/modules/ngx_eventport_module.c Thu Mar 31 02:33:53 2016 +0300 +++ b/src/event/modules/ngx_eventport_module.c Thu Mar 31 02:33:55 2016 +0300 @@ -526,18 +526,18 @@ ngx_eventport_process_events(ngx_cycle_t ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "eventport: fd:%d, ev:%04Xd", - event_list[i].portev_object, revents); + (int) event_list[i].portev_object, revents); if (revents & (POLLERR|POLLHUP|POLLNVAL)) { ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "port_getn() error fd:%d ev:%04Xd", - event_list[i].portev_object, revents); + (int) event_list[i].portev_object, revents); } if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "strange port_getn() events fd:%d ev:%04Xd", - event_list[i].portev_object, revents); + (int) event_list[i].portev_object, revents); } if ((revents & (POLLERR|POLLHUP|POLLNVAL)) @@ -615,7 +615,7 @@ ngx_eventport_process_events(ngx_cycle_t default: ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected eventport object %d", - event_list[i].portev_object); + (int) event_list[i].portev_object); continue; } } diff -r 3ef7bb882ad4 -r dc92298b1852 src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c Thu Mar 31 02:33:53 2016 +0300 +++ b/src/event/modules/ngx_kqueue_module.c Thu Mar 31 02:33:55 2016 +0300 @@ -579,7 +579,7 @@ ngx_kqueue_process_events(ngx_cycle_t *c if (event_list[i].flags & EV_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, event_list[i].data, "kevent() error on %d filter:%d flags:%04Xd", - event_list[i].ident, event_list[i].filter, + (int) event_list[i].ident, event_list[i].filter, event_list[i].flags); continue; } @@ -676,13 +676,20 @@ ngx_kqueue_process_events(ngx_cycle_t *c static ngx_inline void ngx_kqueue_dump_event(ngx_log_t *log, struct kevent *kev) { - ngx_log_debug6(NGX_LOG_DEBUG_EVENT, log, 0, - (kev->ident > 0x8000000 && kev->ident != (unsigned) -1) ? - "kevent: %p: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p": - "kevent: %d: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p", - kev->ident, kev->filter, - kev->flags, kev->fflags, - kev->data, kev->udata); + if (kev->ident > 0x8000000 && kev->ident != (unsigned) -1) { + ngx_log_debug6(NGX_LOG_DEBUG_EVENT, log, 0, + "kevent: %p: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p", + (void *) kev->ident, kev->filter, + kev->flags, kev->fflags, + (int) kev->data, kev->udata); + + } else { + ngx_log_debug6(NGX_LOG_DEBUG_EVENT, log, 0, + "kevent: %d: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p", + (int) kev->ident, kev->filter, + kev->flags, kev->fflags, + (int) kev->data, kev->udata); + } } From pluknet at nginx.com Wed Mar 30 23:35:10 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Wed, 30 Mar 2016 23:35:10 +0000 Subject: [nginx] Fixed logging. Message-ID: details: http://hg.nginx.org/nginx/rev/f01ab2dbcfdc branches: changeset: 6480:f01ab2dbcfdc user: Sergey Kandaurov date: Thu Mar 31 02:33:57 2016 +0300 description: Fixed logging. diffstat: src/core/nginx.c | 2 +- src/core/ngx_cycle.c | 6 +++--- src/core/ngx_file.c | 4 ++-- src/core/ngx_slab.c | 3 ++- src/event/modules/ngx_epoll_module.c | 2 +- src/event/ngx_event.c | 2 +- src/event/ngx_event_openssl.c | 4 ++-- src/event/ngx_event_openssl_stapling.c | 2 +- src/event/ngx_event_pipe.c | 2 +- src/http/modules/ngx_http_auth_basic_module.c | 2 +- src/http/modules/ngx_http_auth_request_module.c | 4 ++-- src/http/modules/ngx_http_chunked_filter_module.c | 2 +- src/http/modules/ngx_http_fastcgi_module.c | 6 +++--- src/http/modules/ngx_http_gzip_filter_module.c | 4 ++-- src/http/modules/ngx_http_image_filter_module.c | 2 +- src/http/modules/ngx_http_limit_conn_module.c | 4 ++-- src/http/modules/ngx_http_map_module.c | 2 +- src/http/modules/ngx_http_memcached_module.c | 2 +- src/http/modules/ngx_http_proxy_module.c | 8 ++++---- src/http/modules/ngx_http_range_filter_module.c | 2 +- src/http/modules/ngx_http_ssi_filter_module.c | 8 ++++---- src/http/modules/ngx_http_sub_filter_module.c | 2 +- src/http/modules/ngx_http_upstream_ip_hash_module.c | 2 +- src/http/ngx_http_request.c | 12 ++++++------ src/http/ngx_http_script.c | 2 +- src/http/ngx_http_write_filter_module.c | 2 +- src/http/v2/ngx_http_v2.c | 2 +- src/mail/ngx_mail_auth_http_module.c | 2 +- src/mail/ngx_mail_proxy_module.c | 2 +- src/os/unix/ngx_file_aio_read.c | 2 +- src/os/unix/ngx_files.c | 2 +- src/os/unix/ngx_linux_aio_read.c | 2 +- src/os/unix/ngx_linux_sendfile_chain.c | 2 +- src/os/unix/ngx_process_cycle.c | 10 +++++----- src/os/unix/ngx_readv_chain.c | 2 +- src/os/unix/ngx_recv.c | 4 ++-- src/os/unix/ngx_send.c | 2 +- src/os/unix/ngx_udp_recv.c | 4 ++-- src/stream/ngx_stream_limit_conn_module.c | 4 ++-- 39 files changed, 67 insertions(+), 66 deletions(-) diffs (706 lines): diff -r dc92298b1852 -r f01ab2dbcfdc src/core/nginx.c --- a/src/core/nginx.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/core/nginx.c Thu Mar 31 02:33:57 2016 +0300 @@ -1510,7 +1510,7 @@ ngx_load_module(ngx_conf_t *cf, ngx_comm return NGX_CONF_ERROR; } - ngx_log_debug2(NGX_LOG_DEBUG_CORE, cf->log, 0, "module: %s i:%i", + ngx_log_debug2(NGX_LOG_DEBUG_CORE, cf->log, 0, "module: %s i:%ui", module->name, module->index); } diff -r dc92298b1852 -r f01ab2dbcfdc src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/core/ngx_cycle.c Thu Mar 31 02:33:57 2016 +0300 @@ -1313,7 +1313,7 @@ ngx_clean_old_cycles(ngx_event_t *ev) if (cycle[i]->connections[n].fd != (ngx_socket_t) -1) { found = 1; - ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "live fd:%d", n); + ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "live fd:%ui", n); break; } @@ -1324,13 +1324,13 @@ ngx_clean_old_cycles(ngx_event_t *ev) continue; } - ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycle: %d", i); + ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycle: %ui", i); ngx_destroy_pool(cycle[i]->pool); cycle[i] = NULL; } - ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "old cycles status: %d", live); + ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "old cycles status: %ui", live); if (live) { ngx_add_timer(ev, 30000); diff -r dc92298b1852 -r f01ab2dbcfdc src/core/ngx_file.c --- a/src/core/ngx_file.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/core/ngx_file.c Thu Mar 31 02:33:57 2016 +0300 @@ -841,7 +841,7 @@ ngx_copy_file(u_char *from, u_char *to, if ((size_t) n != len) { ngx_log_error(NGX_LOG_ALERT, cf->log, 0, - ngx_read_fd_n " has read only %z of %uz from %s", + ngx_read_fd_n " has read only %z of %O from %s", n, size, from); goto failed; } @@ -856,7 +856,7 @@ ngx_copy_file(u_char *from, u_char *to, if ((size_t) n != len) { ngx_log_error(NGX_LOG_ALERT, cf->log, 0, - ngx_write_fd_n " has written only %z of %uz to %s", + ngx_write_fd_n " has written only %z of %O to %s", n, size, to); goto failed; } diff -r dc92298b1852 -r f01ab2dbcfdc src/core/ngx_slab.c --- a/src/core/ngx_slab.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/core/ngx_slab.c Thu Mar 31 02:33:57 2016 +0300 @@ -392,7 +392,8 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p done: - ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p); + ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, + "slab alloc: %p", (void *) p); return (void *) p; } diff -r dc92298b1852 -r f01ab2dbcfdc src/event/modules/ngx_epoll_module.c --- a/src/event/modules/ngx_epoll_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/event/modules/ngx_epoll_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -902,7 +902,7 @@ ngx_epoll_eventfd_handler(ngx_event_t *e events = io_getevents(ngx_aio_ctx, 1, 64, event, &ts); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "io_getevents: %l", events); + "io_getevents: %d", events); if (events > 0) { ready -= events; diff -r dc92298b1852 -r f01ab2dbcfdc src/event/ngx_event.c --- a/src/event/ngx_event.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/event/ngx_event.c Thu Mar 31 02:33:57 2016 +0300 @@ -525,7 +525,7 @@ ngx_event_module_init(ngx_cycle_t *cycle (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "counter: %p, %d", + "counter: %p, %uA", ngx_connection_counter, *ngx_connection_counter); ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl); diff -r dc92298b1852 -r f01ab2dbcfdc src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/event/ngx_event_openssl.c Thu Mar 31 02:33:57 2016 +0300 @@ -1596,7 +1596,7 @@ ngx_ssl_send_chain(ngx_connection_t *c, } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL buf copy: %d", size); + "SSL buf copy: %z", size); ngx_memcpy(buf->last, in->buf->pos, size); @@ -1668,7 +1668,7 @@ ngx_ssl_write(ngx_connection_t *c, u_cha ngx_ssl_clear_error(c->log); - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size); + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size); n = SSL_write(c->ssl->connection, data, size); diff -r dc92298b1852 -r f01ab2dbcfdc src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/event/ngx_event_openssl_stapling.c Thu Mar 31 02:33:57 2016 +0300 @@ -1219,7 +1219,7 @@ ngx_ssl_ocsp_create_request(ngx_ssl_ocsp ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0, "ssl ocsp request length %z, escape %d", - base64.len, escape); + base64.len, (int) escape); len = sizeof("GET ") - 1 + ctx->uri.len + sizeof("/") - 1 + base64.len + 2 * escape + sizeof(" HTTP/1.0" CRLF) - 1 diff -r dc92298b1852 -r f01ab2dbcfdc src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/event/ngx_event_pipe.c Thu Mar 31 02:33:57 2016 +0300 @@ -660,7 +660,7 @@ ngx_event_pipe_write_to_downstream(ngx_e flush: ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0, - "pipe write: out:%p, f:%d", out, flush); + "pipe write: out:%p, f:%ui", out, flush); if (out == NULL) { diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_auth_basic_module.c --- a/src/http/modules/ngx_http_auth_basic_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_auth_basic_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -298,7 +298,7 @@ ngx_http_auth_basic_crypt_handler(ngx_ht &encrypted); ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "rc: %d user: \"%V\" salt: \"%s\"", + "rc: %i user: \"%V\" salt: \"%s\"", rc, &r->headers_in.user, passwd->data); if (rc == NGX_OK) { diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_auth_request_module.c --- a/src/http/modules/ngx_http_auth_request_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_auth_request_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -168,7 +168,7 @@ ngx_http_auth_request_handler(ngx_http_r } ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "auth request unexpected status: %d", ctx->status); + "auth request unexpected status: %ui", ctx->status); return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -219,7 +219,7 @@ ngx_http_auth_request_done(ngx_http_requ ngx_http_auth_request_ctx_t *ctx = data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "auth request done s:%d", r->headers_out.status); + "auth request done s:%ui", r->headers_out.status); ctx->done = 1; ctx->status = r->headers_out.status; diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_chunked_filter_module.c --- a/src/http/modules/ngx_http_chunked_filter_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_chunked_filter_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -121,7 +121,7 @@ ngx_http_chunked_body_filter(ngx_http_re for ( ;; ) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http chunk: %d", ngx_buf_size(cl->buf)); + "http chunk: %O", ngx_buf_size(cl->buf)); size += ngx_buf_size(cl->buf); diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_fastcgi_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -1653,7 +1653,7 @@ ngx_http_fastcgi_process_header(ngx_http && f->type != NGX_HTTP_FASTCGI_STDERR) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "upstream sent unexpected FastCGI record: %d", + "upstream sent unexpected FastCGI record: %ui", f->type); return NGX_HTTP_UPSTREAM_INVALID_HEADER; @@ -1834,7 +1834,7 @@ ngx_http_fastcgi_process_header(ngx_http rc = ngx_http_parse_header_line(r, &u->buffer, 1); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http fastcgi parser: %d", rc); + "http fastcgi parser: %i", rc); if (rc == NGX_AGAIN) { break; @@ -2505,7 +2505,7 @@ ngx_http_fastcgi_non_buffered_filter(voi for (cl = u->out_bufs; cl; cl = cl->next) { ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http fastcgi in memory %p-%p %uz", + "http fastcgi in memory %p-%p %O", cl->buf->pos, cl->buf->last, ngx_buf_size(cl->buf)); if (buf->last == cl->buf->pos) { diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_gzip_filter_module.c --- a/src/http/modules/ngx_http_gzip_filter_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_gzip_filter_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -1009,14 +1009,14 @@ ngx_http_gzip_filter_alloc(void *opaque, ctx->allocated -= alloc; ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0, - "gzip alloc: n:%ud s:%ud a:%ud p:%p", + "gzip alloc: n:%ud s:%ud a:%ui p:%p", items, size, alloc, p); return p; } ngx_log_error(NGX_LOG_ALERT, ctx->request->connection->log, 0, - "gzip filter failed to use preallocated memory: %ud of %ud", + "gzip filter failed to use preallocated memory: %ud of %ui", items * size, ctx->allocated); p = ngx_palloc(ctx->request->pool, items * size); diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_image_filter_module.c --- a/src/http/modules/ngx_http_image_filter_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_image_filter_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -737,7 +737,7 @@ ngx_http_image_size(ngx_http_request_t * } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "image size: %d x %d", width, height); + "image size: %d x %d", (int) width, (int) height); ctx->width = width; ctx->height = height; diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_limit_conn_module.c --- a/src/http/modules/ngx_http_limit_conn_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_limit_conn_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -232,7 +232,7 @@ ngx_http_limit_conn_handler(ngx_http_req } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "limit conn: %08XD %d", node->key, lc->conn); + "limit conn: %08Xi %d", node->key, lc->conn); ngx_shmtx_unlock(&shpool->mutex); @@ -351,7 +351,7 @@ ngx_http_limit_conn_cleanup(void *data) ngx_shmtx_lock(&shpool->mutex); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, lccln->shm_zone->shm.log, 0, - "limit conn cleanup: %08XD %d", node->key, lc->conn); + "limit conn cleanup: %08Xi %d", node->key, lc->conn); lc->conn--; diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_map_module.c --- a/src/http/modules/ngx_http_map_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_map_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -141,7 +141,7 @@ ngx_http_map_variable(ngx_http_request_t *v = *value; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http map: \"%v\" \"%v\"", &val, v); + "http map: \"%V\" \"%v\"", &val, v); return NGX_OK; } diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_memcached_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -523,7 +523,7 @@ ngx_http_memcached_filter(void *data, ss cl->buf->tag = u->output.tag; ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0, - "memcached filter bytes:%z size:%z length:%z rest:%z", + "memcached filter bytes:%z size:%z length:%O rest:%z", bytes, b->last - b->pos, u->length, ctx->rest); if (bytes <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) { diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -1559,7 +1559,7 @@ ngx_http_proxy_body_output_filter(void * for ( ;; ) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "proxy output chunk: %d", ngx_buf_size(cl->buf)); + "proxy output chunk: %O", ngx_buf_size(cl->buf)); size += ngx_buf_size(cl->buf); @@ -1917,7 +1917,7 @@ ngx_http_proxy_input_filter_init(void *d } ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http proxy filter init s:%d h:%d c:%d l:%O", + "http proxy filter init s:%ui h:%d c:%d l:%O", u->headers_in.status_n, ctx->head, u->headers_in.chunked, u->headers_in.content_length_n); @@ -2125,7 +2125,7 @@ ngx_http_proxy_chunked_filter(ngx_event_ } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http proxy chunked state %d, length %d", + "http proxy chunked state %ui, length %O", ctx->chunked.state, p->length); if (b) { @@ -2299,7 +2299,7 @@ ngx_http_proxy_non_buffered_chunked_filt for (cl = u->out_bufs; cl; cl = cl->next) { ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http proxy in memory %p-%p %uz", + "http proxy in memory %p-%p %O", cl->buf->pos, cl->buf->last, ngx_buf_size(cl->buf)); if (buf->last == cl->buf->pos) { diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_range_filter_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -207,7 +207,7 @@ ngx_http_range_header_filter(ngx_http_re if_range_time = ngx_parse_http_time(if_range->data, if_range->len); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http ir:%d lm:%d", + "http ir:%T lm:%T", if_range_time, r->headers_out.last_modified_time); if (if_range_time != r->headers_out.last_modified_time) { diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -468,12 +468,12 @@ ngx_http_ssi_body_filter(ngx_http_reques while (ctx->pos < ctx->buf->last) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "saved: %d state: %d", ctx->saved, ctx->state); + "saved: %uz state: %ui", ctx->saved, ctx->state); rc = ngx_http_ssi_parse(r, ctx); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "parse: %d, looked: %d %p-%p", + "parse: %i, looked: %uz %p-%p", rc, ctx->looked, ctx->copy_start, ctx->copy_end); if (rc == NGX_ERROR) { @@ -485,7 +485,7 @@ ngx_http_ssi_body_filter(ngx_http_reques if (ctx->output) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "saved: %d", ctx->saved); + "saved: %uz", ctx->saved); if (ctx->saved) { @@ -1911,7 +1911,7 @@ ngx_http_ssi_regex_match(ngx_http_reques if (rc < NGX_REGEX_NO_MATCHED) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"", + ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", rc, str, pattern); return NGX_HTTP_SSI_ERROR; } diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_sub_filter_module.c --- a/src/http/modules/ngx_http_sub_filter_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_sub_filter_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -341,7 +341,7 @@ ngx_http_sub_body_filter(ngx_http_reques rc = ngx_http_sub_parse(r, ctx); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "parse: %d, looked: \"%V\" %p-%p", + "parse: %i, looked: \"%V\" %p-%p", rc, &ctx->looked, ctx->copy_start, ctx->copy_end); if (rc == NGX_ERROR) { diff -r dc92298b1852 -r f01ab2dbcfdc src/http/modules/ngx_http_upstream_ip_hash_module.c --- a/src/http/modules/ngx_http_upstream_ip_hash_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -199,7 +199,7 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, - "get ip hash peer, hash: %ui %04XA", p, m); + "get ip hash peer, hash: %ui %04XL", p, (uint64_t) m); if (peer->down) { goto next; diff -r dc92298b1852 -r f01ab2dbcfdc src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/ngx_http_request.c Thu Mar 31 02:33:57 2016 +0300 @@ -648,7 +648,7 @@ ngx_http_ssl_handshake(ngx_event_t *rev) err = ngx_socket_errno; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %z", n); if (n == -1) { if (err == NGX_EAGAIN) { @@ -1500,7 +1500,7 @@ ngx_http_alloc_large_header_buffer(ngx_h } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http large header copy: %d", r->header_in->pos - old); + "http large header copy: %uz", r->header_in->pos - old); new = b->start; @@ -2264,7 +2264,7 @@ ngx_http_finalize_request(ngx_http_reque c = r->connection; ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http finalize request: %d, \"%V?%V\" a:%d, c:%d", + "http finalize request: %i, \"%V?%V\" a:%d, c:%d", rc, &r->uri, &r->args, r == c->data, r->main->count); if (rc == NGX_DONE) { @@ -2956,7 +2956,7 @@ ngx_http_set_keepalive(ngx_http_request_ b->last = b->start; } - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %d", + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %i", hc->free, hc->nfree); if (hc->free) { @@ -2968,7 +2968,7 @@ ngx_http_set_keepalive(ngx_http_request_ hc->nfree = 0; } - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %d", + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %i", hc->busy, hc->nbusy); if (hc->busy) { @@ -3259,7 +3259,7 @@ ngx_http_lingering_close_handler(ngx_eve do { n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %z", n); if (n == NGX_ERROR || n == 0) { ngx_http_close_request(r, 0); diff -r dc92298b1852 -r f01ab2dbcfdc src/http/ngx_http_script.c --- a/src/http/ngx_http_script.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/ngx_http_script.c Thu Mar 31 02:33:57 2016 +0300 @@ -1488,7 +1488,7 @@ ngx_http_script_file_code(ngx_http_scrip r = e->request; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http script file op %p \"%V\"", code->op, &path); + "http script file op %p \"%V\"", (void *) code->op, &path); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); diff -r dc92298b1852 -r f01ab2dbcfdc src/http/ngx_http_write_filter_module.c --- a/src/http/ngx_http_write_filter_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/ngx_http_write_filter_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -174,7 +174,7 @@ ngx_http_write_filter(ngx_http_request_t *ll = NULL; ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http write filter: l:%d f:%d s:%O", last, flush, size); + "http write filter: l:%ui f:%ui s:%O", last, flush, size); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); diff -r dc92298b1852 -r f01ab2dbcfdc src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Thu Mar 31 02:33:57 2016 +0300 @@ -2124,7 +2124,7 @@ ngx_http_v2_state_ping(ngx_http_v2_conne } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "http2 PING frame, flags: %ui", h2c->state.flags); + "http2 PING frame, flags: %ud", h2c->state.flags); if (h2c->state.flags & NGX_HTTP_V2_ACK_FLAG) { return ngx_http_v2_state_skip(h2c, pos, end); diff -r dc92298b1852 -r f01ab2dbcfdc src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/mail/ngx_mail_auth_http_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -431,7 +431,7 @@ ngx_mail_auth_http_ignore_status_line(ng } ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "auth http server &V sent invalid response", + "auth http server %V sent invalid response", ctx->peer.name); ngx_close_connection(ctx->peer.connection); ngx_destroy_pool(ctx->pool); diff -r dc92298b1852 -r f01ab2dbcfdc src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/mail/ngx_mail_proxy_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -935,7 +935,7 @@ ngx_mail_proxy_handler(ngx_event_t *ev) do_write = ev->write ? 1 : 0; ngx_log_debug3(NGX_LOG_DEBUG_MAIL, ev->log, 0, - "mail proxy handler: %d, #%d > #%d", + "mail proxy handler: %ui, #%d > #%d", do_write, src->fd, dst->fd); for ( ;; ) { diff -r dc92298b1852 -r f01ab2dbcfdc src/os/unix/ngx_file_aio_read.c --- a/src/os/unix/ngx_file_aio_read.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/os/unix/ngx_file_aio_read.c Thu Mar 31 02:33:57 2016 +0300 @@ -84,7 +84,7 @@ ngx_file_aio_read(ngx_file_t *file, u_ch } ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, - "aio complete:%d @%O:%z %V", + "aio complete:%d @%O:%uz %V", ev->complete, offset, size, &file->name); if (ev->complete) { diff -r dc92298b1852 -r f01ab2dbcfdc src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/os/unix/ngx_files.c Thu Mar 31 02:33:57 2016 +0300 @@ -176,7 +176,7 @@ ngx_thread_read_handler(void *data, ngx_ #endif ngx_log_debug4(NGX_LOG_DEBUG_CORE, log, 0, - "pread: %z (err: %i) of %uz @%O", + "pread: %z (err: %d) of %uz @%O", n, ctx->err, ctx->size, ctx->offset); } diff -r dc92298b1852 -r f01ab2dbcfdc src/os/unix/ngx_linux_aio_read.c --- a/src/os/unix/ngx_linux_aio_read.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/os/unix/ngx_linux_aio_read.c Thu Mar 31 02:33:57 2016 +0300 @@ -73,7 +73,7 @@ ngx_file_aio_read(ngx_file_t *file, u_ch } ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, - "aio complete:%d @%O:%z %V", + "aio complete:%d @%O:%uz %V", ev->complete, offset, size, &file->name); if (ev->complete) { diff -r dc92298b1852 -r f01ab2dbcfdc src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/os/unix/ngx_linux_sendfile_chain.c Thu Mar 31 02:33:57 2016 +0300 @@ -451,7 +451,7 @@ again: #endif ngx_log_debug4(NGX_LOG_DEBUG_EVENT, log, 0, - "sendfile: %z (err: %i) of %uz @%O", + "sendfile: %z (err: %d) of %uz @%O", n, ctx->err, ctx->size, file->file_pos); if (ctx->err == NGX_EINTR) { diff -r dc92298b1852 -r f01ab2dbcfdc src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/os/unix/ngx_process_cycle.c Thu Mar 31 02:33:57 2016 +0300 @@ -145,7 +145,7 @@ ngx_master_process_cycle(ngx_cycle_t *cy } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "termination cycle: %d", delay); + "termination cycle: %M", delay); itv.it_interval.tv_sec = 0; itv.it_interval.tv_usec = 0; @@ -438,7 +438,7 @@ ngx_pass_open_channel(ngx_cycle_t *cycle } ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, - "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", + "pass channel s:%i pid:%P fd:%d to s:%i pid:%P fd:%d", ch->slot, ch->pid, ch->fd, i, ngx_processes[i].pid, ngx_processes[i].channel[0]); @@ -492,7 +492,7 @@ ngx_signal_worker_processes(ngx_cycle_t for (i = 0; i < ngx_last_process; i++) { ngx_log_debug7(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "child: %d %P e:%d t:%d d:%d r:%d j:%d", + "child: %i %P e:%d t:%d d:%d r:%d j:%d", i, ngx_processes[i].pid, ngx_processes[i].exiting, @@ -570,7 +570,7 @@ ngx_reap_children(ngx_cycle_t *cycle) for (i = 0; i < ngx_last_process; i++) { ngx_log_debug7(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "child: %d %P e:%d t:%d d:%d r:%d j:%d", + "child: %i %P e:%d t:%d d:%d r:%d j:%d", i, ngx_processes[i].pid, ngx_processes[i].exiting, @@ -1047,7 +1047,7 @@ ngx_channel_handler(ngx_event_t *ev) } ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, - "channel command: %d", ch.command); + "channel command: %ui", ch.command); switch (ch.command) { diff -r dc92298b1852 -r f01ab2dbcfdc src/os/unix/ngx_readv_chain.c --- a/src/os/unix/ngx_readv_chain.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/os/unix/ngx_readv_chain.c Thu Mar 31 02:33:57 2016 +0300 @@ -101,7 +101,7 @@ ngx_readv_chain(ngx_connection_t *c, ngx } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "readv: %d, last:%d", vec.nelts, iov->iov_len); + "readv: %ui, last:%uz", vec.nelts, iov->iov_len); do { n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts); diff -r dc92298b1852 -r f01ab2dbcfdc src/os/unix/ngx_recv.c --- a/src/os/unix/ngx_recv.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/os/unix/ngx_recv.c Thu Mar 31 02:33:57 2016 +0300 @@ -52,7 +52,7 @@ ngx_unix_recv(ngx_connection_t *c, u_cha n = recv(c->fd, buf, size, 0); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "recv: fd:%d %d of %d", c->fd, n, size); + "recv: fd:%d %z of %uz", c->fd, n, size); if (n >= 0) { if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { @@ -139,7 +139,7 @@ ngx_unix_recv(ngx_connection_t *c, u_cha n = recv(c->fd, buf, size, 0); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "recv: fd:%d %d of %d", c->fd, n, size); + "recv: fd:%d %z of %uz", c->fd, n, size); if (n == 0) { rev->ready = 0; diff -r dc92298b1852 -r f01ab2dbcfdc src/os/unix/ngx_send.c --- a/src/os/unix/ngx_send.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/os/unix/ngx_send.c Thu Mar 31 02:33:57 2016 +0300 @@ -34,7 +34,7 @@ ngx_unix_send(ngx_connection_t *c, u_cha n = send(c->fd, buf, size, 0); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "send: fd:%d %d of %d", c->fd, n, size); + "send: fd:%d %z of %uz", c->fd, n, size); if (n > 0) { if (n < (ssize_t) size) { diff -r dc92298b1852 -r f01ab2dbcfdc src/os/unix/ngx_udp_recv.c --- a/src/os/unix/ngx_udp_recv.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/os/unix/ngx_udp_recv.c Thu Mar 31 02:33:57 2016 +0300 @@ -25,7 +25,7 @@ ngx_udp_unix_recv(ngx_connection_t *c, u n = recv(c->fd, buf, size, 0); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "recv: fd:%d %d of %d", c->fd, n, size); + "recv: fd:%d %z of %uz", c->fd, n, size); if (n >= 0) { if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { @@ -83,7 +83,7 @@ ngx_udp_unix_recv(ngx_connection_t *c, u n = recv(c->fd, buf, size, 0); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "recv: fd:%d %d of %d", c->fd, n, size); + "recv: fd:%d %z of %uz", c->fd, n, size); if (n >= 0) { return n; diff -r dc92298b1852 -r f01ab2dbcfdc src/stream/ngx_stream_limit_conn_module.c --- a/src/stream/ngx_stream_limit_conn_module.c Thu Mar 31 02:33:55 2016 +0300 +++ b/src/stream/ngx_stream_limit_conn_module.c Thu Mar 31 02:33:57 2016 +0300 @@ -220,7 +220,7 @@ ngx_stream_limit_conn_handler(ngx_stream } ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "limit conn: %08XD %d", node->key, lc->conn); + "limit conn: %08Xi %d", node->key, lc->conn); ngx_shmtx_unlock(&shpool->mutex); @@ -340,7 +340,7 @@ ngx_stream_limit_conn_cleanup(void *data ngx_shmtx_lock(&shpool->mutex); ngx_log_debug2(NGX_LOG_DEBUG_STREAM, lccln->shm_zone->shm.log, 0, - "limit conn cleanup: %08XD %d", node->key, lc->conn); + "limit conn cleanup: %08Xi %d", node->key, lc->conn); lc->conn--; From pluknet at nginx.com Wed Mar 30 23:35:13 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Wed, 30 Mar 2016 23:35:13 +0000 Subject: [nginx] Fixed format specifiers in ngx_sprintf(). Message-ID: details: http://hg.nginx.org/nginx/rev/40bea39731d7 branches: changeset: 6481:40bea39731d7 user: Sergey Kandaurov date: Thu Mar 31 02:34:00 2016 +0300 description: Fixed format specifiers in ngx_sprintf(). diffstat: src/core/ngx_inet.c | 2 +- src/core/ngx_times.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (33 lines): diff -r f01ab2dbcfdc -r 40bea39731d7 src/core/ngx_inet.c --- a/src/core/ngx_inet.c Thu Mar 31 02:33:57 2016 +0300 +++ b/src/core/ngx_inet.c Thu Mar 31 02:34:00 2016 +0300 @@ -348,7 +348,7 @@ ngx_inet6_ntop(u_char *p, u_char *text, continue; } - dst = ngx_sprintf(dst, "%uxi", p[i] * 256 + p[i + 1]); + dst = ngx_sprintf(dst, "%uxd", p[i] * 256 + p[i + 1]); if (i < 14) { *dst++ = ':'; diff -r f01ab2dbcfdc -r 40bea39731d7 src/core/ngx_times.c --- a/src/core/ngx_times.c Thu Mar 31 02:33:57 2016 +0300 +++ b/src/core/ngx_times.c Thu Mar 31 02:34:00 2016 +0300 @@ -154,7 +154,7 @@ ngx_time_update(void) p2 = &cached_http_log_time[slot][0]; - (void) ngx_sprintf(p2, "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d", + (void) ngx_sprintf(p2, "%02d/%s/%d:%02d:%02d:%02d %c%02i%02i", tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1], tm.ngx_tm_year, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec, @@ -163,7 +163,7 @@ ngx_time_update(void) p3 = &cached_http_log_iso8601[slot][0]; - (void) ngx_sprintf(p3, "%4d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d", + (void) ngx_sprintf(p3, "%4d-%02d-%02dT%02d:%02d:%02d%c%02i:%02i", tm.ngx_tm_year, tm.ngx_tm_mon, tm.ngx_tm_mday, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec, From pluknet at nginx.com Wed Mar 30 23:35:16 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Wed, 30 Mar 2016 23:35:16 +0000 Subject: [nginx] Fixed ngx_pid_t formatting in ngx_sprintf() and logging. Message-ID: details: http://hg.nginx.org/nginx/rev/2b7dacb381ed branches: changeset: 6482:2b7dacb381ed user: Sergey Kandaurov date: Thu Mar 31 02:34:04 2016 +0300 description: Fixed ngx_pid_t formatting in ngx_sprintf() and logging. diffstat: src/os/unix/ngx_process.c | 2 +- src/os/win32/ngx_process.c | 6 +++--- src/os/win32/ngx_process_cycle.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diffs (67 lines): diff -r 40bea39731d7 -r 2b7dacb381ed src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c Thu Mar 31 02:34:00 2016 +0300 +++ b/src/os/unix/ngx_process.c Thu Mar 31 02:34:04 2016 +0300 @@ -622,7 +622,7 @@ ngx_os_signal_process(ngx_cycle_t *cycle } ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "kill(%P, %d) failed", pid, sig->signo); + "kill(%P, %d) failed", (ngx_pid_t) pid, sig->signo); } } diff -r 40bea39731d7 -r 2b7dacb381ed src/os/win32/ngx_process.c --- a/src/os/win32/ngx_process.c Thu Mar 31 02:34:00 2016 +0300 +++ b/src/os/win32/ngx_process.c Thu Mar 31 02:34:04 2016 +0300 @@ -76,9 +76,9 @@ ngx_spawn_process(ngx_cycle_t *cycle, ch ngx_processes[s].pid = pid; ngx_processes[s].name = name; - ngx_sprintf(ngx_processes[s].term_event, "ngx_%s_term_%ul%Z", name, pid); - ngx_sprintf(ngx_processes[s].quit_event, "ngx_%s_quit_%ul%Z", name, pid); - ngx_sprintf(ngx_processes[s].reopen_event, "ngx_%s_reopen_%ul%Z", + ngx_sprintf(ngx_processes[s].term_event, "ngx_%s_term_%P%Z", name, pid); + ngx_sprintf(ngx_processes[s].quit_event, "ngx_%s_quit_%P%Z", name, pid); + ngx_sprintf(ngx_processes[s].reopen_event, "ngx_%s_reopen_%P%Z", name, pid); events[0] = ngx_master_process_event; diff -r 40bea39731d7 -r 2b7dacb381ed src/os/win32/ngx_process_cycle.c --- a/src/os/win32/ngx_process_cycle.c Thu Mar 31 02:34:00 2016 +0300 +++ b/src/os/win32/ngx_process_cycle.c Thu Mar 31 02:34:04 2016 +0300 @@ -581,7 +581,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cy ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "worker started"); - ngx_sprintf((u_char *) wtevn, "ngx_worker_term_%ul%Z", ngx_pid); + ngx_sprintf((u_char *) wtevn, "ngx_worker_term_%P%Z", ngx_pid); events[0] = CreateEvent(NULL, 1, 0, wtevn); if (events[0] == NULL) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, @@ -589,7 +589,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cy goto failed; } - ngx_sprintf((u_char *) wqevn, "ngx_worker_quit_%ul%Z", ngx_pid); + ngx_sprintf((u_char *) wqevn, "ngx_worker_quit_%P%Z", ngx_pid); events[1] = CreateEvent(NULL, 1, 0, wqevn); if (events[1] == NULL) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, @@ -597,7 +597,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cy goto failed; } - ngx_sprintf((u_char *) wroevn, "ngx_worker_reopen_%ul%Z", ngx_pid); + ngx_sprintf((u_char *) wroevn, "ngx_worker_reopen_%P%Z", ngx_pid); events[2] = CreateEvent(NULL, 1, 0, wroevn); if (events[2] == NULL) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, @@ -1007,7 +1007,7 @@ ngx_os_signal_process(ngx_cycle_t *cycle ngx_int_t rc; char evn[NGX_PROCESS_SYNC_NAME]; - ngx_sprintf((u_char *) evn, "Global\\ngx_%s_%ul%Z", sig, pid); + ngx_sprintf((u_char *) evn, "Global\\ngx_%s_%P%Z", sig, (ngx_pid_t) pid); ev = OpenEvent(EVENT_MODIFY_STATE, 0, evn); if (ev == NULL) { From tony.fouchard at blablacar.com Thu Mar 31 15:59:13 2016 From: tony.fouchard at blablacar.com (Tony Fouchard) Date: Thu, 31 Mar 2016 17:59:13 +0200 Subject: proxy protocol proxified client port Message-ID: Hi guys, I need to log the user remote port at nginx level when requests are passed through proxy protocol (legal requirement), but looking at implementation I saw that all of the work stopped after reading source IP. In my setup, I have bgp sessions mounted on haproxy instances, but the haproxy acts at level 4 and only route traffic to different nginx farms depending of TLS extension value provided by client : it permits to serve for example both spdy and h2 over alpn. I have tried to implement what I needed and update the test case, changesets in attachment. Regards. Tony Fouchard. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: tests Type: application/octet-stream Size: 2602 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: changeset Type: application/octet-stream Size: 4048 bytes Desc: not available URL: From ru at nginx.com Thu Mar 31 19:26:48 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 31 Mar 2016 19:26:48 +0000 Subject: [nginx] Fixed ngx_os_signal_process() prototype. Message-ID: details: http://hg.nginx.org/nginx/rev/3a50ccd94333 branches: changeset: 6483:3a50ccd94333 user: Ruslan Ermilov date: Thu Mar 31 22:00:33 2016 +0300 description: Fixed ngx_os_signal_process() prototype. diffstat: src/core/ngx_cycle.c | 4 ++-- src/os/unix/ngx_os.h | 2 +- src/os/unix/ngx_process.c | 4 ++-- src/os/win32/ngx_os.h | 2 +- src/os/win32/ngx_process_cycle.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diffs (85 lines): diff -r 2b7dacb381ed -r 3a50ccd94333 src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Thu Mar 31 02:34:04 2016 +0300 +++ b/src/core/ngx_cycle.c Thu Mar 31 22:00:33 2016 +0300 @@ -1006,7 +1006,7 @@ ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig) { ssize_t n; - ngx_int_t pid; + ngx_pid_t pid; ngx_file_t file; ngx_core_conf_t *ccf; u_char buf[NGX_INT64_LEN + 2]; @@ -1044,7 +1044,7 @@ ngx_signal_process(ngx_cycle_t *cycle, c pid = ngx_atoi(buf, ++n); - if (pid == NGX_ERROR) { + if (pid == (ngx_pid_t) NGX_ERROR) { ngx_log_error(NGX_LOG_ERR, cycle->log, 0, "invalid PID number \"%*s\" in \"%s\"", n, buf, file.name.data); diff -r 2b7dacb381ed -r 3a50ccd94333 src/os/unix/ngx_os.h --- a/src/os/unix/ngx_os.h Thu Mar 31 02:34:04 2016 +0300 +++ b/src/os/unix/ngx_os.h Thu Mar 31 22:00:33 2016 +0300 @@ -39,7 +39,7 @@ void ngx_os_status(ngx_log_t *log); ngx_int_t ngx_os_specific_init(ngx_log_t *log); void ngx_os_specific_status(ngx_log_t *log); ngx_int_t ngx_daemon(ngx_log_t *log); -ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_int_t pid); +ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_pid_t pid); ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size); diff -r 2b7dacb381ed -r 3a50ccd94333 src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c Thu Mar 31 02:34:04 2016 +0300 +++ b/src/os/unix/ngx_process.c Thu Mar 31 22:00:33 2016 +0300 @@ -611,7 +611,7 @@ ngx_debug_point(void) ngx_int_t -ngx_os_signal_process(ngx_cycle_t *cycle, char *name, ngx_int_t pid) +ngx_os_signal_process(ngx_cycle_t *cycle, char *name, ngx_pid_t pid) { ngx_signal_t *sig; @@ -622,7 +622,7 @@ ngx_os_signal_process(ngx_cycle_t *cycle } ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "kill(%P, %d) failed", (ngx_pid_t) pid, sig->signo); + "kill(%P, %d) failed", pid, sig->signo); } } diff -r 2b7dacb381ed -r 3a50ccd94333 src/os/win32/ngx_os.h --- a/src/os/win32/ngx_os.h Thu Mar 31 02:34:04 2016 +0300 +++ b/src/os/win32/ngx_os.h Thu Mar 31 22:00:33 2016 +0300 @@ -35,7 +35,7 @@ typedef struct { ngx_int_t ngx_os_init(ngx_log_t *log); void ngx_os_status(ngx_log_t *log); -ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_int_t pid); +ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_pid_t pid); ssize_t ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size); ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size); diff -r 2b7dacb381ed -r 3a50ccd94333 src/os/win32/ngx_process_cycle.c --- a/src/os/win32/ngx_process_cycle.c Thu Mar 31 02:34:04 2016 +0300 +++ b/src/os/win32/ngx_process_cycle.c Thu Mar 31 22:00:33 2016 +0300 @@ -1001,13 +1001,13 @@ ngx_single_process_cycle(ngx_cycle_t *cy ngx_int_t -ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_int_t pid) +ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_pid_t pid) { HANDLE ev; ngx_int_t rc; char evn[NGX_PROCESS_SYNC_NAME]; - ngx_sprintf((u_char *) evn, "Global\\ngx_%s_%P%Z", sig, (ngx_pid_t) pid); + ngx_sprintf((u_char *) evn, "Global\\ngx_%s_%P%Z", sig, pid); ev = OpenEvent(EVENT_MODIFY_STATE, 0, evn); if (ev == NULL) { From ru at nginx.com Thu Mar 31 19:33:54 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 31 Mar 2016 19:33:54 +0000 Subject: [nginx] Removed the prototype mysql module. Message-ID: details: http://hg.nginx.org/nginx/rev/4b420f9c4c5d branches: changeset: 6484:4b420f9c4c5d user: Ruslan Ermilov date: Thu Mar 31 22:33:26 2016 +0300 description: Removed the prototype mysql module. diffstat: contrib/vim/syntax/nginx.vim | 2 +- misc/GNUmakefile | 2 - src/core/ngx_log.c | 2 +- src/core/ngx_log.h | 3 +- src/mysql/config | 13 - src/mysql/ngx_http_mysql_test.c | 204 ----------------- src/mysql/ngx_mysql.c | 465 ---------------------------------------- src/mysql/ngx_mysql.h | 85 ------- 8 files changed, 3 insertions(+), 773 deletions(-) diffs (839 lines): diff -r 3a50ccd94333 -r 4b420f9c4c5d contrib/vim/syntax/nginx.vim --- a/contrib/vim/syntax/nginx.vim Thu Mar 31 22:00:33 2016 +0300 +++ b/contrib/vim/syntax/nginx.vim Thu Mar 31 22:33:26 2016 +0300 @@ -57,6 +57,7 @@ syn keyword ngxDirectiveError post_actio syn keyword ngxDirectiveDeprecated connections syn keyword ngxDirectiveDeprecated imap syn keyword ngxDirectiveDeprecated limit_zone +syn keyword ngxDirectiveDeprecated mysql_test syn keyword ngxDirectiveDeprecated open_file_cache_retest syn keyword ngxDirectiveDeprecated optimize_server_names syn keyword ngxDirectiveDeprecated satisfy_any @@ -246,7 +247,6 @@ syn keyword ngxDirective mp4_max_buffer_ syn keyword ngxDirective msie_padding syn keyword ngxDirective msie_refresh syn keyword ngxDirective multi_accept -syn keyword ngxDirective mysql_test syn keyword ngxDirective open_file_cache syn keyword ngxDirective open_file_cache_errors syn keyword ngxDirective open_file_cache_events diff -r 3a50ccd94333 -r 4b420f9c4c5d misc/GNUmakefile --- a/misc/GNUmakefile Thu Mar 31 22:00:33 2016 +0300 +++ b/misc/GNUmakefile Thu Mar 31 22:33:26 2016 +0300 @@ -20,8 +20,6 @@ release: export rm $(TEMP)/$(NGINX)/src/event/modules/ngx_iocp_module.* rm -r $(TEMP)/$(NGINX)/src/os/win32 - rm -r $(TEMP)/$(NGINX)/src/mysql - mv $(TEMP)/$(NGINX)/docs/text/LICENSE $(TEMP)/$(NGINX) mv $(TEMP)/$(NGINX)/docs/text/README $(TEMP)/$(NGINX) mv $(TEMP)/$(NGINX)/docs/html $(TEMP)/$(NGINX) diff -r 3a50ccd94333 -r 4b420f9c4c5d src/core/ngx_log.c --- a/src/core/ngx_log.c Thu Mar 31 22:00:33 2016 +0300 +++ b/src/core/ngx_log.c Thu Mar 31 22:33:26 2016 +0300 @@ -86,7 +86,7 @@ static ngx_str_t err_levels[] = { static const char *debug_levels[] = { "debug_core", "debug_alloc", "debug_mutex", "debug_event", - "debug_http", "debug_mail", "debug_mysql", "debug_stream" + "debug_http", "debug_mail", "debug_stream" }; diff -r 3a50ccd94333 -r 4b420f9c4c5d src/core/ngx_log.h --- a/src/core/ngx_log.h Thu Mar 31 22:00:33 2016 +0300 +++ b/src/core/ngx_log.h Thu Mar 31 22:33:26 2016 +0300 @@ -29,8 +29,7 @@ #define NGX_LOG_DEBUG_EVENT 0x080 #define NGX_LOG_DEBUG_HTTP 0x100 #define NGX_LOG_DEBUG_MAIL 0x200 -#define NGX_LOG_DEBUG_MYSQL 0x400 -#define NGX_LOG_DEBUG_STREAM 0x800 +#define NGX_LOG_DEBUG_STREAM 0x400 /* * do not forget to update debug_levels[] in src/core/ngx_log.c diff -r 3a50ccd94333 -r 4b420f9c4c5d src/mysql/config --- a/src/mysql/config Thu Mar 31 22:00:33 2016 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ - -ngx_addon_name=ngx_mysql - -HTTP_MODULES="$HTTP_MODULES ngx_http_mysql_test_module" - -HTTP_INCS="$HTTP_INCS $ngx_addon_dir" -HTTP_DEPS="$HTTP_DEPS $ngx_addon_dir/ngx_mysql.h" -#CORE_LIBS="$CORE_LIBS -lmd" - -USE_SHA1=YES - -NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_mysql.c" -NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mysql_test.c" diff -r 3a50ccd94333 -r 4b420f9c4c5d src/mysql/ngx_http_mysql_test.c --- a/src/mysql/ngx_http_mysql_test.c Thu Mar 31 22:00:33 2016 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,204 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - -#include -#include -#include -#include - - -typedef struct { - ngx_addr_t *peers; - ngx_uint_t npeers; -} ngx_http_mysql_test_conf_t; - - -static void ngx_http_mysql_auth(ngx_mysql_t *m); -static void ngx_http_mysql_done(ngx_mysql_t *m); -static void *ngx_http_mysql_test_create_loc_conf(ngx_conf_t *cf); -static char *ngx_http_mysql_test(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - -static ngx_command_t ngx_http_mysql_test_commands[] = { - - { ngx_string("mysql_test"), - NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_mysql_test, - NGX_HTTP_LOC_CONF_OFFSET, - 0, - NULL }, - - ngx_null_command -}; - - -static ngx_http_module_t ngx_http_mysql_test_module_ctx = { - NULL, /* preconfiguration */ - NULL, /* postconfiguration */ - - NULL, /* create main configuration */ - NULL, /* init main configuration */ - - NULL, /* create server configuration */ - NULL, /* merge server configuration */ - - ngx_http_mysql_test_create_loc_conf, /* create location configuration */ - NULL /* merge location configuration */ -}; - - -ngx_module_t ngx_http_mysql_test_module = { - NGX_MODULE_V1, - &ngx_http_mysql_test_module_ctx, /* module context */ - ngx_http_mysql_test_commands, /* module directives */ - NGX_HTTP_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_str_t ngx_mysql_login = ngx_string("root"); -static ngx_str_t ngx_mysql_passwd = ngx_string("tp"); -static ngx_str_t ngx_mysql_database = ngx_string("mysql"); -static ngx_str_t ngx_mysql_command_query = - ngx_string("select * from user"); - - -static ngx_int_t -ngx_http_mysql_test_handler(ngx_http_request_t *r) -{ - ngx_int_t rc; - ngx_mysql_t *m; - ngx_http_mysql_test_conf_t *mtcf; - - mtcf = ngx_http_get_module_loc_conf(r, ngx_http_mysql_test_module); - - m = ngx_pcalloc(r->pool, sizeof(ngx_mysql_t)); - - if (m == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - m->pool = r->pool; - m->handler = ngx_http_mysql_auth; - m->data = r; - - m->login = &ngx_mysql_login; - m->passwd = &ngx_mysql_passwd; - m->database = &ngx_mysql_database; - - /* STUB */ - m->peer.sockaddr = mtcf->peers[0].sockaddr; - m->peer.socklen = mtcf->peers[0].socklen; - m->peer.name = &mtcf->peers[0].name; - m->peer.tries = mtcf->npeers; - m->peer.get = ngx_event_get_peer; - /**/ - m->peer.log = r->connection->log; - m->peer.log_error = NGX_ERROR_ERR; - - rc = ngx_mysql_connect(m); - - if (rc == NGX_OK || rc == NGX_AGAIN) { - return NGX_DONE; - } - - return NGX_HTTP_INTERNAL_SERVER_ERROR; -} - - -static void -ngx_http_mysql_auth(ngx_mysql_t *m) -{ - ngx_http_request_t *r; - - r = m->data; - - if (m->state != NGX_OK) { - ngx_http_finalize_request(r, NGX_HTTP_NO_CONTENT); - return; - } - - m->query.len = NGX_MYSQL_CMDPKT_LEN + ngx_mysql_command_query.len; - - m->query.data = ngx_pnalloc(r->pool, m->query.len); - if (m->query.data == NULL) { - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; - } - - ngx_memcpy(m->query.data + NGX_MYSQL_CMDPKT_LEN, - ngx_mysql_command_query.data, ngx_mysql_command_query.len); - - m->handler = ngx_http_mysql_done; - - ngx_mysql_query(m); -} - - -static void -ngx_http_mysql_done(ngx_mysql_t *m) -{ - ngx_http_request_t *r; - - r = m->data; - - ngx_http_finalize_request(r, NGX_HTTP_NO_CONTENT); -} - - -static void * -ngx_http_mysql_test_create_loc_conf(ngx_conf_t *cf) -{ - ngx_http_mysql_test_conf_t *conf; - - conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_mysql_test_conf_t)); - if (conf == NULL) { - return NGX_CONF_ERROR; - } - - return conf; -} - -static char * -ngx_http_mysql_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - ngx_http_mysql_test_conf_t *mtcf = conf; - - ngx_str_t *value; - ngx_url_t u; - ngx_http_core_loc_conf_t *clcf; - - clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); - clcf->handler = ngx_http_mysql_test_handler; - - value = cf->args->elts; - - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.url = value[1]; - u.default_port = 3306; - - if (ngx_parse_url(cf->pool, &u) != NGX_OK) { - if (u.err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in upstream \"%V\"", u.err, &u.url); - } - - return NGX_CONF_ERROR; - } - - mtcf->peers = u.addrs; - mtcf->npeers = u.naddrs; - - return NGX_CONF_OK; -} diff -r 3a50ccd94333 -r 4b420f9c4c5d src/mysql/ngx_mysql.c --- a/src/mysql/ngx_mysql.c Thu Mar 31 22:00:33 2016 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,465 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -/* the library supports the subset of the MySQL 4.1+ protocol (version 10) */ - - -#include -#include -#include -#include -#include -#include - - -#define NGX_MYSQL_LONG_PASSWORD 0x0001 -#define NGX_MYSQL_CONNECT_WITH_DB 0x0008 -#define NGX_MYSQL_PROTOCOL_41 0x0200 -#define NGX_MYSQL_SECURE_CONNECTION 0x8000 - - -#define NGX_MYSQL_CMD_QUERY 3 - - -typedef struct { - u_char pktlen[3]; - u_char pktn; - - u_char protocol; - u_char version[1]; /* NULL-terminated string */ -} ngx_mysql_greeting1_pkt_t; - - -typedef struct { - u_char thread[4]; - u_char salt1[9]; - u_char capacity[2]; - u_char charset; - u_char status[2]; - u_char zero[13]; - u_char salt2[13]; -} ngx_mysql_greeting2_pkt_t; - - -typedef struct { - u_char pktlen[3]; - u_char pktn; - - u_char capacity[4]; - u_char max_packet[4]; - u_char charset; - u_char zero[23]; - u_char login[1]; /* NULL-terminated string */ - - /* - * u_char passwd_len; 0 if no password - * u_char passwd[20]; - * - * u_char database[1]; NULL-terminated string - */ - -} ngx_mysql_auth_pkt_t; - - -typedef struct { - u_char pktlen[3]; - u_char pktn; - u_char fields; -} ngx_mysql_response_pkt_t; - - -typedef struct { - u_char pktlen[3]; - u_char pktn; - u_char err; - u_char code[2]; - u_char message[1]; /* string */ -} ngx_mysql_error_pkt_t; - - -typedef struct { - u_char pktlen[3]; - u_char pktn; - u_char command; - u_char arg[1]; /* string */ -} ngx_mysql_command_pkt_t; - - -static void ngx_mysql_read_server_greeting(ngx_event_t *rev); -static void ngx_mysql_empty_handler(ngx_event_t *wev); -static void ngx_mysql_read_auth_result(ngx_event_t *rev); -static void ngx_mysql_read_query_result(ngx_event_t *rev); -static void ngx_mysql_close(ngx_mysql_t *m, ngx_int_t rc); - - -ngx_int_t -ngx_mysql_connect(ngx_mysql_t *m) -{ - ngx_int_t rc; - -#if 0 - if (cached) { - return NGX_OK; - } -#endif - - m->peer.log->action = "connecting to mysql server"; - - rc = ngx_event_connect_peer(&m->peer); - - if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) { - return rc; - } - - m->peer.connection->data = m; - - m->peer.connection->read->handler = ngx_mysql_read_server_greeting; - m->peer.connection->write->handler = ngx_mysql_empty_handler; - - ngx_add_timer(m->peer.connection->read, /* STUB */ 5000); - - return NGX_OK; -} - - -static void -ngx_mysql_read_server_greeting(ngx_event_t *rev) -{ - size_t len; - u_char *p; - ssize_t n; - ngx_uint_t i, capacity; - ngx_mysql_t *m; - ngx_connection_t *c; - ngx_mysql_greeting1_pkt_t *gr1; - ngx_mysql_greeting2_pkt_t *gr2; - ngx_mysql_auth_pkt_t *auth; - ngx_sha1_t sha; - u_char hash1[20], hash2[20]; - - c = rev->data; - m = c->data; - - if (rev->timedout) { - ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT, - "mysql server %V timed out", m->peer.name); - - ngx_mysql_close(m, NGX_ERROR); - return; - } - - if (m->buf == NULL) { - m->peer.log->action = "reading mysql server greeting"; - - m->buf = ngx_create_temp_buf(m->pool, /* STUB */ 1024); - if (m->buf == NULL) { - ngx_mysql_close(m, NGX_ERROR); - return; - } - } - - n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024); - - if (n == NGX_AGAIN) { - return; - } - - if (n < 5) { - ngx_mysql_close(m, NGX_ERROR); - return; - } - - gr1 = (ngx_mysql_greeting1_pkt_t *) m->buf->pos; - - if (ngx_m24toh(gr1->pktlen) > n - 4) { - ngx_log_error(NGX_LOG_ERR, rev->log, 0, - "mysql server %V sent incomplete greeting packet", - m->peer.name); - - ngx_mysql_close(m, NGX_ERROR); - return; - } - - if (gr1->protocol < 10) { - ngx_log_error(NGX_LOG_ERR, rev->log, 0, - "mysql server %V sent unsupported protocol version %ud", - m->peer.name, gr1->protocol); - - ngx_mysql_close(m, NGX_ERROR); - return; - } - - gr2 = (ngx_mysql_greeting2_pkt_t *) - (gr1->version + ngx_strlen(gr1->version) + 1); - - capacity = ngx_m16toh(gr2->capacity); - - ngx_log_debug8(NGX_LOG_DEBUG_MYSQL, rev->log, 0, - "mysql version: %ud, \"%s\", thread: %ud, salt: \"%s\", " - "capacity: %Xd, charset: %ud, status: %ud, salt rest \"%s\"", - gr1->protocol, gr1->version, ngx_m32toh(gr2->thread), - gr2->salt1, capacity, gr2->charset, - ngx_m16toh(gr2->status), &gr2->salt2); - - capacity = NGX_MYSQL_LONG_PASSWORD - | NGX_MYSQL_CONNECT_WITH_DB - | NGX_MYSQL_PROTOCOL_41 - | NGX_MYSQL_SECURE_CONNECTION; - - len = 4 + 4 + 4 + 1 + 23 + m->login->len + 1 + 1 + m->database->len + 1; - - if (m->passwd->len) { - len += 20; - } - - auth = ngx_pnalloc(m->pool, len); - if (auth == NULL) { - ngx_mysql_close(m, NGX_ERROR); - return; - } - - ngx_htom24(auth->pktlen, len - 4); - auth->pktn = (u_char) (gr1->pktn + 1); - - ngx_htom32(auth->capacity, capacity); - ngx_htom32(auth->max_packet, 0x01000000); /* max packet size 2^24 */ - ngx_memzero(auth->zero, 24); - auth->charset = gr2->charset; - - p = ngx_copy(auth->login, m->login->data, m->login->len); - *p++ = '\0'; - - if (m->passwd->len) { - - *p++ = (u_char) 20; - - ngx_sha1_init(&sha); - ngx_sha1_update(&sha, m->passwd->data, m->passwd->len); - ngx_sha1_final(hash1, &sha); - - ngx_sha1_init(&sha); - ngx_sha1_update(&sha, hash1, 20); - ngx_sha1_final(hash2, &sha); - - ngx_sha1_init(&sha); - ngx_sha1_update(&sha, gr2->salt1, 8); - ngx_sha1_update(&sha, gr2->salt2, 12); - ngx_sha1_update(&sha, hash2, 20); - ngx_sha1_final(hash2, &sha); - - for (i = 0; i < 20; i++) { - *p++ = (u_char) (hash1[i] ^ hash2[i]); - } - - } else { - *p++ = '\0'; - } - - p = ngx_copy(p, m->database->data, m->database->len); - *p = '\0'; - - - n = ngx_send(m->peer.connection, (void *) auth, len); - - if (n < (ssize_t) len) { - ngx_log_error(NGX_LOG_ERR, rev->log, 0, - "the incomplete packet was sent to mysql server %V", - m->peer.name); - - ngx_mysql_close(m, NGX_ERROR); - return; - } - - m->peer.connection->read->handler = ngx_mysql_read_auth_result; - - ngx_add_timer(m->peer.connection->read, /* STUB */ 5000); -} - - -static void -ngx_mysql_empty_handler(ngx_event_t *wev) -{ - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "mysql empty handler"); - - return; -} - - -static void -ngx_mysql_read_auth_result(ngx_event_t *rev) -{ - ssize_t n, len; - ngx_str_t msg; - ngx_mysql_t *m; - ngx_connection_t *c; - ngx_mysql_error_pkt_t *epkt; - ngx_mysql_response_pkt_t *pkt; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql read auth"); - - c = rev->data; - m = c->data; - - m->peer.log->action = "reading mysql auth result"; - - n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024); - - if (n == NGX_AGAIN) { - return; - } - - if (n < 5) { - ngx_mysql_close(m, NGX_ERROR); - return; - } - - pkt = (ngx_mysql_response_pkt_t *) m->buf->pos; - - len = ngx_m24toh(pkt->pktlen); - - if (len > n - 4) { - ngx_log_error(NGX_LOG_ERR, rev->log, 0, - "mysql server %V sent incomplete response packet", - m->peer.name); - - ngx_mysql_close(m, NGX_ERROR); - return; - } - - if (pkt->fields == 0) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql auth OK"); - - m->state = NGX_OK; - m->pktn = 0; - - m->handler(m); - - return; - } - - epkt = (ngx_mysql_error_pkt_t *) pkt; - - msg.len = (u_char *) epkt + 4 + len - epkt->message; - msg.data = epkt->message; - - ngx_log_error(NGX_LOG_ERR, rev->log, 0, - "mysql server %V sent error (%ud): \"%V\"", - m->peer.name, ngx_m16toh(epkt->code), &msg); - - ngx_mysql_close(m, NGX_ERROR); -} - - -ngx_int_t -ngx_mysql_query(ngx_mysql_t *m) -{ - ssize_t n; - ngx_mysql_command_pkt_t *pkt; - - pkt = (ngx_mysql_command_pkt_t *) m->query.data; - - ngx_htom24(pkt->pktlen, m->query.len - 4); - pkt->pktn = (u_char) m->pktn++; - pkt->command = NGX_MYSQL_CMD_QUERY; - - n = ngx_send(m->peer.connection, m->query.data, m->query.len); - - if (n < (ssize_t) m->query.len) { - ngx_log_error(NGX_LOG_ERR, m->peer.log, 0, - "the incomplete packet was sent to mysql server %V", - m->peer.name); - - ngx_mysql_close(m, NGX_ERROR); - return NGX_OK; - } - - m->peer.connection->read->handler = ngx_mysql_read_query_result; - - ngx_add_timer(m->peer.connection->read, /* STUB */ 5000); - - /* STUB handle event */ - - return NGX_OK; -} - - -static void -ngx_mysql_read_query_result(ngx_event_t *rev) -{ - ssize_t n, len; - ngx_str_t msg; - ngx_mysql_t *m; - ngx_connection_t *c; - ngx_mysql_error_pkt_t *epkt; - ngx_mysql_response_pkt_t *pkt; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql read query result"); - - c = rev->data; - m = c->data; - - m->peer.log->action = "reading mysql read query result"; - - n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024); - - if (n == NGX_AGAIN) { - return; - } - - if (n < 5) { - ngx_mysql_close(m, NGX_ERROR); - return; - } - - pkt = (ngx_mysql_response_pkt_t *) m->buf->pos; - - len = ngx_m24toh(pkt->pktlen); - - if (len > n - 4) { - ngx_log_error(NGX_LOG_ERR, rev->log, 0, - "mysql server %V sent incomplete response packet", - m->peer.name); - - ngx_mysql_close(m, NGX_ERROR); - return; - } - - if (pkt->fields != 0xff) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "mysql query OK"); - - m->state = NGX_OK; - m->pktn = pkt->pktn; - - m->handler(m); - - return; - } - - epkt = (ngx_mysql_error_pkt_t *) pkt; - - msg.len = (u_char *) epkt + 4 + len - epkt->message; - msg.data = epkt->message; - - ngx_log_error(NGX_LOG_ERR, rev->log, 0, - "mysql server %V sent error (%ud): \"%V\"", - m->peer.name, ngx_m16toh(epkt->code), &msg); - - ngx_mysql_close(m, NGX_ERROR); -} - - -static void -ngx_mysql_close(ngx_mysql_t *m, ngx_int_t rc) -{ - if (rc == NGX_ERROR) { - ngx_close_connection(m->peer.connection); - } - - m->state = rc; - - m->handler(m); -} diff -r 3a50ccd94333 -r 4b420f9c4c5d src/mysql/ngx_mysql.h --- a/src/mysql/ngx_mysql.h Thu Mar 31 22:00:33 2016 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#ifndef _NGX_MYSQL_H_INCLUDED_ -#define _NGX_MYSQL_H_INCLUDED_ - - -#include -#include -#include -#include - - -typedef struct ngx_mysql_s ngx_mysql_t; - -typedef void (*ngx_mysql_handler_pt)(ngx_mysql_t *m); - - -struct ngx_mysql_s { - ngx_peer_connection_t peer; - - ngx_buf_t *buf; - ngx_pool_t *pool; - - ngx_str_t *login; - ngx_str_t *passwd; - ngx_str_t *database; - - ngx_str_t query; - - ngx_uint_t pktn; - - ngx_mysql_handler_pt handler; - void *data; - ngx_int_t state; - -}; - - -#define NGX_MYSQL_CMDPKT_LEN 5 - - -#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED && 0) - -#define ngx_m16toh(n) (*(uint32_t *) n & 0x0000ffff) -#define ngx_m24toh(n) (*(uint32_t *) n & 0x00ffffff) -#define ngx_m32toh(n) *(uint32_t *) n - -#define ngx_htom16(n, m) *(uint16_t *) n = (uint16_t) ((m) & 0xffff) - -#define ngx_htom24(n, m) (n)[0] = (u_char) ((m) & 0xff); \ - (n)[1] = (u_char) (((m) >> 8) & 0xff); \ - (n)[2] = (u_char) (((m) >> 16) & 0xff) - -#define ngx_htom32(n, m) *(uint32_t *) (n) = (m) - -#else - -#define ngx_m16toh(n) (n[0] | n[1] << 8) -#define ngx_m24toh(n) (n[0] | n[1] << 8 | n[2] << 16) -#define ngx_m32toh(n) (n[0] | n[1] << 8 | n[2] << 16 | n[3] << 24) - -#define ngx_htom16(n, m) (n)[0] = (u_char) (m); (n)[1] = (u_char) ((m) >> 8) - -#define ngx_htom24(n, m) (n)[0] = (u_char) ((m) & 0xff); \ - (n)[1] = (u_char) (((m) >> 8) & 0xff); \ - (n)[2] = (u_char) (((m) >> 16) & 0xff) - -#define ngx_htom32(n, m) (n)[0] = (u_char) ((m) & 0xff); \ - (n)[1] = (u_char) (((m) >> 8) & 0xff); \ - (n)[2] = (u_char) (((m) >> 16) & 0xff); \ - (n)[3] = (u_char) (((m) >> 24) & 0xff) - -#endif - - -ngx_int_t ngx_mysql_connect(ngx_mysql_t *m); -ngx_int_t ngx_mysql_query(ngx_mysql_t *m); - - -#endif /* _NGX_MYSQL_H_INCLUDED_ */ From mdounin at mdounin.ru Thu Mar 31 23:57:31 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 31 Mar 2016 23:57:31 +0000 Subject: [nginx] SSL: reasonable version for LibreSSL. Message-ID: details: http://hg.nginx.org/nginx/rev/382fc7069e3a branches: changeset: 6485:382fc7069e3a user: Maxim Dounin date: Thu Mar 31 23:38:29 2016 +0300 description: SSL: reasonable version for LibreSSL. LibreSSL defines OPENSSL_VERSION_NUMBER to 0x20000000L, but uses an old API derived from OpenSSL at the time LibreSSL forked. As a result, every version check we use to test for new API elements in newer OpenSSL versions requires an explicit check for LibreSSL. To reduce clutter, redefine OPENSSL_VERSION_NUMBER to 0x1000107fL if LibreSSL is used. The same is done by FreeBSD port of LibreSSL. diffstat: src/event/ngx_event_openssl.c | 6 +++--- src/event/ngx_event_openssl.h | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diffs (46 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -52,7 +52,7 @@ static int ngx_ssl_session_ticket_key_ca HMAC_CTX *hctx, int enc); #endif -#if (OPENSSL_VERSION_NUMBER < 0x10002002L || defined LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER < 0x10002002L static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str); #endif @@ -2944,7 +2944,7 @@ ngx_ssl_check_host(ngx_connection_t *c, return NGX_ERROR; } -#if (OPENSSL_VERSION_NUMBER >= 0x10002002L && !defined LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER >= 0x10002002L /* X509_check_host() is only available in OpenSSL 1.0.2+ */ @@ -3061,7 +3061,7 @@ found: } -#if (OPENSSL_VERSION_NUMBER < 0x10002002L || defined LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER < 0x10002002L static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern) diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -33,6 +33,12 @@ #define NGX_SSL_NAME "OpenSSL" +#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L) +#undef OPENSSL_VERSION_NUMBER +#define OPENSSL_VERSION_NUMBER 0x1000107fL +#endif + + #define ngx_ssl_session_t SSL_SESSION #define ngx_ssl_conn_t SSL From mdounin at mdounin.ru Thu Mar 31 23:57:34 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 31 Mar 2016 23:57:34 +0000 Subject: [nginx] SSL: guarded error codes not present in OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/978ad80b3732 branches: changeset: 6486:978ad80b3732 user: Maxim Dounin date: Thu Mar 31 23:38:31 2016 +0300 description: SSL: guarded error codes not present in OpenSSL 1.1.0. diffstat: src/event/ngx_event_openssl.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (22 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -1956,6 +1956,7 @@ ngx_ssl_connection_error(ngx_connection_ || n == SSL_R_INAPPROPRIATE_FALLBACK /* 373 */ #endif || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */ +#ifdef SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */ || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC /* 1020 */ || n == SSL_R_TLSV1_ALERT_DECRYPTION_FAILED /* 1021 */ @@ -1978,7 +1979,9 @@ ngx_ssl_connection_error(ngx_connection_ || n == SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY /* 1071 */ || n == SSL_R_TLSV1_ALERT_INTERNAL_ERROR /* 1080 */ || n == SSL_R_TLSV1_ALERT_USER_CANCELLED /* 1090 */ - || n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION) /* 1100 */ + || n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION /* 1100 */ +#endif + ) { switch (c->log_error) { From mdounin at mdounin.ru Thu Mar 31 23:57:36 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 31 Mar 2016 23:57:36 +0000 Subject: [nginx] SSL: get_session callback changed in OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/9dd43f4ef67e branches: changeset: 6487:9dd43f4ef67e user: Maxim Dounin date: Thu Mar 31 23:38:32 2016 +0300 description: SSL: get_session callback changed in OpenSSL 1.1.0. diffstat: src/event/ngx_event_openssl.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diffs (46 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -39,6 +39,9 @@ ngx_int_t ngx_ssl_session_cache_init(ngx static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess); static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, +#if OPENSSL_VERSION_NUMBER >= 0x10100003L + const +#endif u_char *id, int len, int *copy); static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess); static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, @@ -2445,8 +2448,11 @@ failed: static ngx_ssl_session_t * -ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len, - int *copy) +ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, +#if OPENSSL_VERSION_NUMBER >= 0x10100003L + const +#endif + u_char *id, int len, int *copy) { #if OPENSSL_VERSION_NUMBER >= 0x0090707fL const @@ -2463,7 +2469,7 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_ u_char buf[NGX_SSL_MAX_SESSION_SIZE]; ngx_connection_t *c; - hash = ngx_crc32_short(id, (size_t) len); + hash = ngx_crc32_short((u_char *) (uintptr_t) id, (size_t) len); *copy = 0; c = ngx_ssl_get_connection(ssl_conn); @@ -2501,7 +2507,8 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_ sess_id = (ngx_ssl_sess_id_t *) node; - rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data); + rc = ngx_memn2cmp((u_char *) (uintptr_t) id, sess_id->id, + (size_t) len, (size_t) node->data); if (rc == 0) { From mdounin at mdounin.ru Thu Mar 31 23:57:38 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 31 Mar 2016 23:57:38 +0000 Subject: [nginx] SSL: initialization changes for OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/a57b2b8999e7 branches: changeset: 6488:a57b2b8999e7 user: Maxim Dounin date: Thu Mar 31 23:38:33 2016 +0300 description: SSL: initialization changes for OpenSSL 1.1.0. OPENSSL_config() deprecated in OpenSSL 1.1.0. Additionally, SSL_library_init(), SSL_load_error_strings() and OpenSSL_add_all_algorithms() are no longer available if OPENSSL_API_COMPAT is set to 0x10100000L. The OPENSSL_init_ssl() function is now used instead with appropriate arguments to trigger the same behaviour. The configure test changed to use SSL_CTX_set_options(). Deinitialization now happens automatically in OPENSSL_cleanup() called via atexit(3), so we no longer call EVP_cleanup() and ENGINE_cleanup() directly. diffstat: auto/lib/openssl/conf | 2 +- src/event/ngx_event_openssl.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletions(-) diffs (50 lines): diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf --- a/auto/lib/openssl/conf +++ b/auto/lib/openssl/conf @@ -52,7 +52,7 @@ else ngx_feature_incs="#include " ngx_feature_path= ngx_feature_libs="-lssl -lcrypto $NGX_LIBDL" - ngx_feature_test="SSL_library_init()" + ngx_feature_test="SSL_CTX_set_options(NULL, 0)" . auto/feature if [ $ngx_found = no ]; then diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -111,6 +111,12 @@ int ngx_ssl_stapling_index; ngx_int_t ngx_ssl_init(ngx_log_t *log) { +#if OPENSSL_VERSION_NUMBER >= 0x10100003L + + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); + +#else + #ifndef OPENSSL_IS_BORINGSSL OPENSSL_config(NULL); #endif @@ -120,6 +126,8 @@ ngx_ssl_init(ngx_log_t *log) OpenSSL_add_all_algorithms(); +#endif + #if OPENSSL_VERSION_NUMBER >= 0x0090800fL #ifndef SSL_OP_NO_COMPRESSION { @@ -3548,8 +3556,12 @@ ngx_openssl_engine(ngx_conf_t *cf, ngx_c static void ngx_openssl_exit(ngx_cycle_t *cycle) { +#if OPENSSL_VERSION_NUMBER < 0x10100003L + EVP_cleanup(); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif + +#endif } From mdounin at mdounin.ru Thu Mar 31 23:57:41 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 31 Mar 2016 23:57:41 +0000 Subject: [nginx] SSL: RSA_generate_key() is deprecated in OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/c256dfdd469d branches: changeset: 6489:c256dfdd469d user: Maxim Dounin date: Thu Mar 31 23:38:34 2016 +0300 description: SSL: RSA_generate_key() is deprecated in OpenSSL 1.1.0. OpenSSL removed support for all 40 and 56 bit ciphers. diffstat: src/event/ngx_event_openssl.c | 2 +- src/http/modules/ngx_http_ssl_module.c | 2 +- src/mail/ngx_mail_ssl_module.c | 2 +- src/stream/ngx_stream_ssl_module.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diffs (48 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -758,7 +758,7 @@ ngx_ssl_rsa512_key_callback(ngx_ssl_conn return NULL; } -#ifndef OPENSSL_NO_DEPRECATED +#if (OPENSSL_VERSION_NUMBER < 0x10100003L && !defined OPENSSL_NO_DEPRECATED) if (key == NULL) { key = RSA_generate_key(512, RSA_F4, NULL, NULL); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -718,7 +718,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } -#ifndef LIBRESSL_VERSION_NUMBER +#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) /* a temporary 512-bit RSA key is required for export versions of MSIE */ SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); #endif diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -421,7 +421,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } -#ifndef LIBRESSL_VERSION_NUMBER +#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); #endif diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -276,7 +276,7 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } -#ifndef LIBRESSL_VERSION_NUMBER +#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); #endif From mdounin at mdounin.ru Thu Mar 31 23:57:44 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 31 Mar 2016 23:57:44 +0000 Subject: [nginx] SSL: EVP_MD_CTX was made opaque in OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/ddf761495ce6 branches: changeset: 6490:ddf761495ce6 user: Sergey Kandaurov date: Thu Mar 31 23:38:36 2016 +0300 description: SSL: EVP_MD_CTX was made opaque in OpenSSL 1.1.0. diffstat: src/event/ngx_event_openssl.c | 23 +++++++++++++---------- 1 files changed, 13 insertions(+), 10 deletions(-) diffs (78 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -2157,7 +2157,7 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss int n, i; X509 *cert; X509_NAME *name; - EVP_MD_CTX md; + EVP_MD_CTX *md; unsigned int len; STACK_OF(X509_NAME) *list; u_char buf[EVP_MAX_MD_SIZE]; @@ -2167,15 +2167,18 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss * the server certificate, and the client CA list. */ - EVP_MD_CTX_init(&md); - - if (EVP_DigestInit_ex(&md, EVP_sha1(), NULL) == 0) { + md = EVP_MD_CTX_create(); + if (md == NULL) { + return NGX_ERROR; + } + + if (EVP_DigestInit_ex(md, EVP_sha1(), NULL) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestInit_ex() failed"); goto failed; } - if (EVP_DigestUpdate(&md, sess_ctx->data, sess_ctx->len) == 0) { + if (EVP_DigestUpdate(md, sess_ctx->data, sess_ctx->len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestUpdate() failed"); goto failed; @@ -2189,7 +2192,7 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss goto failed; } - if (EVP_DigestUpdate(&md, buf, len) == 0) { + if (EVP_DigestUpdate(md, buf, len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestUpdate() failed"); goto failed; @@ -2209,7 +2212,7 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss goto failed; } - if (EVP_DigestUpdate(&md, buf, len) == 0) { + if (EVP_DigestUpdate(md, buf, len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestUpdate() failed"); goto failed; @@ -2217,13 +2220,13 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss } } - if (EVP_DigestFinal_ex(&md, buf, &len) == 0) { + if (EVP_DigestFinal_ex(md, buf, &len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestUpdate() failed"); goto failed; } - EVP_MD_CTX_cleanup(&md); + EVP_MD_CTX_destroy(md); if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, @@ -2235,7 +2238,7 @@ ngx_ssl_session_id_context(ngx_ssl_t *ss failed: - EVP_MD_CTX_cleanup(&md); + EVP_MD_CTX_destroy(md); return NGX_ERROR; } From mdounin at mdounin.ru Thu Mar 31 23:57:46 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 31 Mar 2016 23:57:46 +0000 Subject: [nginx] SSL: X509 was made opaque in OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/45f2385a47e6 branches: changeset: 6491:45f2385a47e6 user: Sergey Kandaurov date: Thu Mar 31 23:38:37 2016 +0300 description: SSL: X509 was made opaque in OpenSSL 1.1.0. To increment reference counters we now use newly introduced X509_up_ref() function. diffstat: src/event/ngx_event_openssl_stapling.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (15 lines): diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -285,7 +285,11 @@ ngx_ssl_stapling_issuer(ngx_conf_t *cf, for (i = 0; i < n; i++) { issuer = sk_X509_value(chain, i); if (X509_check_issued(issuer, cert) == X509_V_OK) { +#if OPENSSL_VERSION_NUMBER >= 0x10100001L + X509_up_ref(issuer); +#else CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509); +#endif ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: found %p in extra certs", issuer); From mdounin at mdounin.ru Thu Mar 31 23:57:48 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 31 Mar 2016 23:57:48 +0000 Subject: [nginx] SSL: SSLeay_version() is deprecated in OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/3b77efe05b92 branches: changeset: 6492:3b77efe05b92 user: Maxim Dounin date: Thu Mar 31 23:38:38 2016 +0300 description: SSL: SSLeay_version() is deprecated in OpenSSL 1.1.0. SSLeay_version() and SSLeay() are no longer available if OPENSSL_API_COMPAT is set to 0x10100000L. Switched to using OpenSSL_version() instead. Additionally, we now compare version strings instead of version numbers, and this correctly works for LibreSSL as well. diffstat: src/core/nginx.c | 5 ++--- src/event/ngx_event_openssl.h | 11 +++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diffs (40 lines): diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -413,13 +413,12 @@ ngx_show_version_info(void) #endif #if (NGX_SSL) - if (SSLeay() == SSLEAY_VERSION_NUMBER) { + if (ngx_strcmp(ngx_ssl_version(), OPENSSL_VERSION_TEXT) == 0) { ngx_write_stderr("built with " OPENSSL_VERSION_TEXT NGX_LINEFEED); } else { ngx_write_stderr("built with " OPENSSL_VERSION_TEXT " (running with "); - ngx_write_stderr((char *) (uintptr_t) - SSLeay_version(SSLEAY_VERSION)); + ngx_write_stderr((char *) (uintptr_t) ngx_ssl_version()); ngx_write_stderr(")" NGX_LINEFEED); } #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -39,6 +39,17 @@ #endif +#if (OPENSSL_VERSION_NUMBER >= 0x10100001L) + +#define ngx_ssl_version() OpenSSL_version(OPENSSL_VERSION) + +#else + +#define ngx_ssl_version() SSLeay_version(SSLEAY_VERSION) + +#endif + + #define ngx_ssl_session_t SSL_SESSION #define ngx_ssl_conn_t SSL