#This is a basic VCL configuration file for varnish.  See the vcl(7)
#man page for details on VCL syntax and semantics.
#
#Default backend definition.  Set this to point to your content
#server.
#
backend default {
    .host = "%(backend_server)s";
    .port = "%(backend_port)s";
    .probe = {
        .timeout = 30s;
        .interval = 5s;
        .window = 4;
        .threshold = 3;
        .request =
            "OPTIONS /erp5/getId HTTP/1.1"
            "Host: %(backend_server)s:%(backend_port)s"
            "Accept-Encoding: identity"
            "Connection: close"
            "User-Agent: Varnish";
    }
}

# Called at the beginning of a request, after the complete request has been received and parsed
sub vcl_recv {
    # Pass any requests that Varnish does not understand straight to the backend.
    if (req.request != "GET" &&
        req.request != "HEAD" &&
        req.request != "PUT" &&
        req.request != "POST" &&
        req.request != "TRACE" &&
        req.request != "OPTIONS" &&
        req.request != "PURGE" &&
        req.request != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }
    # Pass anything other than GET and HEAD directly.
    if (req.request != "GET" && req.request != "HEAD") {
        return (pass);
    }
    if (req.http.Authorization) {
        /* Not cacheable by default */
        return (pass);
    }

    # No need to have cookies for static resources
    if (req.url ~ "\.(css|gif|ico|jpg|js|png)$") {
        unset req.http.Cookie;
    }
    # Remove bogus cookies
    if (req.http.Cookie) {
        set req.http.Cookie = regsuball(req.http.Cookie, "(^|; ) *__utm.=[^;]+;? *", "\1");
        set req.http.Cookie = regsuball(req.http.Cookie, "(^|; ) *__ac_name=\x22\x22;? *", "\1");
        set req.http.Cookie = regsuball(req.http.Cookie, "(^|; ) *__ac=\x22Og.3D.3D\x22;? *", "\1");
    }
    if (req.http.Cookie == "") {
        unset req.http.Cookie;
    }
    if (req.http.Cookie && req.http.Cookie ~ "(^|; ) *__ac=") {
        return (pass);
    }

    # We do not care about Accept-Encoding, because we don't use varnish as the front most HTTP server.
    unset req.http.Accept-Encoding;

    if (req.backend.healthy) {
        set req.grace = 1h;
    } else {
        set req.grace = 1w;
    }
    return (lookup);
}

# Run after a pass in vcl_recv OR after a lookup that returned a hitpass
sub vcl_pass {
    # unset If-Modified-Since to avoid reusing anonymous's browser cache
    # after login.
    unset req.http.If-Modified-Since;
    return (pass);
}

# Creates the varnish cache key by the url
sub vcl_hash {
    # We use url only for hash.
    hash_data(req.url);
    return (hash);
}

# Called after a cache lookup if the requested document was found in the cache
sub vcl_hit {
    return (deliver);
}

# Called after a cache lookup if the requested document was not found in the cache
sub vcl_miss {
    return (fetch);
}

# Called after a document has been successfully retrieved from the backend
sub vcl_fetch {
    # Unset Expires that is always overridden by Cache-Control.
    unset beresp.http.Expires;

    # Unset Pragma that is obsolete.
    unset beresp.http.Pragma;

    # We only cache 200 (OK) and 304 (Not Modified) responses.
    if (beresp.status != 200 && beresp.status != 304) {
        set beresp.ttl = 0s;
    }

    # If max-age is 0 or not set, we want no browser cache.
    if (beresp.ttl <= 0s) {
        set beresp.http.Cache-Control = "no-store";
        # Mark as hit_for_pass for the next 2 minutes.
        set beresp.ttl = 120s;
        return (hit_for_pass);
    }

    # We don't care haproxy's cookie.
    if (beresp.http.Set-Cookie && beresp.http.Set-Cookie !~ "^SERVERID=[^;]+; path=/$") {
        return (hit_for_pass);
    } else {
        unset beresp.http.Set-Cookie;
    }

    # We set long enough grace for cachable objects.
    set beresp.grace = 1w;

    return (deliver);
}

# Called before a cached object is delivered to the client
sub vcl_deliver {
    if (obj.hits > 0) {
        set resp.http.X-Cache = obj.hits;
    } else {
        set resp.http.X-Cache = "MISS";
    }
    return (deliver);
}
