Added support for QUERY cache via proxy_cache_query_key

This commit is contained in:
Mario Daniel Ruiz Saavedra 2026-06-26 13:38:14 -03:00
parent 30e9067038
commit f47cf370ff
3 changed files with 99 additions and 2 deletions

View file

@ -126,6 +126,8 @@ static char *ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_proxy_cache_query_key(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
#endif
#if (NGX_HTTP_SSL)
static char *ngx_http_proxy_ssl_certificate_cache(ngx_conf_t *cf,
@ -433,6 +435,13 @@ static ngx_command_t ngx_http_proxy_commands[] = {
0,
NULL },
{ ngx_string("proxy_cache_query_key"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_proxy_cache_query_key,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL },
{ ngx_string("proxy_cache_path"),
NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
ngx_http_file_cache_set_slot,
@ -1095,6 +1104,17 @@ ngx_http_proxy_create_key(ngx_http_request_t *r)
return NGX_ERROR;
}
if (r->method == NGX_HTTP_QUERY) {
if (plcf->cache_query_key.value.data) {
if (ngx_http_complex_value(r, &plcf->cache_query_key, key) != NGX_OK) {
return NGX_ERROR;
}
return NGX_OK;
}
}
if (plcf->cache_key.value.data) {
if (ngx_http_complex_value(r, &plcf->cache_key, key) != NGX_OK) {
@ -3862,6 +3882,25 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->cache_key = prev->cache_key;
}
if (conf->cache_query_key.value.data == NULL) {
conf->cache_query_key = prev->cache_query_key;
}
if (conf->cache_query_key.value.data == NULL) {
ngx_str_t s = ngx_string("$scheme$proxy_host$request_uri|$request_body");
ngx_http_compile_complex_value_t ccv;
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
ccv.cf = cf;
ccv.value = &s;
ccv.complex_value = &conf->cache_query_key;
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
ngx_conf_merge_value(conf->upstream.cache_lock,
prev->upstream.cache_lock, 0);
@ -5044,6 +5083,34 @@ ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
static char *
ngx_http_proxy_cache_query_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_proxy_loc_conf_t *plcf = conf;
ngx_str_t *value;
ngx_http_compile_complex_value_t ccv;
value = cf->args->elts;
if (plcf->cache_query_key.value.data) {
return "is duplicate";
}
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
ccv.cf = cf;
ccv.value = &value[1];
ccv.complex_value = &plcf->cache_query_key;
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
#endif

View file

@ -65,6 +65,7 @@ typedef struct {
#if (NGX_HTTP_CACHE)
ngx_http_complex_value_t cache_key;
ngx_http_complex_value_t cache_query_key;
#endif
ngx_http_proxy_vars_t vars;

View file

@ -2173,14 +2173,43 @@ ngx_http_variable_request_body(ngx_http_request_t *r,
ngx_chain_t *cl;
if (r->request_body == NULL
|| r->request_body->bufs == NULL
|| r->request_body->temp_file)
|| (r->request_body->bufs == NULL && r->request_body->temp_file == NULL))
{
v->not_found = 1;
return NGX_OK;
}
if (r->request_body->temp_file) {
ngx_file_t *file;
off_t size;
file = &r->request_body->temp_file->file;
size = file->offset;
if (size == 0) {
v->not_found = 1;
return NGX_OK;
}
p = ngx_pnalloc(r->pool, size);
if (p == NULL) {
return NGX_ERROR;
}
if (ngx_read_file(file, p, size, 0) == NGX_ERROR) {
return NGX_ERROR;
}
v->len = size;
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
v->data = p;
return NGX_OK;
}
cl = r->request_body->bufs;
buf = cl->buf;