Same URL: Don't cache with store response header, but cache when it's not there

Maninder Singh mandys at
Sun Jan 20 12:12:48 UTC 2019

Hi Everyone,

I am unable to get caching to work in a particular scenario.

I need to cache the url eg: /app/profile/GDPR1?hostingUrl=http%3A%2F%

However, this is embedded in a 3rd party site ( calls in iframe ) so on Apple Safari we can't drop cookies ( as 3rd
party cookies are blocked by default ).

As a result, for Apple Safari, when this url is hit, our backend returns
top.location.href='someurlonoursite_to_set_cookie' which is fired in
context of 3rd party site since they embed using our javascript.

This way a cookie is dropped on our domain and user gets back to the url
inside the iframe.

Now, when I hit this url in chrome, it always picks up
top.location.href='....' as it got cached by safari.

But, chrome was supposed to get the actual page content since it's not
blocking 3rd party cookies.

So, I went ahead and added a custom header, "store" for cases of apple
safari in our backend.
I skip unsetting cookie (hence varnish cache) for this url in this case.

But, it still doesn't cache on chrome in subsequent hits.

Always goes to backend, never goes to the cache.

Is it because I have one url -
- that can return 2 responses based on browser
- I told it to not cache first time when store header was there, but when
store header is not there i ask it to cache it.

Still doesn't work.


sub vcl_recv {
    std.log("vtglog: in vcl_recv " + req.url);
    # Only cache GET or HEAD requests. This makes sure the POST requests
are always passed.
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);

    if( == "" && req.url ~ "/app/profile"){
        std.log("vtglog: unsetting cookies");
        unset req.http.cookie;
    } else{

    if (req.http.Authorization) {
        # Not cacheable by default
        return (pass);

sub vcl_backend_response {
    std.log("vtglog: vcl_backend_response" + bereq.url) ;
    # Happens after we have read the response headers from the backend.
    # Here you clean the response headers, removing silly Set-Cookie headers
    # and other mistakes your backend does.
    if ( == "" && bereq.url ~
"/app/profile") {
        std.log("vtglog: inside condition in backend response");
        std.log("vtglog: store header value is " +;
        if ( beresp.http.Set-Cookie ) {
            if ( ! ) {
                std.log("vtglog: since no store headers, cache it by
unsetting cookies");
                unset beresp.http.Set-Cookie;
            } else {
                std.log("vtglog: store header found, dont cache");

    if (beresp.status == 301 || beresp.status == 302) {
        set beresp.http.Location = regsub(beresp.http.Location, ":[0-9]+",

    # Don't cache 50x responses
    if (beresp.status == 500 || beresp.status == 502 || beresp.status ==
503 || beresp.status == 504) {
        return (abandon);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the varnish-misc mailing list