Varnish: Кастомная страница с ошибкой

Date October 19th, 2012 Author Vitaly Agapov

— Они ненавидят меня, потому что я лучше их.
— Нет, они ненавидят тебя потому, что ты ведёшь себя так, как будто считаешь себя лучше их.

Джордж Р. Мартин «Игра Престолов»

 

По умолчанию в случае возникновения каких-либо ошибок Varnish выдаёт классическое окно с сакраментальной фразой "Service Unavailable. Guru Meditation". Все это, конечно, интересно. Особенно интересна история этой фразы, берущей начало из операционки AmigaOS, в которую она попала из одной из амиговских игр под контроллер Joyboard. Суть этой игры заключалась в том, чтобы как можно дольше сидеть в позе лотоса и не шевелиться. Если же игрок шевелился, то возникала ошибка "Guru Meditation Error". В общем, можно с уверенностью сказать, что разработчики и пользователи Amiga познали-таки дзен. Завидую.

Однако в production-среде совсем не хочется, чтобы пользователи видели подобные сбивающие с толку сообщения.

Само собой, можно подредактировать дефолтную функцию vcl_error в конфиге Varnish и прописать там свою собственную html-вёрстку вроде такой:

 
sub vcl_error {
    set obj.http.Content-Type = "text/html; charset=utf-8";
    set obj.http.Retry-After = "5";
    synthetic {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <title>My Error</title>
  </head>
  <body>
    <h1>Oops</h1>
    <p>Error occured</p>
    <h3>Sorry</h3>
  </body>
</html>
"};
    return (deliver);
}

Но это не очень удобно (точнее – очень не удобно), если у нас есть нормальная большая свёрстанная заглушка. В конфиге её держать неправильно, править неудобно, а использовать совместно, скажем, с тем же Apache так и вообще невозможно.

На помощь придёт модуль std (речь о Varnish версии 3 и старше) и метод std.fileread, которым можно считать файл с диска, а потом отдать его уже synthetic'у:

 
import std;
sub vcl_error {
  if ( obj.status >= 500 && obj.status <= 505) {
      set obj.http.Content-Type = "text/html; charset=utf-8";
        set obj.http.error50x = std.fileread("/var/www/site-closed/index.html");
        synthetic obj.http.error50x;
        unset obj.http.error50x;
        return(deliver);
  }
}

Есть ещё способ считать файл inline'овым кодом на C. Но этот метод дик, ужасен и костылен. В Гугле можно найти.

Tags:
Category: Varnish | No comments »

Comments

Leave a comment

 Comment Form