# HG changeset patch # User Igor Sysoev # Date 1177358400 -14400 # Node ID 30862655219e4c8933caf76bd9239488cb790e6a # Parent df0fd0d43ed89cbbcb504d5f90437689181faf1e nginx 0.5.19 *) Change: now the $request_time variable has millisecond precision. *) Change: the method $r->rflush of ngx_http_perl_module was renamed to the $r->flush. *) Feature: the $upstream_addr variable. *) Feature: the "proxy_headers_hash_max_size" and "proxy_headers_hash_bucket_size" directives. Thanks to Volodymyr Kostyrko. *) Bugfix: the files more than 2G could not be transferred using sendfile and limit_rate on 64-bit platforms. *) Bugfix: the files more than 2G could not be transferred using sendfile on 64-bit Linux. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,24 @@ +Changes with nginx 0.5.19 24 Apr 2007 + + *) Change: now the $request_time variable has millisecond precision. + + *) Change: the method $r->rflush of ngx_http_perl_module was renamed to + the $r->flush. + + *) Feature: the $upstream_addr variable. + + *) Feature: the "proxy_headers_hash_max_size" and + "proxy_headers_hash_bucket_size" directives. + Thanks to Volodymyr Kostyrko. + + *) Bugfix: the files more than 2G could not be transferred using + sendfile and limit_rate on 64-bit platforms. + + *) Bugfix: the files more than 2G could not be transferred using + sendfile on 64-bit Linux. + + Changes with nginx 0.5.18 19 Apr 2007 *) Feature: the ngx_http_sub_filter_module. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,25 @@ +Изменения в nginx 0.5.19 24.04.2007 + + *) Изменение: значение переменной $request_time теперь записывается с + точностью до миллисекунд. + + *) Изменение: метод $r->rflush в модуле ngx_http_perl_module + переименован в $r->flush. + + *) Добавление: переменная $upstream_addr. + + *) Добавление: директивы proxy_headers_hash_max_size и + proxy_headers_hash_bucket_size. + Спасибо Володымыру Костырко. + + *) Исправление: при использовании sendfile и limit_rate на 64-битных + платформах нельзя было передавать файлы больше 2G. + + *) Исправление: при использовании sendfile на 64-битном Linux нельзя + было передавать файлы больше 2G. + + Изменения в nginx 0.5.18 19.04.2007 *) Добавление: модуль ngx_http_sub_filter_module. 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_VERSION "0.5.18" +#define NGINX_VERSION "0.5.19" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c --- a/src/http/modules/ngx_http_log_module.c +++ b/src/http/modules/ngx_http_log_module.c @@ -170,7 +170,8 @@ static ngx_http_log_var_t ngx_http_log_ { ngx_string("time_local"), sizeof("28/Sep/1970:12:00:00 +0600") - 1, ngx_http_log_time }, { ngx_string("msec"), NGX_TIME_T_LEN + 4, ngx_http_log_msec }, - { ngx_string("request_time"), NGX_TIME_T_LEN, ngx_http_log_request_time }, + { ngx_string("request_time"), NGX_TIME_T_LEN + 4, + ngx_http_log_request_time }, { ngx_string("status"), 3, ngx_http_log_status }, { ngx_string("bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_bytes_sent }, { ngx_string("body_bytes_sent"), NGX_OFF_T_LEN, @@ -394,11 +395,15 @@ static u_char * ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) { - time_t elapsed; + ngx_time_t *tp; + ngx_msec_int_t ms; + + tp = ngx_timeofday(); - elapsed = ngx_time() - r->start_time; + ms = (tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec); + ms = (ms >= 0) ? ms : 0; - return ngx_sprintf(buf, "%T", elapsed); + return ngx_sprintf(buf, "%T.%03M", ms / 1000, ms % 1000); } 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 @@ -54,6 +54,9 @@ typedef struct { ngx_str_t port; ngx_flag_t redirect; + + ngx_uint_t headers_hash_max_size; + ngx_uint_t headers_hash_bucket_size; } ngx_http_proxy_loc_conf_t; @@ -207,6 +210,20 @@ static ngx_command_t ngx_http_proxy_com offsetof(ngx_http_proxy_loc_conf_t, headers_source), NULL }, + { ngx_string("proxy_headers_hash_max_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, headers_hash_max_size), + NULL }, + + { ngx_string("proxy_headers_hash_bucket_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, headers_hash_bucket_size), + NULL }, + { ngx_string("proxy_set_body"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -1510,6 +1527,9 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ conf->redirect = NGX_CONF_UNSET; conf->upstream.change_buffering = 1; + conf->headers_hash_max_size = NGX_CONF_UNSET_UINT; + conf->headers_hash_bucket_size = NGX_CONF_UNSET_UINT; + return conf; } @@ -1712,6 +1732,15 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t } } + ngx_conf_merge_uint_value(conf->headers_hash_max_size, + prev->headers_hash_max_size, 512); + + ngx_conf_merge_uint_value(conf->headers_hash_bucket_size, + prev->headers_hash_bucket_size, 64); + + conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size, + ngx_cacheline_size); + if (conf->upstream.hide_headers == NULL && conf->upstream.pass_headers == NULL) { @@ -1801,9 +1830,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t hash.hash = &conf->upstream.hide_headers_hash; hash.key = ngx_hash_key_lc; - hash.max_size = 512; - hash.bucket_size = ngx_align(64, ngx_cacheline_size); - hash.name = "proxy_hide_headers_hash"; + hash.max_size = conf->headers_hash_max_size; + hash.bucket_size = conf->headers_hash_bucket_size; + hash.name = "proxy_headers_hash"; hash.pool = cf->pool; hash.temp_pool = NULL; @@ -2071,9 +2100,9 @@ peers: hash.hash = &conf->headers_set_hash; hash.key = ngx_hash_key_lc; - hash.max_size = 512; - hash.bucket_size = ngx_cacheline_size; - hash.name = "proxy_set_header_hash"; + hash.max_size = conf->headers_hash_max_size; + hash.bucket_size = conf->headers_hash_bucket_size; + hash.name = "proxy_headers_hash"; hash.pool = cf->pool; hash.temp_pool = NULL; diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.5.18'; +our $VERSION = '0.5.19'; require XSLoader; XSLoader::load('nginx', $VERSION); @@ -92,6 +92,13 @@ use constant HTTP_GATEWAY_TIME_OUT use constant HTTP_INSUFFICIENT_STORAGE => 507; +sub rflush { + my $r = shift; + + $r->flush; +} + + 1; __END__ diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -681,7 +681,7 @@ sendfile(r, filename, offset = -1, bytes void -rflush(r) +flush(r) CODE: ngx_http_request_t *r; @@ -696,7 +696,7 @@ rflush(r) b->flush = 1; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->rflush"); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->flush"); (void) ngx_http_perl_output(r, b); 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 @@ -1353,8 +1353,6 @@ ngx_http_subrequest(ngx_http_request_t * sr->headers_in = r->headers_in; - sr->start_time = ngx_time(); - ngx_http_clear_content_length(sr); ngx_http_clear_accept_ranges(sr); ngx_http_clear_last_modified(sr); 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 @@ -212,6 +212,7 @@ ngx_http_init_connection(ngx_connection_ static void ngx_http_init_request(ngx_event_t *rev) { + ngx_time_t *tp; socklen_t len; ngx_uint_t i; struct sockaddr_in sin; @@ -421,7 +422,9 @@ ngx_http_init_request(ngx_event_t *rev) r->main = r; - r->start_time = ngx_time(); + tp = ngx_timeofday(); + r->start_sec = tp->sec; + r->start_msec = tp->msec; r->method = NGX_HTTP_UNKNOWN; diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -342,7 +342,8 @@ struct ngx_http_request_s { ngx_http_request_body_t *request_body; time_t lingering_time; - time_t start_time; + time_t start_sec; + ngx_msec_t start_msec; ngx_uint_t method; ngx_uint_t http_version; 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 @@ -72,6 +72,8 @@ static ngx_int_t ngx_http_upstream_copy_ #endif static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf); +static ngx_int_t ngx_http_upstream_addr_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r, @@ -257,6 +259,9 @@ ngx_module_t ngx_http_upstream_module = static ngx_http_variable_t ngx_http_upstream_vars[] = { + { ngx_string("upstream_addr"), NULL, + ngx_http_upstream_addr_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, + { ngx_string("upstream_status"), NULL, ngx_http_upstream_status_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, @@ -2509,6 +2514,77 @@ ngx_http_upstream_add_variables(ngx_conf static ngx_int_t +ngx_http_upstream_addr_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + size_t len; + ngx_uint_t i; + ngx_http_upstream_state_t *state; + + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + + if (r->upstream_states == NULL || r->upstream_states->nelts == 0) { + v->not_found = 1; + return NGX_OK; + } + + len = 0; + state = r->upstream_states->elts; + + for (i = 0; i < r->upstream_states->nelts; i++) { + if (state[i].peer) { + len += state[i].peer->len + 2; + + } else { + len += 3; + } + } + + p = ngx_palloc(r->pool, len); + if (p == NULL) { + return NGX_ERROR; + } + + v->data = p; + + i = 0; + + for ( ;; ) { + if (state[i].peer) { + p = ngx_cpymem(p, state[i].peer->data, state[i].peer->len); + } + + if (++i == r->upstream_states->nelts) { + break; + } + + if (state[i].peer) { + *p++ = ','; + *p++ = ' '; + + } else { + *p++ = ' '; + *p++ = ':'; + *p++ = ' '; + + if (++i == r->upstream_states->nelts) { + break; + } + + continue; + } + } + + v->len = p - v->data; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { 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 @@ -210,7 +210,7 @@ ngx_http_write_filter(ngx_http_request_t } if (r->limit_rate) { - to_send = r->limit_rate * (ngx_time() - r->start_time + 1) - c->sent; + to_send = r->limit_rate * (ngx_time() - r->start_sec + 1) - c->sent; if (to_send <= 0) { c->write->delayed = 1; 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 @@ -154,7 +154,7 @@ ngx_freebsd_sendfile_chain(ngx_connectio size = limit - send; aligned = (cl->buf->file_pos + size + ngx_pagesize - 1) - & ~(ngx_pagesize - 1); + & ~((off_t) ngx_pagesize - 1); if (aligned <= cl->buf->file_last) { size = aligned - cl->buf->file_pos; 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 @@ -223,7 +223,7 @@ ngx_linux_sendfile_chain(ngx_connection_ size = limit - send; aligned = (cl->buf->file_pos + size + ngx_pagesize - 1) - & ~(ngx_pagesize - 1); + & ~((off_t) ngx_pagesize - 1); if (aligned <= cl->buf->file_last) { size = aligned - cl->buf->file_pos; 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 @@ -135,7 +135,7 @@ ngx_solaris_sendfilev_chain(ngx_connecti size = limit - send; aligned = (cl->buf->file_pos + size + ngx_pagesize - 1) - & ~(ngx_pagesize - 1); + & ~((off_t) ngx_pagesize - 1); if (aligned <= cl->buf->file_last) { size = aligned - cl->buf->file_pos;