diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 7e08df702..20172e220 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -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 diff --git a/src/http/modules/ngx_http_proxy_module.h b/src/http/modules/ngx_http_proxy_module.h index a0f79bc13..4bf8406ad 100644 --- a/src/http/modules/ngx_http_proxy_module.h +++ b/src/http/modules/ngx_http_proxy_module.h @@ -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; diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 191bc73c7..8812a0fca 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -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;