nginx-0.8.53 segfault
Maxim Dounin
mdounin at mdounin.ru
Thu Jan 20 02:24:08 MSK 2011
Hello!
On Fri, Jan 14, 2011 at 09:55:35PM +0300, Maxim Dounin wrote:
> Hello!
>
> On Fri, Jan 14, 2011 at 06:15:50PM +0100, Maxim C. wrote:
>
> > Maxim, thanks for your help. I saved fresh core :) to anothe directory
> > and ran gdb, output of the commands that you provided is:
> >
> > (gdb) fr 0
> > #0 0x080aaca8 in ngx_http_file_cache_update (r=0x8200528, tf=0x8201570)
> > at src/http/ngx_http_file_cache.c:790
> > 790 if (c->updated) {
> > (gdb) p c
> > $1 = (ngx_http_cache_t *) 0x0
> > (gdb) p *r
> > $2 = {signature = 1347703880, connection = 0x8133e88, ctx = 0x82009d8,
>
> [...]
>
> > http_version = 1001, request_line = {len = 30, data = 0x81fbfa8 "GET
> > /preview/x045.jpg HTTP/1.1\r\nHost"}, uri = {len = 6, data = 0x8113d6c
> > "/empty"},
>
> [...]
>
> > filter_finalize = 1, post_action = 0, request_complete = 0,
>
> Ah, understood, it's image filter which triggers the problem. I'm
> able to reproduce the problem here with the following config:
>
> server {
> listen 127.0.0.1:8080;
>
> location / {
> proxy_pass http://127.0.0.1:8080/bad/;
> proxy_cache one;
> proxy_cache_valid any 1h;
>
> image_filter resize 150 100;
> error_page 415 = /empty;
> }
>
> location /empty {
> return 204;
> }
>
> location /bad/ {
> return 404;
> }
> }
>
> Right now I think correct solution would be to move r->cache into
> upstream's private data (r->upstream). Igor?
The attached patch moves r->cache into r->upstream (and resolves
the SIGSEGV in question).
To Igor:
The patch is rather big and touches lots of code. I would like to
get some explicit response on it to avoid unneeded merge work.
Maxim Dounin
-------------- next part --------------
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1295478387 -10800
# Node ID 16ed85edee18140cdf2c199d723daf4cba0815fd
# Parent 861939dcbd212e535cbee15c574a76bd7a72917a
Move r->cache to r->upstream to avoid conflicts.
1. Get rid of r->cache/r->cached dependencies in range filter, use correct
offset calculations instead.
2. Change cache interfaces to accept cache object instead of unconditionally
using r->cache one.
3. Move r->cache to r->upstream (mostly mechanical change of r->cache and
r->cached to u->cache/cached or r->upstream->cache/cached as appropriate).
This allows upstream to assume cache isn't changed out of it's control (in
particular, invariant "u->cache != NULL if u->cacheable set" is preserved).
This should also simplify cache usage in other modules and allow multiple
caches to be used in parallel (e.g. one cache in upstream, another one in
some filter module).
This resolves problem with image_filter and proxy_cache, see here:
http://nginx.org/pipermail/nginx/2011-January/024703.html
Note that some problems may still be here in case of request finalization by
filter as upstream module with cache/store ignores downstream errors and
tries to continue work assuming r->upstream is still here. This results
in undefined behaviour if another upstream request is issued during filter
finalization.
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -672,7 +672,7 @@ ngx_http_fastcgi_create_key(ngx_http_req
ngx_str_t *key;
ngx_http_fastcgi_loc_conf_t *flcf;
- key = ngx_array_push(&r->cache->keys);
+ key = ngx_array_push(&r->upstream->cache->keys);
if (key == NULL) {
return NGX_ERROR;
}
@@ -1274,9 +1274,9 @@ ngx_http_fastcgi_process_header(ngx_http
*/
#if (NGX_HTTP_CACHE)
- if (r->cache) {
+ if (u->cache) {
u->buffer.pos = u->buffer.start
- + r->cache->header_start;
+ + u->cache->header_start;
} else {
u->buffer.pos = u->buffer.start;
}
@@ -1303,12 +1303,12 @@ ngx_http_fastcgi_process_header(ngx_http
#if (NGX_HTTP_CACHE)
- if (f->large_stderr && r->cache) {
+ if (f->large_stderr && u->cache) {
u_char *start;
ssize_t len;
ngx_http_fastcgi_header_t *fh;
- start = u->buffer.start + r->cache->header_start;
+ start = u->buffer.start + u->cache->header_start;
len = u->buffer.pos - start - 2 * sizeof(ngx_http_fastcgi_header_t);
@@ -1316,7 +1316,7 @@ ngx_http_fastcgi_process_header(ngx_http
* A tail of large stderr output before HTTP header is placed
* in a cache file without a FastCGI record header.
* To workaround it we put a dummy FastCGI record header at the
- * start of the stderr output or update r->cache_header_start,
+ * start of the stderr output or update u->cache_header_start,
* if there is no enough place for the record header.
*/
@@ -1332,7 +1332,7 @@ ngx_http_fastcgi_process_header(ngx_http
fh->reserved = 0;
} else {
- r->cache->header_start += u->buffer.pos - start
+ u->cache->header_start += u->buffer.pos - start
- sizeof(ngx_http_fastcgi_header_t);
}
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
@@ -747,7 +747,7 @@ ngx_http_proxy_create_key(ngx_http_reque
ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
- key = ngx_array_push(&r->cache->keys);
+ key = ngx_array_push(&u->cache->keys);
if (key == NULL) {
return NGX_ERROR;
}
@@ -763,7 +763,7 @@ ngx_http_proxy_create_key(ngx_http_reque
*key = ctx->vars.key_start;
- key = ngx_array_push(&r->cache->keys);
+ key = ngx_array_push(&u->cache->keys);
if (key == NULL) {
return NGX_ERROR;
}
@@ -1191,7 +1191,7 @@ ngx_http_proxy_process_status_line(ngx_h
#if (NGX_HTTP_CACHE)
- if (r->cache) {
+ if (u->cache) {
r->http_version = NGX_HTTP_VERSION_9;
return NGX_OK;
}
diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c
--- a/src/http/modules/ngx_http_range_filter_module.c
+++ b/src/http/modules/ngx_http_range_filter_module.c
@@ -587,15 +587,8 @@ ngx_http_range_test_overlapped(ngx_http_
buf = in->buf;
if (!buf->last_buf) {
-
- if (buf->in_file) {
- start = buf->file_pos + ctx->offset;
- last = buf->file_last + ctx->offset;
-
- } else {
- start = buf->pos - buf->start + ctx->offset;
- last = buf->last - buf->start + ctx->offset;
- }
+ start = ctx->offset;
+ last = ctx->offset + ngx_buf_size(buf);
range = ctx->ranges.elts;
for (i = 0; i < ctx->ranges.nelts; i++) {
@@ -708,7 +701,6 @@ static ngx_int_t
ngx_http_range_multipart_body(ngx_http_request_t *r,
ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in)
{
- off_t body_start;
ngx_buf_t *b, *buf;
ngx_uint_t i;
ngx_chain_t *out, *hcl, *rcl, *dcl, **ll;
@@ -718,12 +710,6 @@ ngx_http_range_multipart_body(ngx_http_r
buf = in->buf;
range = ctx->ranges.elts;
-#if (NGX_HTTP_CACHE)
- body_start = r->cached ? r->cache->body_start : 0;
-#else
- body_start = 0;
-#endif
-
for (i = 0; i < ctx->ranges.nelts; i++) {
/*
@@ -784,13 +770,13 @@ ngx_http_range_multipart_body(ngx_http_r
b->file = buf->file;
if (buf->in_file) {
- b->file_pos = body_start + range[i].start;
- b->file_last = body_start + range[i].end;
+ b->file_pos = buf->file_pos + range[i].start;
+ b->file_last = buf->file_pos + range[i].end;
}
if (ngx_buf_in_memory(buf)) {
- b->pos = buf->start + (size_t) range[i].start;
- b->last = buf->start + (size_t) range[i].end;
+ b->pos = buf->pos + (size_t) range[i].start;
+ b->last = buf->pos + (size_t) range[i].end;
}
dcl = ngx_alloc_chain_link(r->pool);
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -494,7 +494,7 @@ ngx_http_scgi_create_key(ngx_http_reques
ngx_str_t *key;
ngx_http_scgi_loc_conf_t *scf;
- key = ngx_array_push(&r->cache->keys);
+ key = ngx_array_push(&r->upstream->cache->keys);
if (key == NULL) {
return NGX_ERROR;
}
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -527,7 +527,7 @@ ngx_http_uwsgi_create_key(ngx_http_reque
ngx_str_t *key;
ngx_http_uwsgi_loc_conf_t *uwcf;
- key = ngx_array_push(&r->cache->keys);
+ key = ngx_array_push(&r->upstream->cache->keys);
if (key == NULL) {
return NGX_ERROR;
}
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -124,13 +124,16 @@ struct ngx_http_file_cache_s {
};
-ngx_int_t ngx_http_file_cache_new(ngx_http_request_t *r);
-ngx_int_t ngx_http_file_cache_create(ngx_http_request_t *r);
-void ngx_http_file_cache_create_key(ngx_http_request_t *r);
-ngx_int_t ngx_http_file_cache_open(ngx_http_request_t *r);
-void ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf);
-void ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf);
-ngx_int_t ngx_http_cache_send(ngx_http_request_t *);
+ngx_http_cache_t *ngx_http_file_cache_new(ngx_http_request_t *r);
+ngx_int_t ngx_http_file_cache_create(ngx_http_request_t *r,
+ ngx_http_cache_t *c);
+void ngx_http_file_cache_create_key(ngx_http_request_t *r, ngx_http_cache_t *c);
+ngx_int_t ngx_http_file_cache_open(ngx_http_request_t *r, ngx_http_cache_t *c);
+void ngx_http_file_cache_set_header(ngx_http_request_t *r, ngx_http_cache_t *c,
+ u_char *buf);
+void ngx_http_file_cache_update(ngx_http_request_t *r, ngx_http_cache_t *c,
+ ngx_temp_file_t *tf);
+ngx_int_t ngx_http_cache_send(ngx_http_request_t *r, ngx_http_cache_t *c);
void ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf);
time_t ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status);
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
@@ -2339,10 +2339,6 @@ ngx_http_internal_redirect(ngx_http_requ
ngx_http_update_location_config(r);
-#if (NGX_HTTP_CACHE)
- r->cache = NULL;
-#endif
-
r->internal = 1;
r->add_uri_to_alias = 0;
r->main->count++;
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -20,7 +20,7 @@ static void ngx_http_cache_aio_event_han
static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache,
ngx_http_cache_t *c);
static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r,
- ngx_path_t *path);
+ ngx_http_cache_t *c, ngx_path_t *path);
static ngx_http_file_cache_node_t *
ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key);
static void ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
@@ -145,38 +145,35 @@ ngx_http_file_cache_init(ngx_shm_zone_t
}
-ngx_int_t
+ngx_http_cache_t *
ngx_http_file_cache_new(ngx_http_request_t *r)
{
ngx_http_cache_t *c;
c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t));
if (c == NULL) {
- return NGX_ERROR;
+ return NULL;
}
if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) {
- return NGX_ERROR;
+ return NULL;
}
- r->cache = c;
c->file.log = r->connection->log;
c->file.fd = NGX_INVALID_FILE;
- return NGX_OK;
+ return c;
}
ngx_int_t
-ngx_http_file_cache_create(ngx_http_request_t *r)
+ngx_http_file_cache_create(ngx_http_request_t *r, ngx_http_cache_t *c)
{
- ngx_http_cache_t *c;
ngx_pool_cleanup_t *cln;
ngx_http_file_cache_t *cache;
- ngx_http_file_cache_create_key(r);
+ ngx_http_file_cache_create_key(r, c);
- c = r->cache;
cache = c->file_cache;
cln = ngx_pool_cleanup_add(r->pool, 0);
@@ -191,7 +188,7 @@ ngx_http_file_cache_create(ngx_http_requ
cln->handler = ngx_http_file_cache_cleanup;
cln->data = c;
- if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
+ if (ngx_http_file_cache_name(r, c, cache->path) != NGX_OK) {
return NGX_ERROR;
}
@@ -200,15 +197,12 @@ ngx_http_file_cache_create(ngx_http_requ
void
-ngx_http_file_cache_create_key(ngx_http_request_t *r)
+ngx_http_file_cache_create_key(ngx_http_request_t *r, ngx_http_cache_t *c)
{
size_t len;
ngx_str_t *key;
ngx_uint_t i;
ngx_md5_t md5;
- ngx_http_cache_t *c;
-
- c = r->cache;
len = 0;
@@ -235,18 +229,15 @@ ngx_http_file_cache_create_key(ngx_http_
ngx_int_t
-ngx_http_file_cache_open(ngx_http_request_t *r)
+ngx_http_file_cache_open(ngx_http_request_t *r, ngx_http_cache_t *c)
{
ngx_int_t rc, rv;
ngx_uint_t cold, test;
- ngx_http_cache_t *c;
ngx_pool_cleanup_t *cln;
ngx_open_file_info_t of;
ngx_http_file_cache_t *cache;
ngx_http_core_loc_conf_t *clcf;
- c = r->cache;
-
if (c->buf) {
return ngx_http_file_cache_read(r, c);
}
@@ -304,7 +295,7 @@ ngx_http_file_cache_open(ngx_http_reques
}
}
- if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
+ if (ngx_http_file_cache_name(r, c, cache->path) != NGX_OK) {
return NGX_ERROR;
}
@@ -397,8 +388,6 @@ ngx_http_file_cache_read(ngx_http_reques
c->header_start = h->header_start;
c->body_start = h->body_start;
- r->cached = 1;
-
cache = c->file_cache;
if (cache->sh->cold) {
@@ -615,12 +604,10 @@ failed:
static ngx_int_t
-ngx_http_file_cache_name(ngx_http_request_t *r, ngx_path_t *path)
+ngx_http_file_cache_name(ngx_http_request_t *r, ngx_http_cache_t *c,
+ ngx_path_t *path)
{
u_char *p;
- ngx_http_cache_t *c;
-
- c = r->cache;
c->file.name.len = path->name.len + 1 + path->len
+ 2 * NGX_HTTP_CACHE_KEY_LEN;
@@ -739,20 +726,18 @@ ngx_http_file_cache_rbtree_insert_value(
void
-ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
+ngx_http_file_cache_set_header(ngx_http_request_t *r, ngx_http_cache_t *c,
+ u_char *buf)
{
ngx_http_file_cache_header_t *h = (ngx_http_file_cache_header_t *) buf;
u_char *p;
ngx_str_t *key;
ngx_uint_t i;
- ngx_http_cache_t *c;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http file cache set header");
- c = r->cache;
-
h->valid_sec = c->valid_sec;
h->last_modified = c->last_modified;
h->date = c->date;
@@ -775,18 +760,16 @@ ngx_http_file_cache_set_header(ngx_http_
void
-ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
+ngx_http_file_cache_update(ngx_http_request_t *r, ngx_http_cache_t *c,
+ ngx_temp_file_t *tf)
{
off_t size, length;
ngx_int_t rc;
ngx_file_uniq_t uniq;
ngx_file_info_t fi;
- ngx_http_cache_t *c;
ngx_ext_rename_file_t ext;
ngx_http_file_cache_t *cache;
- c = r->cache;
-
if (c->updated) {
return;
}
@@ -854,14 +837,11 @@ ngx_http_file_cache_update(ngx_http_requ
ngx_int_t
-ngx_http_cache_send(ngx_http_request_t *r)
+ngx_http_cache_send(ngx_http_request_t *r, ngx_http_cache_t *c)
{
ngx_int_t rc;
ngx_buf_t *b;
ngx_chain_t out;
- ngx_http_cache_t *c;
-
- c = r->cache;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http file cache send: %s", c->file.name.data);
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
@@ -354,10 +354,6 @@ struct ngx_http_request_s {
ngx_http_event_handler_pt read_event_handler;
ngx_http_event_handler_pt write_event_handler;
-#if (NGX_HTTP_CACHE)
- ngx_http_cache_t *cache;
-#endif
-
ngx_http_upstream_t *upstream;
ngx_array_t *upstream_states;
/* of ngx_http_upstream_state_t */
@@ -460,10 +456,6 @@ struct ngx_http_request_s {
unsigned subrequest_in_memory:1;
unsigned waited:1;
-#if (NGX_HTTP_CACHE)
- unsigned cached:1;
-#endif
-
#if (NGX_HTTP_GZIP)
unsigned gzip_tested:1;
unsigned gzip_ok:1;
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
@@ -392,10 +392,6 @@ ngx_http_upstream_create(ngx_http_reques
u->peer.lock = &r->connection->lock;
#endif
-#if (NGX_HTTP_CACHE)
- r->cache = NULL;
-#endif
-
return NGX_OK;
}
@@ -629,7 +625,7 @@ ngx_http_upstream_cache(ngx_http_request
ngx_int_t rc;
ngx_http_cache_t *c;
- c = r->cache;
+ c = u->cache;
if (c == NULL) {
@@ -654,22 +650,23 @@ ngx_http_upstream_cache(ngx_http_request
u->method = ngx_http_core_get_method;
}
- if (ngx_http_file_cache_new(r) != NGX_OK) {
+ u->cache = ngx_http_file_cache_new(r);
+ if (u->cache == NULL) {
return NGX_ERROR;
}
+ c = u->cache;
+
if (u->create_key(r) != NGX_OK) {
return NGX_ERROR;
}
/* TODO: add keys */
- ngx_http_file_cache_create_key(r);
+ ngx_http_file_cache_create_key(r, c);
u->cacheable = 1;
- c = r->cache;
-
c->min_uses = u->conf->cache_min_uses;
c->body_start = u->conf->buffer_size;
c->file_cache = u->conf->cache->data;
@@ -677,7 +674,7 @@ ngx_http_upstream_cache(ngx_http_request
u->cache_status = NGX_HTTP_CACHE_MISS;
}
- rc = ngx_http_file_cache_open(r);
+ rc = ngx_http_file_cache_open(r, c);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http upstream cache: %i", rc);
@@ -755,7 +752,7 @@ ngx_http_upstream_cache(ngx_http_request
return rc;
}
- r->cached = 0;
+ u->cached = 0;
return NGX_DECLINED;
}
@@ -767,12 +764,12 @@ ngx_http_upstream_cache_send(ngx_http_re
ngx_int_t rc;
ngx_http_cache_t *c;
- r->cached = 1;
- c = r->cache;
+ u->cached = 1;
+ c = u->cache;
if (c->header_start == c->body_start) {
r->http_version = NGX_HTTP_VERSION_9;
- return ngx_http_cache_send(r);
+ return ngx_http_cache_send(r, c);
}
/* TODO: cache stack */
@@ -797,7 +794,7 @@ ngx_http_upstream_cache_send(ngx_http_re
return NGX_DONE;
}
- return ngx_http_cache_send(r);
+ return ngx_http_cache_send(r, c);
}
if (rc == NGX_ERROR) {
@@ -1306,8 +1303,8 @@ ngx_http_upstream_reinit(ngx_http_reques
#if (NGX_HTTP_CACHE)
- if (r->cache) {
- u->buffer.pos += r->cache->header_start;
+ if (u->cache) {
+ u->buffer.pos += u->cache->header_start;
}
#endif
@@ -1491,8 +1488,8 @@ ngx_http_upstream_process_header(ngx_htt
#if (NGX_HTTP_CACHE)
- if (r->cache) {
- u->buffer.pos += r->cache->header_start;
+ if (u->cache) {
+ u->buffer.pos += u->cache->header_start;
u->buffer.last = u->buffer.pos;
}
#endif
@@ -1722,17 +1719,17 @@ ngx_http_upstream_intercept_errors(ngx_h
#if (NGX_HTTP_CACHE)
- if (r->cache) {
+ if (u->cache) {
time_t valid;
valid = ngx_http_file_cache_valid(u->conf->cache_valid, status);
if (valid) {
- r->cache->valid_sec = ngx_time() + valid;
- r->cache->error = status;
+ u->cache->valid_sec = ngx_time() + valid;
+ u->cache->error = status;
}
- ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
+ ngx_http_file_cache_free(u->cache, u->pipe->temp_file);
}
#endif
ngx_http_upstream_finalize_request(r, u, status);
@@ -2108,9 +2105,9 @@ ngx_http_upstream_send_response(ngx_http
#if (NGX_HTTP_CACHE)
- if (r->cache && r->cache->file.fd != NGX_INVALID_FILE) {
- ngx_pool_run_cleanup_file(r->pool, r->cache->file.fd);
- r->cache->file.fd = NGX_INVALID_FILE;
+ if (u->cache && u->cache->file.fd != NGX_INVALID_FILE) {
+ ngx_pool_run_cleanup_file(r->pool, u->cache->file.fd);
+ u->cache->file.fd = NGX_INVALID_FILE;
}
switch (ngx_http_test_predicates(r, u->conf->no_cache)) {
@@ -2127,7 +2124,8 @@ ngx_http_upstream_send_response(ngx_http
if (u->cache_status == NGX_HTTP_CACHE_BYPASS) {
- if (ngx_http_file_cache_new(r) != NGX_OK) {
+ u->cache = ngx_http_file_cache_new(r);
+ if (u->cache == NULL) {
ngx_http_upstream_finalize_request(r, u, 0);
return;
}
@@ -2139,11 +2137,11 @@ ngx_http_upstream_send_response(ngx_http
/* TODO: add keys */
- r->cache->min_uses = u->conf->cache_min_uses;
- r->cache->body_start = u->conf->buffer_size;
- r->cache->file_cache = u->conf->cache->data;
-
- if (ngx_http_file_cache_create(r) != NGX_OK) {
+ u->cache->min_uses = u->conf->cache_min_uses;
+ u->cache->body_start = u->conf->buffer_size;
+ u->cache->file_cache = u->conf->cache->data;
+
+ if (ngx_http_file_cache_create(r, u->cache) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u, 0);
return;
}
@@ -2159,22 +2157,22 @@ ngx_http_upstream_send_response(ngx_http
now = ngx_time();
- valid = r->cache->valid_sec;
+ valid = u->cache->valid_sec;
if (valid == 0) {
valid = ngx_http_file_cache_valid(u->conf->cache_valid,
u->headers_in.status_n);
if (valid) {
- r->cache->valid_sec = now + valid;
+ u->cache->valid_sec = now + valid;
}
}
if (valid) {
- r->cache->last_modified = r->headers_out.last_modified_time;
- r->cache->date = now;
- r->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start);
-
- ngx_http_file_cache_set_header(r, u->buffer.start);
+ u->cache->last_modified = r->headers_out.last_modified_time;
+ u->cache->date = now;
+ u->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start);
+
+ ngx_http_file_cache_set_header(r, u->cache, u->buffer.start);
} else {
u->cacheable = 0;
@@ -2185,8 +2183,8 @@ ngx_http_upstream_send_response(ngx_http
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http cacheable: %d", u->cacheable);
- if (u->cacheable == 0 && r->cache) {
- ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
+ if (u->cacheable == 0 && u->cache) {
+ ngx_http_file_cache_free(u->cache, u->pipe->temp_file);
}
#endif
@@ -2652,16 +2650,16 @@ ngx_http_upstream_process_request(ngx_ht
if (u->cacheable) {
if (p->upstream_done) {
- ngx_http_file_cache_update(r, u->pipe->temp_file);
+ ngx_http_file_cache_update(r, u->cache, u->pipe->temp_file);
} else if (p->upstream_eof) {
/* TODO: check length & update cache */
- ngx_http_file_cache_update(r, u->pipe->temp_file);
+ ngx_http_file_cache_update(r, u->cache, u->pipe->temp_file);
} else if (p->upstream_error) {
- ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
+ ngx_http_file_cache_free(u->cache, u->pipe->temp_file);
}
}
@@ -2986,7 +2984,7 @@ ngx_http_upstream_finalize_request(ngx_h
#if (NGX_HTTP_CACHE)
- if (u->cacheable && r->cache) {
+ if (u->cacheable) {
time_t valid;
if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) {
@@ -2994,12 +2992,12 @@ ngx_http_upstream_finalize_request(ngx_h
valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc);
if (valid) {
- r->cache->valid_sec = ngx_time() + valid;
- r->cache->error = rc;
+ u->cache->valid_sec = ngx_time() + valid;
+ u->cache->error = rc;
}
}
- ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
+ ngx_http_file_cache_free(u->cache, u->pipe->temp_file);
}
#endif
@@ -3100,11 +3098,11 @@ ngx_http_upstream_process_cache_control(
return NGX_OK;
}
- if (r->cache == NULL) {
+ if (u->cache == NULL) {
return NGX_OK;
}
- if (r->cache->valid_sec != 0) {
+ if (u->cache->valid_sec != 0) {
return NGX_OK;
}
@@ -3146,7 +3144,7 @@ ngx_http_upstream_process_cache_control(
return NGX_OK;
}
- r->cache->valid_sec = ngx_time() + n;
+ u->cache->valid_sec = ngx_time() + n;
}
#endif
@@ -3171,11 +3169,11 @@ ngx_http_upstream_process_expires(ngx_ht
return NGX_OK;
}
- if (r->cache == NULL) {
+ if (u->cache == NULL) {
return NGX_OK;
}
- if (r->cache->valid_sec != 0) {
+ if (u->cache->valid_sec != 0) {
return NGX_OK;
}
@@ -3186,7 +3184,7 @@ ngx_http_upstream_process_expires(ngx_ht
return NGX_OK;
}
- r->cache->valid_sec = expires;
+ u->cache->valid_sec = expires;
}
#endif
@@ -3213,7 +3211,7 @@ ngx_http_upstream_process_accel_expires(
return NGX_OK;
}
- if (r->cache == NULL) {
+ if (u->cache == NULL) {
return NGX_OK;
}
@@ -3230,7 +3228,7 @@ ngx_http_upstream_process_accel_expires(
return NGX_OK;
default:
- r->cache->valid_sec = ngx_time() + n;
+ u->cache->valid_sec = ngx_time() + n;
return NGX_OK;
}
}
@@ -3241,7 +3239,7 @@ ngx_http_upstream_process_accel_expires(
n = ngx_atoi(p, len);
if (n != NGX_ERROR) {
- r->cache->valid_sec = n;
+ u->cache->valid_sec = n;
}
}
#endif
@@ -3562,10 +3560,9 @@ ngx_http_upstream_copy_allow_ranges(ngx_
#if (NGX_HTTP_CACHE)
- if (r->cached) {
+ if (r->upstream->cached) {
r->allow_ranges = 1;
return NGX_OK;
-
}
#endif
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -265,6 +265,10 @@ struct ngx_http_upstream_s {
ngx_http_upstream_resolved_t *resolved;
+#if (NGX_HTTP_CACHE)
+ ngx_http_cache_t *cache;
+#endif
+
ngx_buf_t buffer;
size_t length;
@@ -303,6 +307,7 @@ struct ngx_http_upstream_s {
unsigned accel:1;
unsigned ssl:1;
#if (NGX_HTTP_CACHE)
+ unsigned cached:1;
unsigned cache_status:3;
#endif
More information about the nginx
mailing list