changeset 298:30862655219e NGINX_0_5_19

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.
author Igor Sysoev <http://sysoev.ru>
date Tue, 24 Apr 2007 00:00:00 +0400
parents df0fd0d43ed8
children 7d0d14dc5fd7
files CHANGES CHANGES.ru src/core/nginx.h src/http/modules/ngx_http_log_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/perl/nginx.pm src/http/modules/perl/nginx.xs src/http/ngx_http_core_module.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_upstream.c src/http/ngx_http_write_filter_module.c src/os/unix/ngx_freebsd_sendfile_chain.c src/os/unix/ngx_linux_sendfile_chain.c src/os/unix/ngx_solaris_sendfilev_chain.c
diffstat 15 files changed, 182 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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.
--- 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"
--- 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);
 }
 
 
--- 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;
 
--- 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__
 
--- 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);
 
--- 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);
--- 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;
 
--- 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;
--- 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)
 {
--- 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;
--- 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;
--- 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;
--- 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;