From 7c8b7aecc31439f071cb1f8f3d9baa0afea7d18e Mon Sep 17 00:00:00 2001 From: Kirill A. Korinskiy Date: Tue, 21 Apr 2009 21:54:11 +0400 Subject: [PATCH] Implement $upstream_header_time Cc: catap@catap.ru --- src/http/ngx_http_upstream.c | 99 ++++++++++++++++++++++++++++++++++++++++++ src/http/ngx_http_upstream.h | 2 + 2 files changed, 101 insertions(+), 0 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 7ae15cb..4ddc285 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -118,6 +118,8 @@ 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, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_upstream_header_time_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_upstream_response_length_variable( ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); @@ -328,6 +330,10 @@ static ngx_http_variable_t ngx_http_upstream_vars[] = { ngx_http_upstream_response_time_variable, 0, NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("upstream_header_time"), NULL, + ngx_http_upstream_header_time_variable, 0, + NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("upstream_response_length"), NULL, ngx_http_upstream_response_length_variable, 0, NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE, 0 }, @@ -930,6 +936,11 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u) u->state->response_msec = tp->msec - u->state->response_msec; } + if (u->state && u->state->header_sec) { + u->state->header_sec = tp->sec - u->state->header_sec; + u->state->header_msec = tp->msec - u->state->header_msec; + } + u->state = ngx_array_push(r->upstream_states); if (u->state == NULL) { ngx_http_upstream_finalize_request(r, u, @@ -942,6 +953,8 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u) tp = ngx_timeofday(); u->state->response_sec = tp->sec; u->state->response_msec = tp->msec; + u->state->header_sec = tp->sec; + u->state->header_msec = tp->msec; rc = ngx_event_connect_peer(&u->peer); @@ -1843,10 +1856,17 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) int tcp_nodelay; ssize_t n; ngx_int_t rc; + ngx_time_t *tp; ngx_event_pipe_t *p; ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; + if (u->state && u->state->header_sec) { + tp = ngx_timeofday(); + u->state->header_sec = tp->sec - u->state->header_sec; + u->state->header_msec = tp->msec - u->state->header_msec; + } + rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->post_action) { @@ -2754,6 +2774,12 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r, } } + if (u->state && u->state->header_sec && !u->header_sent) { + tp = ngx_timeofday(); + u->state->header_sec = tp->sec - u->state->header_sec; + u->state->header_msec = tp->msec - u->state->header_msec; + } + u->finalize_request(r, rc); if (u->peer.free) { @@ -3602,6 +3628,79 @@ ngx_http_upstream_response_time_variable(ngx_http_request_t *r, static ngx_int_t +ngx_http_upstream_header_time_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + size_t len; + ngx_time_t *tp; + ngx_uint_t i; + ngx_msec_int_t ms; + ngx_http_upstream_state_t *state; + + tp = ngx_timeofday(); + + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + + if (r->upstream_states == NULL || r->upstream_states->nelts == 0) { + v->not_found = 1; + return NGX_OK; + } + + len = r->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2); + + p = ngx_pnalloc(r->pool, len); + if (p == NULL) { + return NGX_ERROR; + } + + v->data = p; + + i = 0; + state = r->upstream_states->elts; + + for ( ;; ) { + if (state[i].status) { + + ms = (ngx_msec_int_t) + (state[i].header_sec * 1000 + state[i].header_msec); + ms = (ms >= 0) ? ms : 0; + p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000); + + } else { + *p++ = '-'; + } + + 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_response_length_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index ad08195..241fe88 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -43,6 +43,8 @@ typedef struct { ngx_uint_t bl_state; ngx_uint_t status; + time_t header_sec; + ngx_uint_t header_msec; time_t response_sec; ngx_uint_t response_msec; off_t response_length; -- 1.6.2