简体   繁体   中英

Server side caching Joomfish (varnish)

Does anyone have any idea how I can get around Joomfish needing a cookie to set and keep the language for a joomla site.

I have to use server side caching for the site I have inherited as it is stupidly slow and server intensive due to the way its constructed. I can't restructure it as that woul dbe way to much rebuilding.

Problem being JoomFish sets a cookie to determine the language of the user. That cookie gets cached or unset. Which means the user only gets the chached language site rather than the language they have chosen.

I am using Varnish 3 for server side caching. Joomla 2.5 and Joomfish 2.5.1

My VCL is:

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}
acl purge {
    "127.0.0.1";
    "192.168.0.0"/24;
}

sub vcl_recv {

    # Set up purging cache
    if(req.request == "PURGE") {
        if (!client.ip ~ purge) {
          error 405 "Method not allowed";
        }
        return (lookup);
    }

    # Forward client's IP to backend
    remove req.http.X-Forwarded-For;
    set req.http.X-Forwarded-For = client.ip;

    # Proxy (pass) any request that goes to the backend admin,
    # the banner component links or any post requests
    # You can add more pages or entire URL structure in the end of the "if"

    if(req.http.cookie ~ "userID" || req.url ~ "^/administrator" || req.url ~ "^/component/banners" || req.request == "POST") {
        return (pipe);
    }

    # Check for the custom "x-logged-in" header to identify if the visitor is a guest,
    # then unset any cookie (including session cookies) provided it's not a POST request
    if(req.http.x-logged-in == "False" && req.request != "POST"){
        unset req.http.cookie;
    }

    # Properly handle different encoding types
    if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$") {
            # No point in compressing these
            remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            # unknown algorithm (aka crappy browser)
            remove req.http.Accept-Encoding;
        }
    }

    # Cache files with these extensions
    if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$") {
        return (lookup);
    }

    # Set how long Varnish will cache content depending on whether your backend is healthy or not
    if (req.backend.healthy) {
        set req.grace = 5m;
    } else {
        set req.grace = 1h;
    }

    return (lookup);
}

sub vcl_fetch {

    # Check for the custom "x-logged-in" header to identify if the visitor is a guest,
    # then unset any cookie (including session cookies) provided it's not a POST request
    if(req.request != "POST" && beresp.http.x-logged-in == "False") {
        unset beresp.http.Set-Cookie;
    }

    # Allow items to be stale if needed (this value should be the same as with "set req.grace"
    # inside the sub vcl_recv {…} block (the 2nd part of the if/else statement)
    set beresp.grace = 1h;

    # Serve pages from the cache should we get a sudden error and re-check in one minute
    if (beresp.status == 503 || beresp.status == 502 || beresp.status == 501 || beresp.status == 500) {
        set beresp.grace = 60s;
        return (restart);
    }

    # Unset the "etag" header (suggested)
    unset beresp.http.etag;

    # This is Joomla! specific: fix stupid "no-cache" header sent by Joomla! even
    # when caching is on - make sure to replace 300 with the number of seconds that
    # you want the browser to cache content
    if(beresp.http.Cache-Control == "no-cache" || beresp.http.Cache-Control == ""){
        set beresp.http.Cache-Control = "max-age=300, public, must-revalidate";
    }

    # This is how long Varnish will cache content
    set beresp.ttl = 15m;

    return (deliver);
}

sub vcl_hit {
    if (req.request == "PURGE") {
        purge;
        error 200 "Purged";
    }
}

sub vcl_miss {
    if (req.request == "PURGE") {
        purge;
        error 404 "Not in cache";
    }
}
sub vcl_pass {
    if (req.request == "PURGE") {
        error 502 "PURGE on a passed object";
    }
}

I have now figured this out. For any one else experiencing the same problem. You can simply pass to the server on the value of the joomfish cookie. For example:

sub vcl_recv {  
    if(req.http.cookie ~ "jfcookie\[lang\]=fr"){
        return (pass);
    }
}

That will ensure that the french user receives the french site. Haven't figured out a way to cache the french site separately though. Apparently you can do something with the hash. Which is what I am now looking into, will post a solution if I find one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM