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

Varnish default.vcl для покрытия как Drupal, так и простого обычного веб-сайта

У меня есть простой веб-сайт с индексным файлом PHP, который меняет цвет при обновлении через порт 8080, но правильно показывает кешированную версию страницы с тем же цветом благодаря следующему default.vcl:

    vcl 4.0;

    # This is where your content lives. Adjust it to point at your web server.

    backend default {
        .host = "xx.xx.xx.xx";
        .port = "8080";
    }

    # The only thing stopping Varnish from caching properly by default in most
# cases is the presence of cookies. Strip them, and voila, cache works.
sub vcl_recv {
    # We leave cookies for content under "/user".
        if (req.url !~ "^/user") {
                unset req.http.cookie;
        }
}

# That's all you need, but you might want to start adjusting cache duration
# too! You can do that by emitting "Cache-Control: s-maxage=123" from your
# backend server, telling Varnish to cache for 123 seconds. That requires 0
# configuration, but the following snippet removes "s-maxage" from the
# response before it is sent to the client, so as not to confuse other
# proxy servers between you and the client.
sub strip_smaxage {
        # Remove white space
        set beresp.http.cache-control = regsuball(beresp.http.cache-control, " ","");
        # strip s-maxage - Varnish has already used it
        set beresp.http.cache-control = regsub(beresp.http.cache-control, "s-maxage=[0-9]+\b","");
        # Strip extra commas
        set beresp.http.cache-control = regsub(beresp.http.cache-control, "(^,|,$|,,)", "");
}

# This just calls the above function at the appropriate time.
sub vcl_backend_response {
        call strip_smaxage;
}

# You can read more about control Varnish through headers at
# https://varnishfoo.info/chapter-2.html

Однако мне нужно разместить веб-сайт Drupal на том же сервере, поэтому я заменил файл default.vcl следующим содержимым:

vcl 4.0;

backend default {
    .host = "xx.xx.xx.xx";
    .port = "8080";
}

acl purge {
  "localhost";
  "127.0.0.1";
}

sub vcl_recv {


 # Check the incoming request type is "PURGE", not "GET" or "POST".
  if (req.method == "PURGE") {
    # Check if the IP is allowed.
    if (!client.ip ~ purge) {
      # Return error code 405 (Forbidden) when not.
      return (synth(405, "Not allowed."));
    }
    return (purge);
  }

# Do not cache these paths.
  if (req.url ~ "^/status\.php$" ||
      req.url ~ "^/update\.php" ||
      req.url ~ "^/install\.php" ||
      req.url ~ "^/apc\.php$" ||
      req.url ~ "^/admin" ||
      req.url ~ "^/admin/.*$" ||
      req.url ~ "^/user" ||
      req.url ~ "^/user/.*$" ||
      req.url ~ "^/users/.*$" ||
      req.url ~ "^/info/.*$" ||
      req.url ~ "^/flag/.*$" ||
      req.url ~ "^.*/ajax/.*$" ||
      req.url ~ "^.*/ahah/.*$" ||
      req.url ~ "^/system/files/.*$") {

    return (pass);
  }

 # Always cache the following file types for all users. This list of extensions
  # appears twice, once here and again in vcl_backend_response so make sure you edit both
  # and keep them equal.
  if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {
    unset req.http.Cookie;
  }

  # Remove all cookies that Drupal doesn't need to know about. We explicitly
  # list the ones that Drupal does need, the SESS and NO_CACHE. If, after
  # running this code we find that either of these two cookies remains, we
  # will pass as the page cannot be cached.
  if (req.http.Cookie) {
    # 1. Append a semi-colon to the front of the cookie string.
    # 2. Remove all spaces that appear after semi-colons.
    # 3. Match the cookies we want to keep, adding the space we removed
    #    previously back. (\1) is first matching group in the regsuball.
    # 4. Remove all other cookies, identifying them by the fact that they have
    #    no space after the preceding semi-colon.
    # 5. Remove all spaces and semi-colons from the beginning and end of the
    #    cookie string.
    set req.http.Cookie = ";" + req.http.Cookie;
    set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
    set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1=");
    set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

    if (req.http.Cookie == "") {
      # If there are no remaining cookies, remove the cookie header. If there
      # aren't any cookie headers, Varnish's default behavior will be to cache
      # the page.
      unset req.http.Cookie;
    }
    else {
      # If there is any cookies left (a session or NO_CACHE cookie), do not
      # cache the page. Pass it on to Apache directly.
      return (pass);
    }
  }


}

и он отлично работает для кэширования сайта Drupal, но ломает другой «обычный» веб-сайт, потому что он начинает менять цвета при каждом обновлении страницы на обоих портах 80 (Varnish cached) и 8080 (Apache) версиях.

Каким должно быть правильное содержимое файла default.vcl, чтобы охватить как Drupal-сайты, так и не-Drupal-сайты?

Пробуя разные комбинации, я обнаружил, что просто добавляя if (req.http.host == "non-drupal-site.com") { в sub vcl_recv раздел второго (Drupal) конфигурационного файла следующим образом:

sub vcl_recv {

 if (req.http.host == "non-drupal-site.com") {
        if (req.url !~ "^/user") {
                unset req.http.cookie;
        }
    }

работает нормально и дает желаемый эффект: страницы Drupal кэшируются правильно, но и цвета простого веб-сайта кешируются без изменений.