Назад | Перейти на главную страницу

Я изо всех сил пытаюсь настроить лак для учета языкового cookie

Я новичок в мире кеширования лака, и мне нужно оптимизировать приложение Wordpress, которое работает довольно медленно. Сегодня я провел много исследований и добился определенных успехов, но я застрял в настройке языковых файлов cookie.

Итак, приложение устанавливает файл cookie с именем qtrans_front_language это указывает, какой язык должен использоваться во внешнем интерфейсе. Я хочу кэшировать все страницы с помощью varnish, но я не могу игнорировать этот файл cookie, иначе я не могу переключить язык после кеширования страницы, и я получаю странное поведение при одновременной навигации из разных браузеров.
Я думал о добавлении определения языка (например, «en») в хэш при кэшировании, чтобы каждая страница получала свою собственную запись в кеше, и в следующий раз, когда я ее просматриваю, я получаю HIT.

Моя проблема в том, что этот файл cookie устанавливается серверной частью, но, если я не «отбрасываю» файлы cookie серверной части, мои страницы никогда не кэшируются лаком.

Вот что у меня есть на данный момент:

vcl 4.0;

# Import directors and std library.
import directors;
import std;

# Backend
backend default {
    .host = "my_ip_here";
    .port = "80";
    .connect_timeout = 600s;
    .first_byte_timeout = 600s;
    .between_bytes_timeout = 600s;
    .max_connections = 800;
    .probe = {
        .url = "/";
        .timeout = 1s;
        .interval = 5s;
        .window = 5;
        .threshold = 3;
    }
}

sub vcl_init {
    new foo = directors.round_robin();
    foo.add_backend(default);
}

sub vcl_recv {

    call identify_cookie;

    # Send all traffic to the foo director.
    set req.backend_hint = foo.backend();

    # Skip administrative areas
    if (req.url ~ "wp-admin|wp-login|xmlrpc.php") {
        return(pass);
    }

    # Do not cache POST requests.
    if (req.http.Authorization || req.method == "POST") {
        return(pass);
    }

    # Remove all cookies that starts with '__', namely Google Analytics cookies.
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", "");

    # Remove language cookie.
    set req.http.Cookie = regsuball(req.http.Cookie, "qtrans_front_language=.*", "");

    # Remove wordpress cookies.
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");

    # Remove empty cookies
    set req.http.Cookie = regsuball(req.http.Cookie, "^ *$", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "^; +?$", "");

    # Cache images, css, js and other static content.
    if (req.url ~ "\.(css|js|png|gif|jp(e)?g|swf|ico)") {
        unset req.http.cookie;
        call normalize_req_url;
    }

    # Normalize Accept-Encoding header and compression
    if (req.http.Accept-Encoding) {
        # Do not compress compressed files.
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
            unset 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 {
            unset req.http.Accept-Encoding;
        }
    }

    if (req.http.Cookie == "") {
        unset req.http.Cookie;
    }

    return(hash);
}

sub vcl_backend_response {

    # Set a grace time of 1h
    set beresp.grace = 1h;

    # Set a TTL of 10m
    set beresp.ttl = 10m;

    # Avoid setting cookies and Cache-Control if url !~ wp-(login|admin)
    if (!bereq.url ~ "wp-(login|admin)") {
        unset beresp.http.Set-Cookie;
        unset beresp.http.Cache-Control;
    }
}

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) {
        set req.http.Language = "en";
    }

    hash_data(req.http.Language);

    # If the client supports compression, keep that in a different cache entry
    if (req.http.Accept-Encoding) {
        hash_data(req.http.Accept-Encoding);
    }

    return (lookup);
}

sub vcl_deliver {

    # A bit of debugging info.
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    }
    else {
        set resp.http.X-Cache = "MISS";
    }
}

sub vcl_hit {

    # A cache hit, deliver it.
    if (obj.ttl >= 0s) {
        return(deliver);
    }

    # If object is in grace deliver it and trigger a background fetch.
    # Also make sure backend is healthy.
    if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace > 0s)) {
        return(deliver);
    }
    else {
        return(fetch);
    }
}

# This method is used to strip out ?timestamp=[0-9]+ from the url
# so that we can hash it later.
sub normalize_req_url {
    if (req.url ~ "\?timestamp=[0-9]+") {
        set req.url = regsuball(req.url, "\?timestamp=[0-9]+", "");
    }
}

sub identify_cookie {
    if (req.http.cookie ~ "qtrans_front_language=") {
        set req.http.Language = regsub(req.http.Cookie, "(.*?)(qtrans_front_language=)([^;]*)(.*)$", "\3");
    }
}

Таким образом, я могу определить текущий язык, но я делаю что-то не так, потому что даже если пользователь устанавливает другой язык, отображается неправильная страница. Я думаю это тревожит beresp.http.Set-Cookie в ответе серверной части, вероятно, неправильный поступок.

Что я делаю не так? Как я могу решить эту проблему?