diff --git a/boring-nginx/boring.patch b/boring-nginx/boring.patch index d77e8ef..29724a8 100644 --- a/boring-nginx/boring.patch +++ b/boring-nginx/boring.patch @@ -1,8 +1,8 @@ -diff -ur nginx-1.11.1/src/event/ngx_event_openssl.c nginx-1.11.1-patched/src/event/ngx_event_openssl.c ---- nginx-1.11.1/src/event/ngx_event_openssl.c 2016-06-01 07:32:19.447914116 +0200 -+++ nginx-1.11.1-patched/src/event/ngx_event_openssl.c 2016-06-01 07:34:11.267362975 +0200 -@@ -1994,13 +1994,17 @@ - +diff -Naur nginx-1.11.4/src/event/ngx_event_openssl.c nginx-1.11.4-patched/src/event/ngx_event_openssl.c +--- nginx-1.11.4/src/event/ngx_event_openssl.c 2016-09-16 00:49:53.176182112 +0200 ++++ nginx-1.11.4-patched/src/event/ngx_event_openssl.c 2016-09-16 00:47:27.636986453 +0200 +@@ -2016,7 +2016,9 @@ + /* handshake failures */ if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */ +#ifdef SSL_R_BLOCK_CIPHER_PAD_IS_WRONG @@ -11,21 +11,23 @@ diff -ur nginx-1.11.1/src/event/ngx_event_openssl.c nginx-1.11.1-patched/src/eve || n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */ || n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */ - || n == SSL_R_LENGTH_MISMATCH /* 159 */ +@@ -2024,7 +2026,9 @@ + #ifdef SSL_R_NO_CIPHERS_PASSED || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ + #endif +#ifdef SSL_R_NO_CIPHERS_SPECIFIED || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ +#endif || n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */ || n == SSL_R_NO_SHARED_CIPHER /* 193 */ || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */ -diff -ur nginx-1.11.1/src/http/ngx_http_upstream.c nginx-1.11.1-patched/src/http/ngx_http_upstream.c ---- nginx-1.11.1/src/http/ngx_http_upstream.c 2016-06-01 07:32:25.935882743 +0200 -+++ nginx-1.11.1-patched/src/http/ngx_http_upstream.c 2016-06-01 07:34:57.047131542 +0200 -@@ -1690,7 +1690,7 @@ +diff -Naur nginx-1.11.4/src/http/ngx_http_upstream.c nginx-1.11.4-patched/src/http/ngx_http_upstream.c +--- nginx-1.11.4/src/http/ngx_http_upstream.c 2016-09-16 00:50:04.068121614 +0200 ++++ nginx-1.11.4-patched/src/http/ngx_http_upstream.c 2016-09-16 00:47:50.916858344 +0200 +@@ -1694,7 +1694,7 @@ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "upstream SSL server name: \"%s\"", name.data); - + - if (SSL_set_tlsext_host_name(c->ssl->connection, name.data) == 0) { + if (SSL_set_tlsext_host_name(c->ssl->connection, (const char*) name.data) == 0) { ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, diff --git a/boring-nginx/patch-source/nginx-1.11.1/src/event/ngx_event_openssl.c b/boring-nginx/patch-source/nginx-1.11.4-patched/src/event/ngx_event_openssl.c similarity index 97% rename from boring-nginx/patch-source/nginx-1.11.1/src/event/ngx_event_openssl.c rename to boring-nginx/patch-source/nginx-1.11.4-patched/src/event/ngx_event_openssl.c index 810c469..fd827fc 100644 --- a/boring-nginx/patch-source/nginx-1.11.1/src/event/ngx_event_openssl.c +++ b/boring-nginx/patch-source/nginx-1.11.4-patched/src/event/ngx_event_openssl.c @@ -118,9 +118,7 @@ ngx_ssl_init(ngx_log_t *log) #else -#ifndef OPENSSL_IS_BORINGSSL OPENSSL_config(NULL); -#endif SSL_library_init(); SSL_load_error_strings(); @@ -591,6 +589,30 @@ ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata) } +ngx_int_t +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, + ngx_uint_t prefer_server_ciphers) +{ + if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_set_cipher_list(\"%V\") failed", + ciphers); + return NGX_ERROR; + } + + if (prefer_server_ciphers) { + SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + } + +#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(ssl->ctx, ngx_ssl_rsa512_key_callback); +#endif + + return NGX_OK; +} + + ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth) @@ -1994,13 +2016,19 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, /* handshake failures */ if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */ +#ifdef SSL_R_BLOCK_CIPHER_PAD_IS_WRONG || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */ +#endif || n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */ || n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */ || n == SSL_R_LENGTH_MISMATCH /* 159 */ +#ifdef SSL_R_NO_CIPHERS_PASSED || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ +#endif +#ifdef SSL_R_NO_CIPHERS_SPECIFIED || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ +#endif || n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */ || n == SSL_R_NO_SHARED_CIPHER /* 193 */ || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */ @@ -2917,13 +2945,6 @@ failed: } -#ifdef OPENSSL_NO_SHA256 -#define ngx_ssl_session_ticket_md EVP_sha1 -#else -#define ngx_ssl_session_ticket_md EVP_sha256 -#endif - - static int ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, @@ -2934,6 +2955,8 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, ngx_array_t *keys; ngx_connection_t *c; ngx_ssl_session_ticket_key_t *key; + const EVP_MD *digest; + const EVP_CIPHER *cipher; #if (NGX_DEBUG) u_char buf[32]; #endif @@ -2941,6 +2964,13 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, c = ngx_ssl_get_connection(ssl_conn); ssl_ctx = c->ssl->session_ctx; + cipher = EVP_aes_128_cbc(); +#ifdef OPENSSL_NO_SHA256 + digest = EVP_sha1(); +#else + digest = EVP_sha256(); +#endif + keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_ticket_keys_index); if (keys == NULL) { return -1; @@ -2956,13 +2986,29 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, ngx_hex_dump(buf, key[0].name, 16) - buf, buf, SSL_session_reused(ssl_conn) ? "reused" : "new"); - RAND_bytes(iv, 16); - EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key[0].aes_key, iv); - HMAC_Init_ex(hctx, key[0].hmac_key, 16, - ngx_ssl_session_ticket_md(), NULL); + if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "RAND_bytes() failed"); + return -1; + } + + if (EVP_EncryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, + "EVP_EncryptInit_ex() failed"); + return -1; + } + +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + if (HMAC_Init_ex(hctx, key[0].hmac_key, 16, digest, NULL) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); + return -1; + } +#else + HMAC_Init_ex(hctx, key[0].hmac_key, 16, digest, NULL); +#endif + ngx_memcpy(name, key[0].name, 16); - return 0; + return 1; } else { /* decrypt session ticket */ @@ -2986,9 +3032,20 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, ngx_hex_dump(buf, key[i].name, 16) - buf, buf, (i == 0) ? " (default)" : ""); - HMAC_Init_ex(hctx, key[i].hmac_key, 16, - ngx_ssl_session_ticket_md(), NULL); - EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key[i].aes_key, iv); +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + if (HMAC_Init_ex(hctx, key[i].hmac_key, 16, digest, NULL) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); + return -1; + } +#else + HMAC_Init_ex(hctx, key[i].hmac_key, 16, digest, NULL); +#endif + + if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, + "EVP_DecryptInit_ex() failed"); + return -1; + } return (i == 0) ? 1 : 2 /* renew */; } diff --git a/boring-nginx/patch-source/nginx-1.11.1-patched/src/http/ngx_http_upstream.c b/boring-nginx/patch-source/nginx-1.11.4-patched/src/http/ngx_http_upstream.c similarity index 99% rename from boring-nginx/patch-source/nginx-1.11.1-patched/src/http/ngx_http_upstream.c rename to boring-nginx/patch-source/nginx-1.11.4-patched/src/http/ngx_http_upstream.c index 863b44b..7310c1c 100644 --- a/boring-nginx/patch-source/nginx-1.11.1-patched/src/http/ngx_http_upstream.c +++ b/boring-nginx/patch-source/nginx-1.11.4-patched/src/http/ngx_http_upstream.c @@ -391,6 +391,10 @@ static ngx_http_variable_t ngx_http_upstream_vars[] = { ngx_http_upstream_response_length_variable, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("upstream_bytes_received"), NULL, + ngx_http_upstream_response_length_variable, 1, + NGX_HTTP_VAR_NOCACHEABLE, 0 }, + #if (NGX_HTTP_CACHE) { ngx_string("upstream_cache_status"), NULL, @@ -2136,6 +2140,8 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u) return; } + u->state->bytes_received += n; + u->buffer.last += n; #if 0 @@ -2642,6 +2648,7 @@ ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r, return; } + u->state->bytes_received += n; u->state->response_length += n; if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { @@ -3215,6 +3222,10 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, do_write = 1; b->last += n; + if (from_upstream) { + u->state->bytes_received += n; + } + continue; } @@ -3411,6 +3422,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, } if (n > 0) { + u->state->bytes_received += n; u->state->response_length += n; if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { @@ -4095,6 +4107,8 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r, u->state->response_time = ngx_current_msec - u->state->response_time; if (u->pipe && u->pipe->read_length) { + u->state->bytes_received += u->pipe->read_length + - u->pipe->preread_size; u->state->response_length = u->pipe->read_length; } } @@ -5242,7 +5256,13 @@ ngx_http_upstream_response_length_variable(ngx_http_request_t *r, state = r->upstream_states->elts; for ( ;; ) { - p = ngx_sprintf(p, "%O", state[i].response_length); + + if (data == 1) { + p = ngx_sprintf(p, "%O", state[i].bytes_received); + + } else { + p = ngx_sprintf(p, "%O", state[i].response_length); + } if (++i == r->upstream_states->nelts) { break; @@ -5828,7 +5848,8 @@ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } - rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); + rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data, + value[1].len); switch (rc) { case NGX_OK: @@ -5900,7 +5921,7 @@ ngx_http_upstream_set_local(ngx_http_request_t *r, ngx_http_upstream_t *u, return NGX_ERROR; } - rc = ngx_parse_addr(r->pool, addr, val.data, val.len); + rc = ngx_parse_addr_port(r->pool, addr, val.data, val.len); if (rc == NGX_ERROR) { return NGX_ERROR; } diff --git a/boring-nginx/patch-source/nginx-1.11.1-patched/src/event/ngx_event_openssl.c b/boring-nginx/patch-source/nginx-1.11.4/src/event/ngx_event_openssl.c similarity index 97% rename from boring-nginx/patch-source/nginx-1.11.1-patched/src/event/ngx_event_openssl.c rename to boring-nginx/patch-source/nginx-1.11.4/src/event/ngx_event_openssl.c index 6bab3f1..1cbfdf2 100644 --- a/boring-nginx/patch-source/nginx-1.11.1-patched/src/event/ngx_event_openssl.c +++ b/boring-nginx/patch-source/nginx-1.11.4/src/event/ngx_event_openssl.c @@ -118,9 +118,7 @@ ngx_ssl_init(ngx_log_t *log) #else -#ifndef OPENSSL_IS_BORINGSSL OPENSSL_config(NULL); -#endif SSL_library_init(); SSL_load_error_strings(); @@ -591,6 +589,30 @@ ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata) } +ngx_int_t +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, + ngx_uint_t prefer_server_ciphers) +{ + if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_set_cipher_list(\"%V\") failed", + ciphers); + return NGX_ERROR; + } + + if (prefer_server_ciphers) { + SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + } + +#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(ssl->ctx, ngx_ssl_rsa512_key_callback); +#endif + + return NGX_OK; +} + + ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth) @@ -1994,17 +2016,15 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, /* handshake failures */ if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */ -#ifdef SSL_R_BLOCK_CIPHER_PAD_IS_WRONG || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */ -#endif || n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */ || n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */ || n == SSL_R_LENGTH_MISMATCH /* 159 */ +#ifdef SSL_R_NO_CIPHERS_PASSED || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ -#ifdef SSL_R_NO_CIPHERS_SPECIFIED - || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ #endif + || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ || n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */ || n == SSL_R_NO_SHARED_CIPHER /* 193 */ || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */ @@ -2921,13 +2941,6 @@ failed: } -#ifdef OPENSSL_NO_SHA256 -#define ngx_ssl_session_ticket_md EVP_sha1 -#else -#define ngx_ssl_session_ticket_md EVP_sha256 -#endif - - static int ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, @@ -2938,6 +2951,8 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, ngx_array_t *keys; ngx_connection_t *c; ngx_ssl_session_ticket_key_t *key; + const EVP_MD *digest; + const EVP_CIPHER *cipher; #if (NGX_DEBUG) u_char buf[32]; #endif @@ -2945,6 +2960,13 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, c = ngx_ssl_get_connection(ssl_conn); ssl_ctx = c->ssl->session_ctx; + cipher = EVP_aes_128_cbc(); +#ifdef OPENSSL_NO_SHA256 + digest = EVP_sha1(); +#else + digest = EVP_sha256(); +#endif + keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_ticket_keys_index); if (keys == NULL) { return -1; @@ -2960,13 +2982,29 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, ngx_hex_dump(buf, key[0].name, 16) - buf, buf, SSL_session_reused(ssl_conn) ? "reused" : "new"); - RAND_bytes(iv, 16); - EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key[0].aes_key, iv); - HMAC_Init_ex(hctx, key[0].hmac_key, 16, - ngx_ssl_session_ticket_md(), NULL); + if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "RAND_bytes() failed"); + return -1; + } + + if (EVP_EncryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, + "EVP_EncryptInit_ex() failed"); + return -1; + } + +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + if (HMAC_Init_ex(hctx, key[0].hmac_key, 16, digest, NULL) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); + return -1; + } +#else + HMAC_Init_ex(hctx, key[0].hmac_key, 16, digest, NULL); +#endif + ngx_memcpy(name, key[0].name, 16); - return 0; + return 1; } else { /* decrypt session ticket */ @@ -2990,9 +3028,20 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, ngx_hex_dump(buf, key[i].name, 16) - buf, buf, (i == 0) ? " (default)" : ""); - HMAC_Init_ex(hctx, key[i].hmac_key, 16, - ngx_ssl_session_ticket_md(), NULL); - EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key[i].aes_key, iv); +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + if (HMAC_Init_ex(hctx, key[i].hmac_key, 16, digest, NULL) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed"); + return -1; + } +#else + HMAC_Init_ex(hctx, key[i].hmac_key, 16, digest, NULL); +#endif + + if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, + "EVP_DecryptInit_ex() failed"); + return -1; + } return (i == 0) ? 1 : 2 /* renew */; } diff --git a/boring-nginx/patch-source/nginx-1.11.1/src/http/ngx_http_upstream.c b/boring-nginx/patch-source/nginx-1.11.4/src/http/ngx_http_upstream.c similarity index 99% rename from boring-nginx/patch-source/nginx-1.11.1/src/http/ngx_http_upstream.c rename to boring-nginx/patch-source/nginx-1.11.4/src/http/ngx_http_upstream.c index 89b2160..7e4b3c5 100644 --- a/boring-nginx/patch-source/nginx-1.11.1/src/http/ngx_http_upstream.c +++ b/boring-nginx/patch-source/nginx-1.11.4/src/http/ngx_http_upstream.c @@ -391,6 +391,10 @@ static ngx_http_variable_t ngx_http_upstream_vars[] = { ngx_http_upstream_response_length_variable, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("upstream_bytes_received"), NULL, + ngx_http_upstream_response_length_variable, 1, + NGX_HTTP_VAR_NOCACHEABLE, 0 }, + #if (NGX_HTTP_CACHE) { ngx_string("upstream_cache_status"), NULL, @@ -2136,6 +2140,8 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u) return; } + u->state->bytes_received += n; + u->buffer.last += n; #if 0 @@ -2642,6 +2648,7 @@ ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r, return; } + u->state->bytes_received += n; u->state->response_length += n; if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { @@ -3215,6 +3222,10 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r, do_write = 1; b->last += n; + if (from_upstream) { + u->state->bytes_received += n; + } + continue; } @@ -3411,6 +3422,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, } if (n > 0) { + u->state->bytes_received += n; u->state->response_length += n; if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { @@ -4095,6 +4107,8 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r, u->state->response_time = ngx_current_msec - u->state->response_time; if (u->pipe && u->pipe->read_length) { + u->state->bytes_received += u->pipe->read_length + - u->pipe->preread_size; u->state->response_length = u->pipe->read_length; } } @@ -5242,7 +5256,13 @@ ngx_http_upstream_response_length_variable(ngx_http_request_t *r, state = r->upstream_states->elts; for ( ;; ) { - p = ngx_sprintf(p, "%O", state[i].response_length); + + if (data == 1) { + p = ngx_sprintf(p, "%O", state[i].bytes_received); + + } else { + p = ngx_sprintf(p, "%O", state[i].response_length); + } if (++i == r->upstream_states->nelts) { break; @@ -5828,7 +5848,8 @@ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } - rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); + rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data, + value[1].len); switch (rc) { case NGX_OK: @@ -5900,7 +5921,7 @@ ngx_http_upstream_set_local(ngx_http_request_t *r, ngx_http_upstream_t *u, return NGX_ERROR; } - rc = ngx_parse_addr(r->pool, addr, val.data, val.len); + rc = ngx_parse_addr_port(r->pool, addr, val.data, val.len); if (rc == NGX_ERROR) { return NGX_ERROR; }