1

My website has multiple languages. English is default language with url:

http://domain.com/ (http://domain.com/en).

When users want to use different language, they will click on the language button. For example, They want to switch to Japanese:

http://domain.com/ja

At that time, they will have cookies with name SiteLang=ja.

My Varnish configuration:

backend default {
    .first_byte_timeout = 15s;
    .connect_timeout = 1s;
    .max_connections = 200;
    .between_bytes_timeout = 10s;
    .port = "8080";
    .host = "127.0.0.1";
}

sub vcl_recv {

    if (req.http.Cookie ~ "SiteLang=") {
            #unset all the cookie from request except language
            set req.http.Language = regsub(req.http.Cookie, "(?:^|;\s*)(?:SiteLang=(.*?))(?:;|$)", "\1.");
        } elseif (!req.http.Cookie) {
            set req.http.Language = "fr";
        }
    # Forward client's IP to backend
    remove req.http.X-Forwarded-For;
    set req.http.X-Forwarded-For = client.ip;

    # Set the URI of your system directory
    if (req.url ~ "^/system/" ||
        req.url ~ "ACT=" ||
        req.request == "POST" ||
        (req.url ~ "member_box" && req.http.Cookie ~ "exp_sessionid"))
    {
        return (pass);
    }

    unset req.http.Cookie;

    set req.grace = 1h;

    return(lookup);
}

sub vcl_fetch {

   #if (!beresp.http.set-Cookie ~ "SiteLang="){
   #     unset beresp.http.set-cookie;
   #}

    # Enable ESI includes
    set beresp.do_esi = true;

    # Our cache TTL
    set beresp.ttl = 1m;

    set beresp.grace = 1h;

    return(deliver);

}
sub vcl_deliver {

    if (req.http.X-Varnish-Accept-Language) {
        set resp.http.Set-Cookie = req.http.Language;
    }

}

sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    if (req.http.Language) {
        #add cookie in hash
        hash_data(req.http.Language);
    }
    return(hash);
}

When the user visits the homepage, their preferred language was changed to English. So something is wrong with cookies on varnish.

All I want is when users choose their language, they can go to the homepage without changing languages and varnish serves cache properly.

Thanks

Kevin Nguyen
  • 189
  • 1
  • 2
  • 8

1 Answers1

1

I finally made it work.

backend default {
    .first_byte_timeout = 15s;
    .connect_timeout = 1s;
    .max_connections = 200;
    .between_bytes_timeout = 10s;
    .port = "8080";
    .host = "127.0.0.1";
}

sub vcl_recv {

    if (req.http.Cookie ~ "SiteLang=") {
            #unset all the cookie from request except language
            set req.http.Language = regsub(req.http.Cookie, "(?:^|;\s*)(?:SiteLang=(.*?))(?:;|$)", "\1.");
        } elseif (!req.http.Cookie) {
            set req.http.Language = "fr";
        }
    # Forward client's IP to backend
    remove req.http.X-Forwarded-For;
    set req.http.X-Forwarded-For = client.ip;

    # Set the URI of your system directory
    if (req.url ~ "^/system/" ||
        req.url ~ "ACT=" ||
        req.request == "POST" ||
        (req.url ~ "member_box" && req.http.Cookie ~ "exp_sessionid"))
    {
        return (pass);
    }

    #unset req.http.Cookie;

    set req.grace = 1h;

    return(lookup);
}

sub vcl_fetch {

   #if (!beresp.http.set-Cookie ~ "SiteLang="){
   #     unset beresp.http.set-cookie;
   #}

    # Enable ESI includes
    set beresp.do_esi = true;

    # Our cache TTL
    set beresp.ttl = 1m;

    set beresp.grace = 1h;

    return(deliver);

}
sub vcl_deliver {

    if (req.http.X-Varnish-Accept-Language) {
        set resp.http.Set-Cookie = req.http.Language;
    }

}

sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    if (req.http.Language) {
        #add cookie in hash
        hash_data(req.http.Language);
    }
    return(hash);
}

My mistake is:

#unset req.http.Cookie;

in sub vcl_recv that will empty my cookies.

Kevin Nguyen
  • 189
  • 1
  • 2
  • 8