MINOR: cache: Add a process-vary option that can enable/disable Vary processing
The cache section's process-vary option takes a 0 or 1 value to disable or enable the vary processing. When disabled, a response containing such a header will never be cached. When enabled, we will calculate a preliminary hash for a subset of request headers on all the incoming requests (which might come with a cpu cost) which will be used to build a secondary key for a given request (see RFC 7234#4.1). The default value is 0 (disabled).
This commit is contained in:
parent
1785f3dd96
commit
754b2428d3
|
@ -14336,6 +14336,13 @@ max-age <seconds>
|
|||
seconds, which means that you can't cache an object more than 60 seconds by
|
||||
default.
|
||||
|
||||
process-vary <0 or 1>
|
||||
Disable or enable the processing of the Vary header. When disabled, a response
|
||||
containing such a header will never be cached. When enabled, we need to calculate
|
||||
a preliminary hash for a subset of request headers on all the incoming requests
|
||||
(which might come with a cpu cost) which will be used to build a secondary key
|
||||
for a given request (see RFC 7234#4.1). The default value is 0 (disabled).
|
||||
|
||||
|
||||
6.2.2. Proxy section
|
||||
---------------------
|
||||
|
|
|
@ -93,6 +93,30 @@ server s1 {
|
|||
chunkedlen 19
|
||||
chunkedlen 0
|
||||
|
||||
|
||||
} -start
|
||||
|
||||
server s2 {
|
||||
# Responses that should not be cached
|
||||
rxreq
|
||||
expect req.url == "/no_vary_support"
|
||||
txresp -nolen -hdr "Transfer-Encoding: chunked" \
|
||||
-hdr "Vary: accept-encoding" \
|
||||
-hdr "Cache-Control: max-age=5"
|
||||
chunkedlen 19
|
||||
chunkedlen 19
|
||||
chunkedlen 19
|
||||
chunkedlen 0
|
||||
|
||||
rxreq
|
||||
expect req.url == "/no_vary_support"
|
||||
txresp -nolen -hdr "Transfer-Encoding: chunked" \
|
||||
-hdr "Vary: accept-encoding" \
|
||||
-hdr "Cache-Control: max-age=5"
|
||||
chunkedlen 19
|
||||
chunkedlen 19
|
||||
chunkedlen 19
|
||||
chunkedlen 0
|
||||
} -start
|
||||
|
||||
haproxy h1 -conf {
|
||||
|
@ -105,6 +129,7 @@ haproxy h1 -conf {
|
|||
|
||||
frontend fe
|
||||
bind "fd@${fe}"
|
||||
use_backend no_vary_be if { path_beg /no_vary_support }
|
||||
default_backend test
|
||||
|
||||
backend test
|
||||
|
@ -113,10 +138,23 @@ haproxy h1 -conf {
|
|||
http-response cache-store my_cache
|
||||
http-response set-header X-Cache-Hit %[res.cache_hit]
|
||||
|
||||
backend no_vary_be
|
||||
http-request cache-use no_vary_cache
|
||||
server www ${s2_addr}:${s2_port}
|
||||
http-response cache-store no_vary_cache
|
||||
http-response set-header X-Cache-Hit %[res.cache_hit]
|
||||
|
||||
cache my_cache
|
||||
total-max-size 3
|
||||
max-age 20
|
||||
max-object-size 3072
|
||||
process-vary 1
|
||||
|
||||
cache no_vary_cache
|
||||
total-max-size 3
|
||||
max-age 20
|
||||
max-object-size 3072
|
||||
process-vary 0
|
||||
} -start
|
||||
|
||||
|
||||
|
@ -231,4 +269,20 @@ client c1 -connect ${h1_fe_sock} {
|
|||
expect resp.status == 200
|
||||
expect resp.bodylen == 57
|
||||
expect resp.http.X-Cache-Hit == 1
|
||||
|
||||
# The following requests are trated by a backend that does not cache
|
||||
# responses containing a Vary header
|
||||
txreq -url "/no_vary_support"
|
||||
rxresp
|
||||
expect resp.status == 200
|
||||
expect resp.bodylen == 57
|
||||
expect resp.http.X-Cache-Hit == 0
|
||||
|
||||
txreq -url "/no_vary_support"
|
||||
rxresp
|
||||
expect resp.status == 200
|
||||
expect resp.bodylen == 57
|
||||
expect resp.http.X-Cache-Hit == 0
|
||||
|
||||
|
||||
} -run
|
||||
|
|
29
src/cache.c
29
src/cache.c
|
@ -49,6 +49,7 @@ struct cache {
|
|||
unsigned int maxage; /* max-age */
|
||||
unsigned int maxblocks;
|
||||
unsigned int maxobjsz; /* max-object-size (in bytes) */
|
||||
uint8_t vary_processing_enabled; /* boolean : manage Vary header (disabled by default) */
|
||||
char id[33]; /* cache name */
|
||||
};
|
||||
|
||||
|
@ -706,7 +707,8 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
|
|||
struct filter *filter;
|
||||
struct shared_block *first = NULL;
|
||||
struct cache_flt_conf *cconf = rule->arg.act.p[0];
|
||||
struct shared_context *shctx = shctx_ptr(cconf->c.cache);
|
||||
struct cache *cache = cconf->c.cache;
|
||||
struct shared_context *shctx = shctx_ptr(cache);
|
||||
struct cache_st *cache_ctx = NULL;
|
||||
struct cache_entry *object, *old;
|
||||
unsigned int key = read_u32(txn->cache_hash);
|
||||
|
@ -763,8 +765,14 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
|
|||
|
||||
/* Only a subset of headers are supported in our Vary implementation. If
|
||||
* any other header is present in the Vary header value, we won't be
|
||||
* able to use the cache. */
|
||||
if (!http_check_vary_header(htx, &vary_signature)) {
|
||||
* able to use the cache. Likewise, if Vary header support is disabled,
|
||||
* avoid caching responses that contain such a header. */
|
||||
ctx.blk = NULL;
|
||||
if (cache->vary_processing_enabled) {
|
||||
if (!http_check_vary_header(htx, &vary_signature))
|
||||
goto out;
|
||||
}
|
||||
else if (http_find_header(htx, ist("Vary"), &ctx, 0)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1507,7 +1515,7 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p
|
|||
|
||||
/* Shared context does not need to be locked while we calculate the
|
||||
* secondary hash. */
|
||||
if (!res) {
|
||||
if (!res && cache->vary_processing_enabled) {
|
||||
/* Build a complete secondary hash until the server response
|
||||
* tells us which fields should be kept (if any). */
|
||||
http_request_prebuild_full_secondary_key(s);
|
||||
|
@ -1640,6 +1648,19 @@ int cfg_parse_cache(const char *file, int linenum, char **args, int kwm)
|
|||
goto out;
|
||||
}
|
||||
tmp_cache_config->maxobjsz = maxobjsz;
|
||||
} else if (strcmp(args[0], "process-vary") == 0) {
|
||||
if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
|
||||
err_code |= ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!*args[1]) {
|
||||
ha_warning("parsing [%s:%d]: '%s' expects 0 or 1 (disable or enable vary processing).\n",
|
||||
file, linenum, args[0]);
|
||||
err_code |= ERR_WARN;
|
||||
}
|
||||
|
||||
tmp_cache_config->vary_processing_enabled = atoi(args[1]);
|
||||
}
|
||||
else if (*args[0] != 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown keyword '%s' in 'cache' section\n", file, linenum, args[0]);
|
||||
|
|
Loading…
Reference in New Issue