Search code examples
reactjsreact-reduxvarnishvarnish-vclvarnish-4

Issue with Varnish


We are developing a website with React and Redux. We have just added a Varnish cache on our API and, although everything seems to work well when testing the API on Postman, this is not working fine on our website.

For some reason, all API queries are failing with an 401 status code the first time that they are done, however, they works fine after having failed the first time.

This behaviour has just started happening once we have added Varnish cache, but, we are unable to found the error.

The Varnish configuration file is as follows:

vcl 4.0;

backend default {
    .host = ...;
    .port = ...;
}

sub vcl_backend_response {
    set beresp.ttl = 5m;

    # Don't cache non-200 responses
    if ( beresp.status != 200 ) {
        set beresp.ttl = 0s;
    }
    # Don't cache if "no-cache" or "private" on cache control
    if (beresp.http.cache-control ~ "(no-cache|private)" ||
        beresp.http.pragma ~ "no-cache") {
            set beresp.ttl = 0s;
    }

}

sub vcl_recv {
    # Do not cache Healthcheck call
    if (req.url == "/api/healthcheck") {
        return (pass);
    }

    # Do not cache POST methods
    if (req.method == "POST") {
        return (pass);
    }

    # Do not cache users' calls as each user will be different
    if (req.url ~ "\/api\/v[a-zA-Z0-9\.]+\/users\/.*") {
        return (pass);
    } 

    # Ensure that cache is enabled to any call to the API
    if (req.url ~ "/api/*") {
        return (hash);
    }   
}

sub vcl_deliver {
  if (req.url ~ "/api/*") {
    set resp.http.Access-Control-Allow-Headers = "Accept, Accept-Encoding, Authorization, Content-Type, Dnt, Origin, User-Agent, X-CSRFToken, X-Requested-With";
    return (deliver);
  } 
}

What may be going on?

Thanks a lot


Solution

  • I have finally found my issue, there was an return(hash) missing on my configuration file.

    The right configuration file is as follows:

    vcl 4.0;
    
    backend default {
        .host = ...;
        .port = ...;
    }
    
    sub vcl_backend_response {
        set beresp.ttl = 5m;
    
        # Don't cache non-200 responses
        if ( beresp.status != 200 ) {
            set beresp.ttl = 0s;
        }
        # Don't cache if "no-cache" or "private" on cache control
        if (beresp.http.cache-control ~ "(no-cache|private)" ||
            beresp.http.pragma ~ "no-cache") {
                set beresp.ttl = 0s;
        }
    
    }
    
    sub vcl_recv {
        # Do not cache Healthcheck call
        if (req.url == "/api/healthcheck") {
            return (pass);
        }
    
        if (req.method != "GET" && req.method != "HEAD") {
            # We only deal with GET and HEAD by default
            return (pass);
        }
    
        # Do not cache users' calls as each user will be different
        if (req.url ~ "\/api\/v[a-zA-Z0-9\.]+\/users\/.*") {
            return (pass);
        }
        return (hash);
    }
    
    sub vcl_deliver {
      if (req.url ~ "/api/*") {
        set resp.http.Access-Control-Allow-Headers = "Accept, Accept-Encoding, Authorization, Content-Type, Dnt, Origin, User-Agent, X-CSRFToken, X-Requested-With";
        return (deliver);
      }
    }