Hi,
There is a problem with ngx_http_slice_module when it is used together
with an internal redirection to a named location. It results in Nginx
workers caching incorrect content and spinning in an infinite loop.
Consider the following fragment:
location /foo {
error_page 550 = @bar;
return 550;
}
location @bar {
slice ...;
proxy_pass ...;
proxy_cache ...;
...
}
In ngx_http_slice_body_filter(), the slice context is associated with
the subrequest:
ngx_http_set_ctx(sr, ctx, ngx_http_slice_filter_module);
However, the location re-match is triggered for the subrequests trying
to fetch each slice. In the ngx_http_named_location() function:
/* clear the modules contexts */
ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
So, the slice context gets lost. There are several ways to fix this.
Unless you want an API to preserve the context, one simple fix would be
to get the context via r->parent (if ctx == NULL && r != r->main).
What would be the preferred way to fix this?
Thanks.
--
Mindaugas
Hi,
This patch adds a build option to the server_tokens directive. When build is specified the Server header will have a value of NGINX_VER_BUILD. Also the tail of built in error pages will be NGINX_VER_BUILD. off and on are retained as valid values and behave as they always have.
This makes it possible to specify semi-custom server tokens of the form "nginx/<version> (<value>)". <value> is specified with the --build flag for ./configure.
A potential use case is including the name of a custom build for example with --build="super-nginx/0.1". This would give: nginx/1.9.15 (super-nginx/0.1).
Another potential use case of this feature is to include the git revision of a parent build with --build="`git rev-parse --short HEAD`". This would give: nginx/1.9.15 (c3ebabd). In that case the feature can be used to enhance troubleshooting and/or provide more information to end users.
Kind Regards,
Tom Thorogood.
Hello,
I am using nginx primarily as a proxy and I am looking to improve the
visibility and control over keepalive connections to upstreams.
I have several patches I would like to submit for your consideration
but I am relatively unfamiliar with the code base so I've started
simple and I appreciate your feedback. I must say the code base has
been very approachable to work with.
To begin I am adding support for an $upstream_connection variable for
use with the log_format directive. This is essentially the same as the
$connection variable but applies to upstream connections instead of
downstream.
The intent of this variable is to help understand which requests are
being serviced by the same upstream keepalive connection and which are
using different connections.
I think I have followed the Contributing Changes page at nginx.org.
I've honoured the existing code formatting and my `hg export` output
follows my signature. I have also executed the tests from the
nginx-tests repository in a Ubuntu Trusty environment but I did not
have many nginx modules included in my build.
Regards,
Jason
--
# HG changeset patch
# User Jason Stangroome <jason(a)codeassassin.com>
# Date 1472649436 0
# Wed Aug 31 13:17:16 2016 +0000
# Node ID f06c8a934e3f3ceac2ff393a391234e225cbfcf1
# Parent c6372a40c2a731d8816160bf8f55a7a50050c2ac
Added the $upstream_connection variable
Allows the connection identifier of the upstream connection used to service a
proxied request to be logged in the access.log to understand which requests
are using which upstream keepalive connections.
diff -r c6372a40c2a7 -r f06c8a934e3f src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c Fri Aug 26 15:33:07 2016 +0300
+++ b/src/http/ngx_http_upstream.c Wed Aug 31 13:17:16 2016 +0000
@@ -161,6 +161,9 @@
static ngx_int_t ngx_http_upstream_response_length_variable(
ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_upstream_connection_variable(
+ ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
+
static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd,
void *dummy);
static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -395,6 +398,10 @@
ngx_http_upstream_response_length_variable, 1,
NGX_HTTP_VAR_NOCACHEABLE, 0 },
+ { ngx_string("upstream_connection"), NULL,
+ ngx_http_upstream_connection_variable, 0,
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
#if (NGX_HTTP_CACHE)
{ ngx_string("upstream_cache_status"), NULL,
@@ -1804,6 +1811,7 @@
if (u->state->connect_time == (ngx_msec_t) -1) {
u->state->connect_time = ngx_current_msec - u->state->response_time;
+ u->state->connection_number = c->number;
}
if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
@@ -5291,6 +5299,67 @@
}
+static ngx_int_t
+ngx_http_upstream_connection_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_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_ATOMIC_T_LEN + 2);
+
+ p = ngx_pnalloc(r->pool, len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->data = p;
+
+ i = 0;
+ state = r->upstream_states->elts;
+
+ for ( ;; ) {
+
+ p = ngx_sprintf(p, "%uA", state[i].connection_number);
+
+ 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;
+}
+
+
ngx_int_t
ngx_http_upstream_header_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
diff -r c6372a40c2a7 -r f06c8a934e3f src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h Fri Aug 26 15:33:07 2016 +0300
+++ b/src/http/ngx_http_upstream.h Wed Aug 31 13:17:16 2016 +0000
@@ -66,6 +66,8 @@
off_t bytes_received;
ngx_str_t *peer;
+
+ ngx_atomic_uint_t connection_number;
} ngx_http_upstream_state_t;
Hi, guys
I found a coredump file generated on production.
(gdb) print ngx_http_abc_module
$7 = {ctx_index = 18446744073709551615, index = 18446744073709551615, name
= 0x0, spare0 = 0, spare1 = 0, version = 1010001, signature = 0x3520
<Address 0x3520 out of bounds>,
ctx = 0x204800, commands = 0x204840, type = 1347703880, init_master = 0,
init_module = 0, init_process = 0, init_thread = 0, exit_thread = 0,
exit_process = 0,
exit_master = 0, spare_hook0 = 0, spare_hook1 = 0, spare_hook2 = 0,
spare_hook3 = 0, spare_hook4 = 0, spare_hook5 = 0, spare_hook6 = 0,
spare_hook7 = 0}
The ngx_http_'abc'_module is a simple module written by ourself.
It runed well in the past time, and I just changed the following structure
defined in the module.
typedef struct {
ngx_flag_t valid;
...
ngx_uint_t member1; # added
ngx_uint_t member2; # added
...
} ngx_http_abc_ctx_t;
nginx.conf
load_module modules/....;
load_module modules/ngx_http_abc_module_3.so; # This module is in the
last postion, the other modules seems right.
And there is tiny detail. I generate so file named
'ngx_http_abc_module.so', then I copy as ngx_http_abc_module_3.so
And here are short codes about this module.
static ngx_int_t
ngx_http_abc_handler(ngx_http_request_t *r)
{
...
ngx_http_abc_ctx_t *ctx;
ngx_http_abc_loc_conf_t *vlcf;
vlcf = ngx_http_get_module_loc_conf(r, ngx_http_abc_module);
if (vlcf->enable == 0) {
return NGX_DECLINED;
}
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_abc_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
}
ngx_http_set_ctx(r, ctx, ngx_http_abc_module);
…
}
config
ngx_addon_name="ngx_http_abc_module"
ngx_module_type=HTTP
ngx_module_name=ngx_http_abc_module
ngx_module_incs="$ngx_addon_dir"
ngx_module_srcs="$ngx_addon_dir/ngx_http_abc_module.c"
. auto/module
It's sad that I can't regenerate coredump file now.
By the way, It's so convinient that use dso instead of upgrading static
module.
Thanks so much.
B.R.