# HG changeset patch # User Igor Sysoev # Date 1145303741 0 # Node ID 18268abd340cb351e0c01b9c44e9f8cc05492364 # Parent af8e203680226276a814116bde6b0705d630d5da nginx-0.3.39-RELEASE import *) Feature: the "uninitialized_variable_warn" directive; the logging level of the "uninitialized variable" message was lowered from "alert" to "warn". *) Feature: the "override_charset" directive. *) Change: now if the unknown variable is used in the "echo" and "if expr='$name'" SSI-commands, then the "unknown variable" message is not logged. *) Bugfix: the active connection counter increased on the exceeding of the connection limit specified by the "worker_connections" directive; the bug had appeared in 0.2.0. *) Bugfix: the limit rate might not work on some condition; the bug had appeared in 0.3.38. diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -236,6 +236,9 @@ cat << END --with-http_ssl_module enable ngx_http_ssl_module --with-http_realip_module enable ngx_http_realip_module + --with-http_addition_module enable ngx_http_addition_module + --with-http_dav_module enable ngx_http_dav_module + --without-http_charset_module disable ngx_http_charset_module --without-http_gzip_module disable ngx_http_gzip_module --without-http_ssi_module disable ngx_http_ssi_module @@ -257,11 +260,10 @@ cat << END --http-log-path=PATH set path to the http access log --http-client-body-temp-path=PATH set path to the http client request body - temporary files path - --http-proxy-temp-path=PATH set path to the http proxy temporary - files path + temporary files + --http-proxy-temp-path=PATH set path to the http proxy temporary files --http-fastcgi-temp-path=PATH set path to the http fastcgi temporary - files path + files --without-http disable HTTP server 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 @@ -9,6 +9,66 @@ nginx changelog + + + + +директива uninitialized_variable_warn; уровень логгирования сообщения +о неинициализированной переменной понижен с уровня alert на warn. + + +the "uninitialized_variable_warn" directive; the logging level of the +"uninitialized variable" message was lowered from "alert" to "warn". + + + + + +директива override_charset. + + +the "override_charset" directive. + + + + + +при использовании неизвестной переменной в SSI-командах echo и if expr='$name' +теперь не записывается в лог сообщение о неизвестной переменной. + + +now if the unknown variable is used in the "echo" and "if expr='$name'" +SSI-commands, then the "unknown variable" message is not logged. + + + + + +счётчик активных соединений рос при превышении лимита соединений, +заданного директивой worker_connections; +ошибка появилась в 0.2.0. + + +the active connection counter increased on the exceeding of the connection +limit specified by the "worker_connections" directive; +bug appeared in 0.2.0. + + + + + +при некоторых условия ограничение скорости соединения могло не работать; +ошибка появилась в 0.3.38. + + +the limit rate might not work on some condition; +bug appeared in 0.3.38. + + + + + + diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.3.38" +#define NGINX_VER "nginx/0.3.39" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -386,6 +386,21 @@ ngx_configure_listening_socket(ngx_cycle } } +#if 0 + if (1) { + int tcp_nodelay = 1; + + if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(TCP_NODELAY) %V failed, ignored", + &ls[i].addr_text); + } + } +#endif + if (ls[i].listen) { if (listen(ls[i].fd, ls[i].backlog) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -78,7 +78,6 @@ ngx_event_accept(ngx_event_t *ev) #if (NGX_STAT_STUB) ngx_atomic_fetch_add(ngx_stat_accepted, 1); - ngx_atomic_fetch_add(ngx_stat_active, 1); #endif ngx_accept_disabled = NGX_ACCEPT_THRESHOLD @@ -95,6 +94,10 @@ ngx_event_accept(ngx_event_t *ev) return; } +#if (NGX_STAT_STUB) + 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); diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c --- a/src/http/modules/ngx_http_charset_filter_module.c +++ b/src/http/modules/ngx_http_charset_filter_module.c @@ -13,47 +13,48 @@ typedef struct { - char **tables; - ngx_str_t name; + u_char **tables; + ngx_str_t name; - ngx_uint_t utf8; /* unsigned utf8:1; */ + ngx_uint_t utf8; /* unsigned utf8:1; */ } ngx_http_charset_t; typedef struct { - ngx_int_t src; - ngx_int_t dst; + ngx_int_t src; + ngx_int_t dst; } ngx_http_charset_recode_t; typedef struct { - ngx_int_t src; - ngx_int_t dst; - char *src2dst; - char *dst2src; + ngx_int_t src; + ngx_int_t dst; + u_char *src2dst; + u_char *dst2src; } ngx_http_charset_tables_t; typedef struct { - ngx_array_t charsets; /* ngx_http_charset_t */ - ngx_array_t tables; /* ngx_http_charset_tables_t */ - ngx_array_t recodes; /* ngx_http_charset_recode_t */ + ngx_array_t charsets; /* ngx_http_charset_t */ + ngx_array_t tables; /* ngx_http_charset_tables_t */ + ngx_array_t recodes; /* ngx_http_charset_recode_t */ } ngx_http_charset_main_conf_t; typedef struct { - ngx_int_t charset; - ngx_int_t source_charset; + ngx_int_t charset; + ngx_int_t source_charset; + ngx_flag_t override_charset; } ngx_http_charset_loc_conf_t; typedef struct { - ngx_int_t server; - ngx_int_t client; + u_char *table; + ngx_int_t charset; } ngx_http_charset_ctx_t; -static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, char *table); +static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table); static char *ngx_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -90,6 +91,14 @@ static ngx_command_t ngx_http_charset_f offsetof(ngx_http_charset_loc_conf_t, source_charset), NULL }, + { ngx_string("override_charset"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF + |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_charset_loc_conf_t, override_charset), + NULL }, + { ngx_string("charset_map"), NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2, ngx_charset_map_block, @@ -139,16 +148,30 @@ static ngx_http_output_body_filter_pt static ngx_int_t ngx_http_charset_header_filter(ngx_http_request_t *r) { + size_t len; + u_char *p; + ngx_int_t charset, source_charset; + ngx_uint_t i; ngx_http_charset_t *charsets; ngx_http_charset_ctx_t *ctx; ngx_http_charset_loc_conf_t *lcf; ngx_http_charset_main_conf_t *mcf; mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); - lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); + + ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module); - if (lcf->charset == NGX_HTTP_NO_CHARSET) { - return ngx_http_next_header_filter(r); + if (ctx == NULL) { + lcf = ngx_http_get_module_loc_conf(r->main, + ngx_http_charset_filter_module); + charset = lcf->charset; + + if (charset == NGX_HTTP_NO_CHARSET) { + return ngx_http_next_header_filter(r); + } + + } else { + charset = ctx->charset; } if (r->headers_out.content_type.len == 0) { @@ -162,9 +185,72 @@ ngx_http_charset_header_filter(ngx_http_ return ngx_http_next_header_filter(r); } - if (r == r->main - && ngx_strstr(r->headers_out.content_type.data, "charset") != NULL) - { + charsets = mcf->charsets.elts; + + lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); + + len = 0; + + for (p = r->headers_out.content_type.data; *p; p++) { + if (*p == ';') { + len = p - r->headers_out.content_type.data; + } + + if (ngx_strncasecmp(p, "charset=", 8) != 0) { + continue; + } + + p += 8; + + for (i = 0; i < mcf->charsets.nelts; i++) { + + if (ngx_strcasecmp(p, charsets[i].name.data) == 0) { + + if (r == r->main && lcf->override_charset == 0) { + ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t)); + if (ctx == NULL) { + return NGX_ERROR; + } + + ngx_http_set_ctx(r, ctx, ngx_http_charset_filter_module); + + ctx->charset = i; + + return ngx_http_next_header_filter(r); + } + + if (i != (ngx_uint_t) charset + && (charsets[i].tables == NULL + || charsets[i].tables[charset] == NULL)) + { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "no \"charset_map\" between the charsets " + "\"%V\" and \"%V\"", + &charsets[i].name, &charsets[charset].name); + + return ngx_http_next_header_filter(r); + } + + r->headers_out.content_type.len = len; + + if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY + || r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY) + { + /* + * do not set charset for the redirect because NN 4.x + * uses this charset instead of the next page charset + */ + + r->headers_out.charset.len = 0; + return ngx_http_next_header_filter(r); + } + + source_charset = i; + + goto found; + } + } + return ngx_http_next_header_filter(r); } @@ -172,8 +258,8 @@ ngx_http_charset_header_filter(ngx_http_ || r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY) { /* - * do not set charset for the redirect because NN 4.x uses this - * charset instead of the next page charset + * do not set charset for the redirect because NN 4.x + * use this charset instead of the next page charset */ r->headers_out.charset.len = 0; @@ -184,17 +270,17 @@ ngx_http_charset_header_filter(ngx_http_ return ngx_http_next_header_filter(r); } - charsets = mcf->charsets.elts; - r->headers_out.charset = charsets[lcf->charset].name; - r->utf8 = charsets[lcf->charset].utf8; + source_charset = lcf->source_charset; + +found: - if (lcf->source_charset == NGX_CONF_UNSET - || lcf->source_charset == lcf->charset) - { + r->headers_out.charset = charsets[charset].name; + r->utf8 = charsets[charset].utf8; + + if (source_charset == NGX_CONF_UNSET || source_charset == charset) { return ngx_http_next_header_filter(r); } - ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t)); if (ctx == NULL) { return NGX_ERROR; @@ -202,6 +288,8 @@ ngx_http_charset_header_filter(ngx_http_ ngx_http_set_ctx(r, ctx, ngx_http_charset_filter_module); + ctx->table = charsets[source_charset].tables[charset]; + ctx->charset = charset; r->filter_need_in_memory = 1; @@ -212,27 +300,17 @@ ngx_http_charset_header_filter(ngx_http_ static ngx_int_t ngx_http_charset_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { - char *table; - ngx_chain_t *cl; - ngx_http_charset_t *charsets; - ngx_http_charset_ctx_t *ctx; - ngx_http_charset_loc_conf_t *lcf; - ngx_http_charset_main_conf_t *mcf; + ngx_chain_t *cl; + ngx_http_charset_ctx_t *ctx; ctx = ngx_http_get_module_ctx(r, ngx_http_charset_filter_module); - if (ctx == NULL) { + if (ctx == NULL || ctx->table == NULL) { return ngx_http_next_body_filter(r, in); } - mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); - lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); - - charsets = mcf->charsets.elts; - table = charsets[lcf->source_charset].tables[lcf->charset]; - for (cl = in; cl; cl = cl->next) { - ngx_http_charset_recode(cl->buf, table); + (void) ngx_http_charset_recode(cl->buf, ctx->table); } return ngx_http_next_body_filter(r, in); @@ -240,21 +318,15 @@ ngx_http_charset_body_filter(ngx_http_re static ngx_uint_t -ngx_http_charset_recode(ngx_buf_t *b, char *table) +ngx_http_charset_recode(ngx_buf_t *b, u_char *table) { - u_char *p; - ngx_uint_t change; - - change = 0; + u_char *p; for (p = b->pos; p < b->last; p++) { - if (*p != table[*p]) { - change = 1; - break; + + if (*p == table[*p]) { + continue; } - } - - if (change) { while (p < b->last) { *p = table[*p]; @@ -262,9 +334,11 @@ ngx_http_charset_recode(ngx_buf_t *b, ch } b->in_file = 0; + + return 1; } - return change; + return 0; } @@ -330,8 +404,8 @@ ngx_charset_map_block(ngx_conf_t *cf, ng } for (i = 0; i < 128; i++) { - table->src2dst[i] = (char) i; - table->dst2src[i] = (char) i; + table->src2dst[i] = (u_char) i; + table->dst2src[i] = (u_char) i; } for (/* void */; i < 256; i++) { @@ -382,8 +456,8 @@ ngx_charset_map(ngx_conf_t *cf, ngx_comm table = cf->ctx; - table->src2dst[src] = (char) dst; - table->dst2src[dst] = (char) src; + table->src2dst[src] = (u_char) dst; + table->dst2src[dst] = (u_char) src; return NGX_CONF_OK; } @@ -519,6 +593,7 @@ ngx_http_charset_create_loc_conf(ngx_con lcf->charset = NGX_CONF_UNSET; lcf->source_charset = NGX_CONF_UNSET; + lcf->override_charset = NGX_CONF_UNSET; return lcf; } @@ -534,6 +609,7 @@ ngx_http_charset_merge_loc_conf(ngx_conf ngx_http_charset_recode_t *recode; ngx_http_charset_main_conf_t *mcf; + ngx_conf_merge_value(conf->override_charset, prev->override_charset, 0); ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_NO_CHARSET); if (conf->source_charset == NGX_CONF_UNSET) { @@ -573,6 +649,7 @@ ngx_http_charset_merge_loc_conf(ngx_conf static ngx_int_t ngx_http_charset_postconfiguration(ngx_conf_t *cf) { + u_char **src, **dst; ngx_int_t c; ngx_uint_t i, t; ngx_http_charset_t *charset; @@ -591,21 +668,13 @@ ngx_http_charset_postconfiguration(ngx_c c = recode[i].src; - charset[c].tables = ngx_pcalloc(cf->pool, - sizeof(char *) * mcf->charsets.nelts); - if (charset[c].tables == NULL) { - return NGX_ERROR; - } - for (t = 0; t < mcf->tables.nelts; t++) { if (c == tables[t].src && recode[i].dst == tables[t].dst) { - charset[c].tables[tables[t].dst] = tables[t].src2dst; goto next; } if (c == tables[t].dst && recode[i].dst == tables[t].src) { - charset[c].tables[tables[t].src] = tables[t].dst2src; goto next; } } @@ -620,5 +689,34 @@ ngx_http_charset_postconfiguration(ngx_c continue; } + + for (t = 0; t < mcf->tables.nelts; t++) { + + src = charset[tables[t].src].tables; + + if (src == NULL) { + src = ngx_pcalloc(cf->pool, sizeof(u_char *) * mcf->charsets.nelts); + if (src == NULL) { + return NGX_ERROR; + } + + charset[tables[t].src].tables = src; + } + + dst = charset[tables[t].dst].tables; + + if (dst == NULL) { + dst = ngx_pcalloc(cf->pool, sizeof(u_char *) * mcf->charsets.nelts); + if (dst == NULL) { + return NGX_ERROR; + } + + charset[tables[t].dst].tables = dst; + } + + src[tables[t].dst] = tables[t].src2dst; + dst[tables[t].src] = tables[t].dst2src; + } + return NGX_OK; } diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -16,6 +16,7 @@ typedef struct { ngx_uint_t stack_size; ngx_flag_t log; + ngx_flag_t uninitialized_variable_warn; } ngx_http_rewrite_loc_conf_t; @@ -91,13 +92,21 @@ static ngx_command_t ngx_http_rewrite_c NULL }, { ngx_string("rewrite_log"), - NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF - |NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF + |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_rewrite_loc_conf_t, log), NULL }, + { ngx_string("uninitialized_variable_warn"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF + |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_rewrite_loc_conf_t, uninitialized_variable_warn), + NULL }, + ngx_null_command }; @@ -138,11 +147,11 @@ ngx_http_rewrite_handler(ngx_http_reques { ngx_http_script_code_pt code; ngx_http_script_engine_t *e; - ngx_http_rewrite_loc_conf_t *cf; + ngx_http_rewrite_loc_conf_t *rlcf; - cf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module); + rlcf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module); - if (cf->codes == NULL) { + if (rlcf->codes == NULL) { return NGX_DECLINED; } @@ -152,13 +161,13 @@ ngx_http_rewrite_handler(ngx_http_reques } e->sp = ngx_pcalloc(r->pool, - cf->stack_size * sizeof(ngx_http_variable_value_t)); + rlcf->stack_size * sizeof(ngx_http_variable_value_t)); if (e->sp == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (cf->captures) { - e->captures = ngx_palloc(r->pool, cf->captures * sizeof(int)); + if (rlcf->captures) { + e->captures = ngx_palloc(r->pool, rlcf->captures * sizeof(int)); if (e->captures == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -167,10 +176,10 @@ ngx_http_rewrite_handler(ngx_http_reques e->captures = NULL; } - e->ip = cf->codes->elts; + e->ip = rlcf->codes->elts; e->request = r; e->quote = 1; - e->log = cf->log; + e->log = rlcf->log; e->status = NGX_DECLINED; while (*(uintptr_t *) e->ip) { @@ -186,8 +195,16 @@ static ngx_int_t ngx_http_rewrite_var(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - ngx_http_variable_t *var; - ngx_http_core_main_conf_t *cmcf; + ngx_http_variable_t *var; + ngx_http_core_main_conf_t *cmcf; + ngx_http_rewrite_loc_conf_t *rlcf; + + rlcf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module); + + if (rlcf->uninitialized_variable_warn == 0) { + *v = ngx_http_variable_null_value; + return NGX_OK; + } cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); @@ -199,7 +216,7 @@ ngx_http_rewrite_var(ngx_http_request_t * so the handler is called only if the variable is not initialized */ - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, "using uninitialized \"%V\" variable", &var[data].name); *v = ngx_http_variable_null_value; @@ -220,6 +237,7 @@ ngx_http_rewrite_create_loc_conf(ngx_con conf->stack_size = NGX_CONF_UNSET_UINT; conf->log = NGX_CONF_UNSET; + conf->uninitialized_variable_warn = NGX_CONF_UNSET; return conf; } @@ -234,6 +252,8 @@ ngx_http_rewrite_merge_loc_conf(ngx_conf uintptr_t *code; ngx_conf_merge_value(conf->log, prev->log, 0); + ngx_conf_merge_value(conf->uninitialized_variable_warn, + prev->uninitialized_variable_warn, 1); ngx_conf_merge_unsigned_value(conf->stack_size, prev->stack_size, 10); if (conf->codes == NULL) { diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -14,6 +14,7 @@ #define NGX_HTTP_SSI_ADD_PREFIX 1 #define NGX_HTTP_SSI_ADD_ZERO 2 +#define NGX_HTTP_SSI_EXPR_TEST 4 typedef struct { @@ -1502,8 +1503,8 @@ ngx_http_ssi_evaluate_string(ngx_http_re val = ngx_http_ssi_get_variable(r, &var, key); if (val == NULL) { - vv = ngx_http_get_variable(r, &var, key); - + vv = ngx_http_get_variable(r, &var, key, + flags & NGX_HTTP_SSI_EXPR_TEST); if (vv == NULL) { return NGX_ERROR; } @@ -1681,7 +1682,7 @@ ngx_http_ssi_echo(ngx_http_request_t *r, value = ngx_http_ssi_get_variable(r, var, key); if (value == NULL) { - vv = ngx_http_get_variable(r, var, key); + vv = ngx_http_get_variable(r, var, key, 1); if (vv == NULL) { return NGX_HTTP_SSI_ERROR; @@ -1873,10 +1874,12 @@ ngx_http_ssi_if(ngx_http_request_t *r, n p++; } + flags = (p == last) ? NGX_HTTP_SSI_EXPR_TEST : 0; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "left: \"%V\"", &left); - if (ngx_http_ssi_evaluate_string(r, ctx, &left, 0) != NGX_OK) { + if (ngx_http_ssi_evaluate_string(r, ctx, &left, flags) != NGX_OK) { return NGX_HTTP_SSI_ERROR; } diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -188,6 +188,7 @@ ngx_http_perl_handler(ngx_http_request_t r->request_body_in_single_buf = 1; r->request_body_in_persistent_file = 1; + r->request_body_delete_incomplete_file = 1; rc = ngx_http_read_client_request_body(r, ngx_http_perl_handle_request); 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 @@ -486,8 +486,8 @@ ngx_http_handler(ngx_http_request_t *r) if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) { /* - * MSIE may wait for some time if the response for the POST request - * is sent over the keepalive connection + * MSIE may wait for some time if the response for + * the POST request is sent over the keepalive connection */ r->keepalive = 0; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1473,21 +1473,6 @@ ngx_http_finalize_request(ngx_http_reque &pr->uri, &pr->args); pr->write_event_handler(pr); - -#if 0 - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http request: \"%V?%V\" still has postponed", - &pr->uri, &pr->args); - - if (pr->done || pr->postponed->out) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http wake parent request: \"%V?%V\"", - &pr->uri, &pr->args); - - pr->write_event_handler(pr); - } -#endif - } return; @@ -1856,7 +1841,8 @@ ngx_http_set_keepalive(ngx_http_request_ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) + (const void *) &tcp_nodelay, sizeof(int)) + == -1) { ngx_connection_error(c, ngx_socket_errno, "setsockopt(TCP_NODELAY) failed"); diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -324,7 +324,8 @@ ngx_http_get_flushed_variable(ngx_http_r ngx_http_variable_value_t * -ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key) +ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key, + ngx_uint_t nowarn) { ngx_http_variable_t *v; ngx_http_variable_value_t *vv; @@ -377,10 +378,12 @@ ngx_http_get_variable(ngx_http_request_t return NULL; } - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "unknown \"%V\" variable", name); + vv->not_found = 1; - vv->not_found = 1; + if (nowarn == 0) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "unknown \"%V\" variable", name); + } return vv; } diff --git a/src/http/ngx_http_variables.h b/src/http/ngx_http_variables.h --- a/src/http/ngx_http_variables.h +++ b/src/http/ngx_http_variables.h @@ -56,7 +56,7 @@ ngx_http_variable_value_t *ngx_http_get_ ngx_uint_t index); ngx_http_variable_value_t *ngx_http_get_variable(ngx_http_request_t *r, - ngx_str_t *name, ngx_uint_t key); + ngx_str_t *name, ngx_uint_t key, ngx_uint_t nowarn); #define ngx_http_clear_variable(r, index) r->variables0[index].text.data = NULL; diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c --- a/src/http/ngx_http_write_filter_module.c +++ b/src/http/ngx_http_write_filter_module.c @@ -209,9 +209,20 @@ ngx_http_write_filter(ngx_http_request_t return NGX_ERROR; } - to_send = r->limit_rate * (ngx_time() - r->start_time + 1) - c->sent; + if (r->limit_rate) { + to_send = r->limit_rate * (ngx_time() - r->start_time + 1) - c->sent; - if (to_send < 0) { + if (to_send <= 0) { + c->write->delayed = 1; + ngx_add_timer(r->connection->write, + (ngx_msec_t) (- to_send * 1000 / r->limit_rate)); + + c->buffered |= NGX_HTTP_WRITE_BUFFERED; + + return NGX_AGAIN; + } + + } else { to_send = 0; }