Я ищу способ настроить Varnish для обработки HTTP-запросов в Varnish.
В частности, для определенных путей (скажем, в * / foo / **) я хочу, чтобы Varnish отвечал кодом состояния HTTP 200 и пустым (или фиксированным) телом сообщения, а не перенаправлял запросы на внутренние серверы.
Я согласен с кратким ответом Майкла на злоупотребление / использование vcl_error для этой цели и хочу показать вам, что мы имели в виду в приведенном ниже примере кода.
Чтобы злоупотребить vcl_error, я использовал здесь коды ошибок, выходящие за рамки стандарта HTTP, и реализовал специальную обработку для такого рода ошибок.
Пример в VCL_RECV:
sub vcl_recv {
...
# respond HTTP 200 to /ping requests
if (req.url ~ "^/ping") {
error 700;
}
# return a 301 redirect
if (req.url ~ "^/wrong-target") {
error 751 "http://www.example.com/correct-target";
}
}
Пример в VCL_ERROR:
sub vcl_error {
# send response "Pong" (HTTP 200)
if (obj.status == 700) {
set obj.status = 200;
set obj.response = "OK";
set obj.http.Content-Type = "text/plain";
synthetic {"Pong"};
return (deliver);
}
# send empty response (HTTP 204)
if (obj.status == 701) {
set obj.status = 204;
set obj.response = "No Content";
synthetic {""};
return (deliver);
}
# redirect 301
if (obj.status == 751) {
set obj.http.Location = obj.response;
set obj.status = 301;
set obj.response = "Moved Permanently";
return (deliver);
}
# redirect 302
if (obj.status == 752) {
set obj.http.Location = obj.response;
set obj.status = 302;
set obj.response = "Found";
return (deliver);
}
# Fall through to default behavior for all other exceptions
}
Для будущих читателей этого вопроса я портировал vcl @ jens-bradler на Varnish 4. (Serverfault не позволяет мне публиковать многострочный код в качестве комментариев, поэтому я публикую здесь как другой ответ)
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
if (req.url ~ "^/ping") {
return (synth(700, "Ping"));
}
if (req.url ~ "^/wrong-target") {
return (synth(751, "http://www.example.com/correct-target"));
}
}
sub vcl_synth {
set resp.http.Retry-After = "5";
if (resp.status == 700) {
set resp.status = 200;
set resp.reason = "OK";
set resp.http.Content-Type = "text/plain;";
synthetic( {"Pong"} );
return (deliver);
}
if (resp.status == 701) {
set resp.status = 204;
set resp.reason = "No Content";
set resp.http.Content-Type = "text/plain;";
synthetic( {""} );
return (deliver);
}
if (resp.status == 751) {
set resp.http.Location = resp.reason;
set resp.status = 301;
set resp.reason = "Moved Permanently";
return (deliver);
}
if (resp.status == 752) {
set resp.http.Location = resp.reason;
set resp.status = 302;
set resp.reason = "Found";
return (deliver);
}
return (deliver);
}
sub vcl_backend_response {
# Happens after we have read the response headers from the backend.
#
# Here you clean the response headers, removing silly Set-Cookie headers
# and other mistakes your backend does.
}
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
}