Избегайте кеширования перенаправления из Special: Random в лаке - PullRequest
0 голосов
/ 24 января 2020

Я использую varni sh для предоставления контента из моей установки MediaWiki моим пользователям. Почти каждая страница кэшируется правильно, как определено в vcl:

vcl 4.0;

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

backend thumbor {
    .host = "xxxx";
    .port = "xxxx";
}

acl purge {
    "xxxx";
}

sub vcl_recv {
        set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
        set req.backend_hint= default;

        if (req.method == "PURGE") {
            if (!client.ip ~ purge) {
                return (synth(405, "Not allowed."));
            } else {
                return (purge);
            }
        }

        if (req.method != "GET" && req.method != "HEAD" &&
            req.method != "PUT" && req.method != "POST" &&
            req.method != "TRACE" && req.method != "OPTIONS" &&
            req.method != "DELETE") {
                return (pipe);
        }

        if (req.method != "GET" && req.method != "HEAD") {
            return (pass);
        }

    if (req.http.If-None-Match) {
        return (pass);
    }

    if (req.http.X-Debug-Server) {
        return (pass);
    }

    if (req.http.Cache-Control ~ "no-cache") {
        ban(req.url);
    }

        if (req.http.Accept-Encoding) {
          if (req.http.User-Agent ~ "MSIE 6") {
            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.url ~ "(?i)\.(jpg|jpeg|jpe|png)$" && req.url ~ "(?i)/thumb/" && req.http.Accept ~ "(?i)image/webp" && req.http.x-no-thumbor != "yes") {
        set req.http.x-orig-url = req.url;
        set req.url = regsub(req.url,".*\/thumb\/(.*)","/unsafe/filters:format(webp)/thumb/\1");
        set req.backend_hint = thumbor;
    }

    if (req.url ~ "action=amp$") {
        unset req.http.Cookie;
        unset req.http.x-wap;
        return (hash);
    }

        if (req.http.Authorization || req.http.Cookie ~ "session" || req.http.Cookie ~ "Token") {
            return (pass);
        }

    if (req.http.Cookie ~ "droidwikiwikicookiewarning_dismissed=true") {
        set req.http.Cookie = "droidwikiwikicookiewarning_dismissed=true";
    } else {
        unset req.http.Cookie;
    }

    unset req.http.x-wap;
    if (req.http.User-Agent ~ "(?i)^(lg-|sie-|nec-|lge-|sgh-|pg-)|(mobi|240x240|240x320|320x320|alcatel|android|audiovox|bada|benq|blackberry|cdm-|compal-|docomo|ericsson|hiptop|htc[-_]|huawei|ipod|kddi-|kindle|meego|midp|mitsu|mmp\/|mot-|motor|ngm_|nintendo|opera.m|palm|panasonic|philips|phone|playstation|portalmmm|sagem-|samsung|sanyo|sec-|sendo|sharp|softbank|symbian|teleca|up.browser|webos)" && req.url !~ "(\?|&)(action=amp)") {
        set req.http.x-wap = "no";
    }

    if (req.http.Cookie ~ "mf_useformat=") {
        set req.http.x-wap = "no";
    }

        return (hash);
}

sub vcl_hash {
    hash_data(req.http.x-wap);
}

sub vcl_pipe {
        set req.http.connection = "close";
}

sub vcl_purge {
    if (req.url !~ "(\?|&)(action=amp)") {
        set req.http.X-Original = req.url;
        if (req.url ~ "&") {
            set req.url = req.url + "&action=amp";
        } else {
            set req.url = req.url + "?action=amp";
        }
        return (restart);
    }

    if (req.http.X-Original) {
        set req.url = req.http.X-Original;
    }

    if (!req.http.x-wap) {
        set req.http.x-wap = "no";
        return (restart);
    }
}

sub vcl_hit {
        if (req.method == "PURGE") {
            ban(req.url);
            return (synth(200, "Purged"));
        }

        if (!obj.ttl > 0s) {
            return (pass);
        }
}

sub vcl_miss {
        if (req.method == "PURGE")  {
            return (synth(200, "Not in cache"));
        }
}

sub vcl_deliver {
    if (resp.http.x-origin == "thumbor" && resp.status != 200) {
        set req.url = req.http.x-orig-url;
        set req.http.x-no-thumbor = "yes";
        return (restart);
    }

    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    } else {
        set resp.http.X-Cache = "MISS";
    }
}

sub vcl_backend_error {
    set beresp.http.x-origin = beresp.backend.name;
}

sub vcl_backend_response {
        set beresp.grace = 120s;

        if (beresp.ttl < 48h) {
          set beresp.ttl = 48h;
        }       

        if (!beresp.ttl > 0s) {
          set beresp.uncacheable = true;
          return (deliver);
        }

        if (beresp.http.Set-Cookie) {
          set beresp.uncacheable = true;
          return (deliver);
        }

        if (beresp.http.Authorization && !beresp.http.Cache-Control ~ "public") {
          set beresp.uncacheable = true;
          return (deliver);
        }

        return (deliver);
}

Однако текущая конфигурация также приводит к кэшированию перенаправлений. Хотя это вполне ожидаемое поведение для обычных страниц с перенаправлением (например, перенаправление статьи A на статью B), для страницы Special:Random это неожиданно. Ожидается, что эта страница будет перенаправлять меня на случайную страницу каждый раз, когда я ее открываю. Однако, поскольку редирект кешируется varni sh, я всегда перенаправляюсь на одну и ту же страницу.

То, о чем я уже думал: 1. Не кэшируем 302 редиректы вообще, однако это может оказать негативное влияние к другим перенаправлениям, которые я обычно хотел бы кэшировать 2. Однако, имея URL-фильтр на Special:Random, делая это, я должен был бы выполнить это исключение для всех языков, которые поддерживает вики, чтобы обеспечить его надежность. Я не очень доволен этим

Мой вопрос здесь будет таким: есть ли у кого-нибудь идеи, как этого можно достичь с помощью правила, которое не требует обслуживания, а также охватывает только Special:Random? Может быть, решение, которое также используется вики-сайтами Викимедиа? Там страница Special:Random всегда перенаправляет на другую страницу, однако мне не удалось найти блок кода, который достигает этого в их репозитории: (

1 Ответ

1 голос
/ 18 февраля 2020

Varni sh уважает обычный Cache-Control HTTP-заголовок ответа, который можно отправить из вашего приложения.

Я не эксперт MediaWiki, но заметил, что MediaWiki предоставляет хуки для расширяет свое поведение. Если вы можете подключиться к потоку запросов / ответов MediaWiki и обнаружить случай Special:Random, вы можете внедрить заголовок Cache-Control: private, no-cache, no-store, который вынуждает Varni sh не кэшировать эти страницы.

Это было бы идеальным способом получить ожидаемый результат без необходимости писать VCL.

В целом, рекомендуется использовать заголовки кэширования HTTP для управления поведением обратного кэширующего прокси, такого как Varni sh.

  • Это делает приложение более переносимым
  • Это делает приложение менее зависимым от специфики c технологии кэширования
  • Это позволяет разработчикам думать о кэшировании изнутри архитектура приложения
...