Skip to content

Add vary-dynamic test#54

Open
neilstuartcraig wants to merge 5 commits intohttp-tests:mainfrom
bbc:master
Open

Add vary-dynamic test#54
neilstuartcraig wants to merge 5 commits intohttp-tests:mainfrom
bbc:master

Conversation

@neilstuartcraig
Copy link

Hi @mnot
This is the PR I mentioned in #49 - adding a test to validate what I have called "dynamic vary". This issue came to my attention during building a traffic management system, we determined that nginx does not create cache object variants when the origin issues a vary header whose value is dependent on the value of a request header (we have some use cases which require this). Failure to support "dynamic vary" can result in flip-flopping - nginx simply overwrites the single cached object with the new object, this obviously ruins cache offload under transitional circumstances. As a ref for nginx, please see this ticket: https://trac.nginx.org/nginx/ticket/955.

My intention through adding this PR is twofold:

  1. I'd like to document for others that nginx doesn't support "dynamic vary" as there's not much on the internet about it
  2. This might add some weight to HTTP specs (I guess) which in turn might persuade the nginx folks that they should support "dynamic vary"

Varnish does support "dynamic vary" according to our tests.

I'm sure you'll see what I'm trying to achieve by looking at the added test, I believe I've correctly defined the behaviour but please let me know if you think I've done the wrong thing. Currently I see an error on request 3 which I expect not to be cached and indeed it looks to me like nginx did not serve a cached response for that request (I added a custom response header to nginx whose value is $upstream_cache_status, this says MISS):

[root@8b32f5ef0012 cache-tests]# npm run --silent cli --base=http://127.0.0.1:80 --id=vary-dynamic
(node:1045) ExperimentalWarning: The ESM module loader is experimental.
Running vary-dynamic
=== Client request 1
    GET http://127.0.0.1:80/test/19bd78b2-8e6c-4ba2-b1e7-7f7c17fef2ac
    v1: one
    v2: two
    ctrl: a
    Test-Name: An optimal HTTP cache stores and correctly serves multiple object variants when the `Vary` response header value depends on one or more request header values
    Test-ID: vary-dynamic
    Req-Num: 1

=== Server request 1
    GET /test/19bd78b2-8e6c-4ba2-b1e7-7f7c17fef2ac
    host: 127.0.0.1
    v1: one
    v2: two
    ctrl: a
    test-name: An optimal HTTP cache stores and correctly serves multiple object variants when the `Vary` response header value depends on one or more request header values
    test-id: vary-dynamic
    req-num: 1
    accept: */*
    user-agent: node-fetch/1.0 (+https://github.com/bitinn/node-fetch)
    accept-encoding: gzip,deflate

=== Server response 1
    HTTP 200 OK
    expires: Wed, 15 May 2019 14:05:37 GMT
    last-modified: Wed, 15 May 2019 11:52:17 GMT
    date: Wed, 15 May 2019 12:42:17 GMT
    vary: v1, ctrl
    content-type: text/plain
    server-request-count: 1
    server-now: Wed, 15 May 2019 12:42:17 GMT

=== Client response 1
    HTTP 200 OK
    connection: close
    content-length: 36
    content-type: text/plain
    date: Wed, 15 May 2019 12:42:17 GMT
    expires: Wed, 15 May 2019 14:05:37 GMT
    last-modified: Wed, 15 May 2019 11:52:17 GMT
    ngx-cache-status: MISS
    server: nginx/1.16.0
    server-now: Wed, 15 May 2019 12:42:17 GMT
    server-request-count: 1
    vary: v1, ctrl

=== Client request 2
    GET http://127.0.0.1:80/test/19bd78b2-8e6c-4ba2-b1e7-7f7c17fef2ac
    v1: one
    v2: two
    ctrl: a
    Test-Name: An optimal HTTP cache stores and correctly serves multiple object variants when the `Vary` response header value depends on one or more request header values
    Test-ID: vary-dynamic
    Req-Num: 2

=== Client response 2
    HTTP 200 OK
    connection: close
    content-length: 36
    content-type: text/plain
    date: Wed, 15 May 2019 12:42:17 GMT
    expires: Wed, 15 May 2019 14:05:37 GMT
    last-modified: Wed, 15 May 2019 11:52:17 GMT
    ngx-cache-status: HIT
    server: nginx/1.16.0
    server-now: Wed, 15 May 2019 12:42:17 GMT
    server-request-count: 1
    vary: v1, ctrl

=== Client request 3
    GET http://127.0.0.1:80/test/19bd78b2-8e6c-4ba2-b1e7-7f7c17fef2ac
    v1: one
    v2: two
    ctrl: b
    Test-Name: An optimal HTTP cache stores and correctly serves multiple object variants when the `Vary` response header value depends on one or more request header values
    Test-ID: vary-dynamic
    Req-Num: 3

=== Server request 2
    GET /test/19bd78b2-8e6c-4ba2-b1e7-7f7c17fef2ac
    host: 127.0.0.1
    v1: one
    v2: two
    ctrl: b
    test-name: An optimal HTTP cache stores and correctly serves multiple object variants when the `Vary` response header value depends on one or more request header values
    test-id: vary-dynamic
    req-num: 3
    accept: */*
    user-agent: node-fetch/1.0 (+https://github.com/bitinn/node-fetch)
    accept-encoding: gzip,deflate

=== Server response 2
    HTTP 200 OK
    content-type: text/plain
    server-request-count: 2
    server-now: Wed, 15 May 2019 12:42:17 GMT

=== Client response 3
    HTTP 200 OK
    connection: close
    content-length: 36
    content-type: text/plain
    date: Wed, 15 May 2019 12:42:17 GMT
    ngx-cache-status: MISS
    server: nginx/1.16.0
    server-now: Wed, 15 May 2019 12:42:17 GMT
    server-request-count: 2

==== Results
{
  "vary-dynamic": [
    "Assertion",
    "Response 3 comes from cache"
  ]

I suspect that perhaps the server component of cache-tests might be doing the wrong thing here, would you agree? I'll happily do some work on it if you think that is likely to be the issue and if you're interested in this PR so if you could let me know when you have moment, that'd be great.

Many thanks and apologies for the epic message :-)
Neil

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants