Cache: update variant while setting header.

Some parts of code related to handling variants of a resource moved into
a separate function that is called earlier.  This allows to use cache file
name as a prefix for temporary file in the following patch.
This commit is contained in:
Valentin Bartenev 2014-12-26 16:22:56 +03:00
parent a54e37edda
commit 1858857c25
3 changed files with 62 additions and 37 deletions

View File

@ -162,7 +162,7 @@ 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);
ngx_int_t 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);
void ngx_http_file_cache_update_header(ngx_http_request_t *r);
ngx_int_t ngx_http_cache_send(ngx_http_request_t *);

View File

@ -37,6 +37,8 @@ static void ngx_http_file_cache_vary_header(ngx_http_request_t *r,
ngx_md5_t *md5, ngx_str_t *name);
static ngx_int_t ngx_http_file_cache_reopen(ngx_http_request_t *r,
ngx_http_cache_t *c);
static ngx_int_t ngx_http_file_cache_update_variant(ngx_http_request_t *r,
ngx_http_cache_t *c);
static void ngx_http_file_cache_cleanup(void *data);
static time_t ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache);
static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache);
@ -1122,7 +1124,7 @@ ngx_http_file_cache_reopen(ngx_http_request_t *r, ngx_http_cache_t *c)
}
void
ngx_int_t
ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
{
ngx_http_file_cache_header_t *h = (ngx_http_file_cache_header_t *) buf;
@ -1164,9 +1166,10 @@ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
ngx_http_file_cache_vary(r, c->vary.data, c->vary.len, c->variant);
ngx_memcpy(h->variant, c->variant, NGX_HTTP_CACHE_KEY_LEN);
}
} else {
ngx_memzero(c->variant, NGX_HTTP_CACHE_KEY_LEN);
if (ngx_http_file_cache_update_variant(r, c) != NGX_OK) {
return NGX_ERROR;
}
p = buf + sizeof(ngx_http_file_cache_header_t);
@ -1179,6 +1182,57 @@ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
}
*p = LF;
return NGX_OK;
}
static ngx_int_t
ngx_http_file_cache_update_variant(ngx_http_request_t *r, ngx_http_cache_t *c)
{
ngx_http_file_cache_t *cache;
if (!c->secondary) {
return NGX_OK;
}
if (c->vary.len
&& ngx_memcmp(c->variant, c->key, NGX_HTTP_CACHE_KEY_LEN) == 0)
{
return NGX_OK;
}
/*
* if the variant hash doesn't match one we used as a secondary
* cache key, switch back to the original key
*/
cache = c->file_cache;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http file cache main key");
ngx_shmtx_lock(&cache->shpool->mutex);
c->node->count--;
c->node->updating = 0;
c->node = NULL;
ngx_shmtx_unlock(&cache->shpool->mutex);
c->file.name.len = 0;
ngx_memcpy(c->key, c->main, NGX_HTTP_CACHE_KEY_LEN);
if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) {
return NGX_ERROR;
}
if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
return NGX_ERROR;
}
return NGX_OK;
}
@ -1204,38 +1258,6 @@ ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
cache = c->file_cache;
if (c->secondary
&& ngx_memcmp(c->variant, c->key, NGX_HTTP_CACHE_KEY_LEN) != 0)
{
/*
* if the variant hash doesn't match one we used as a secondary
* cache key, switch back to the original key
*/
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http file cache main key");
ngx_shmtx_lock(&cache->shpool->mutex);
c->node->count--;
c->node->updating = 0;
c->node = NULL;
ngx_shmtx_unlock(&cache->shpool->mutex);
c->file.name.len = 0;
ngx_memcpy(c->key, c->main, NGX_HTTP_CACHE_KEY_LEN);
if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) {
return;
}
if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
return;
}
}
c->updated = 1;
c->updating = 0;

View File

@ -2628,7 +2628,10 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
}
}
ngx_http_file_cache_set_header(r, u->buffer.start);
if (ngx_http_file_cache_set_header(r, u->buffer.start) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
return;
}
} else {
u->cacheable = 0;