This patch add a hash of the Origin header to the cache's secondary key.
This enables to manage store responses that have a "Vary: Origin" header
in the cache when vary is enabled.
This cannot be considered as a means to manage CORS requests though, it
only processes the Origin header and hashes the presented value without
any form of URI normalization.
This need was expressed by Philipp Hossner in GitHub issue #251.
Co-Authored-by: Philipp Hossner <philipp.hossner@posteo.de>
- If the response is not a 200
- If the response contains a Vary header and either the process-vary option is
disabled, or a currently unmanaged header is specified in the Vary value (only
- accept-encoding and referer are managed for now)
+ accept-encoding, referer and origin are managed for now)
- If the Content-Length + the headers size is greater than "max-object-size"
- If the response is not cacheable
- If the response does not have an explicit expiration time (s-maxage or max-age
Enable or disable 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 off (disabled).
+ (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 secondary key is built out of
+ the contents of the 'accept-encoding', 'referer' and 'origin' headers for
+ now. The default value is off (disabled).
max-secondary-entries <number>
Define the maximum number of simultaneous secondary entries with the same primary
* request/response pairs, because they depend on the responses' optional Vary
* header. The different sizes can be found in the vary_information object (see
* cache.c).*/
-#define HTTP_CACHE_SEC_KEY_LEN (sizeof(uint32_t)+sizeof(uint64_t))
+#define HTTP_CACHE_SEC_KEY_LEN (sizeof(uint32_t)+sizeof(uint64_t)+sizeof(uint64_t))
/* Redirect flags */
-hdr "Content-Encoding: gzip" \
-bodylen 57
+ rxreq
+ expect req.url == "/origin-referer-accept-encoding"
+ txresp -hdr "Vary: origin,referer,accept-encoding" \
+ -hdr "Cache-Control: max-age=5" \
+ -hdr "Content-Encoding: gzip" \
+ -bodylen 58
+
+ rxreq
+ expect req.url == "/origin-referer-accept-encoding"
+ txresp -hdr "Vary: origin,referer,accept-encoding" \
+ -hdr "Cache-Control: max-age=5" \
+ -hdr "Content-Encoding: gzip" \
+ -bodylen 59
+
# Multiple Accept-Encoding headers
rxreq
expect req.url == "/multiple_headers"
expect resp.http.X-Cache-Hit == 1
+ # Mixed Vary (Accept-Encoding + Referer + Origin)
+ txreq -url "/origin-referer-accept-encoding" \
+ -hdr "Accept-Encoding: br, gzip" \
+ -hdr "Referer: referer" \
+ -hdr "Origin: origin"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 58
+ expect resp.http.X-Cache-Hit == 0
+
+ txreq -url "/origin-referer-accept-encoding" \
+ -hdr "Accept-Encoding: br, gzip" \
+ -hdr "Referer: referer" \
+ -hdr "Origin: origin"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 58
+ expect resp.http.X-Cache-Hit == 1
+
+ txreq -url "/origin-referer-accept-encoding" \
+ -hdr "Accept-Encoding: br, gzip" \
+ -hdr "Referer: referer" \
+ -hdr "Origin: other-origin"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 59
+ expect resp.http.X-Cache-Hit == 0
+
+ txreq -url "/origin-referer-accept-encoding" \
+ -hdr "Accept-Encoding: br, gzip" \
+ -hdr "Referer: referer" \
+ -hdr "Origin: other-origin"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 59
+ expect resp.http.X-Cache-Hit == 1
+
# Multiple Accept-encoding headers
txreq -url "/multiple_headers" \
-hdr "Accept-Encoding: gzip" \
enum vary_header_bit {
VARY_ACCEPT_ENCODING = (1 << 0),
VARY_REFERER = (1 << 1),
+ VARY_ORIGIN = (1 << 2),
VARY_LAST /* should always be last */
};
const struct vary_hashing_information vary_information[] = {
{ IST("accept-encoding"), VARY_ACCEPT_ENCODING, sizeof(uint32_t), &accept_encoding_normalizer, &accept_encoding_bitmap_cmp },
{ IST("referer"), VARY_REFERER, sizeof(uint64_t), &default_normalizer, NULL },
+ { IST("origin"), VARY_ORIGIN, sizeof(uint64_t), &default_normalizer, NULL },
};
#undef ACCEPT_ENCODING_MAX_ENTRIES
/*
- * Normalizer used by default for the Referer header. It only
+ * Normalizer used by default for the Referer and Origin header. It only
* calculates a hash of the whole value using xxhash algorithm.
* Only the first occurrence of the header will be taken into account in the
* hash.