201 lines
5.4 KiB
Plaintext
201 lines
5.4 KiB
Plaintext
/*-
|
|
* Copyright (c) 2006 Verdens Gang AS
|
|
* Copyright (c) 2006-2015 Varnish Software AS
|
|
* All rights reserved.
|
|
*
|
|
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* This is the builtin VCL code
|
|
*/
|
|
|
|
vcl 4.0;
|
|
|
|
#######################################################################
|
|
# Client side
|
|
|
|
sub vcl_recv {
|
|
if (req.method == "PRI") {
|
|
/* This will never happen in properly formed traffic (see: RFC7540) */
|
|
return (synth(405));
|
|
}
|
|
if (!req.http.host &&
|
|
req.esi_level == 0 &&
|
|
req.proto ~ "^(?i)HTTP/1.1") {
|
|
/* In HTTP/1.1, Host is required. */
|
|
return (synth(400));
|
|
}
|
|
if (req.method != "GET" &&
|
|
req.method != "HEAD" &&
|
|
req.method != "PUT" &&
|
|
req.method != "POST" &&
|
|
req.method != "TRACE" &&
|
|
req.method != "OPTIONS" &&
|
|
req.method != "DELETE" &&
|
|
req.method != "PATCH") {
|
|
/* Non-RFC2616 or CONNECT which is weird. */
|
|
return (pipe);
|
|
}
|
|
|
|
if (req.method != "GET" && req.method != "HEAD") {
|
|
/* We only deal with GET and HEAD by default */
|
|
return (pass);
|
|
}
|
|
if (req.http.Authorization || req.http.Cookie) {
|
|
/* Not cacheable by default */
|
|
return (pass);
|
|
}
|
|
return (hash);
|
|
}
|
|
|
|
sub vcl_pipe {
|
|
# By default Connection: close is set on all piped requests, to stop
|
|
# connection reuse from sending future requests directly to the
|
|
# (potentially) wrong backend. If you do want this to happen, you can undo
|
|
# it here.
|
|
# unset bereq.http.connection;
|
|
return (pipe);
|
|
}
|
|
|
|
sub vcl_pass {
|
|
return (fetch);
|
|
}
|
|
|
|
sub vcl_hash {
|
|
hash_data(req.url);
|
|
if (req.http.host) {
|
|
hash_data(req.http.host);
|
|
} else {
|
|
hash_data(server.ip);
|
|
}
|
|
return (lookup);
|
|
}
|
|
|
|
sub vcl_purge {
|
|
return (synth(200, "Purged"));
|
|
}
|
|
|
|
sub vcl_hit {
|
|
if (obj.ttl >= 0s) {
|
|
// A pure unadulterated hit, deliver it
|
|
return (deliver);
|
|
}
|
|
if (obj.ttl + obj.grace > 0s) {
|
|
// Object is in grace, deliver it
|
|
// Automatically triggers a background fetch
|
|
return (deliver);
|
|
}
|
|
// fetch & deliver once we get the result
|
|
return (miss);
|
|
}
|
|
|
|
sub vcl_miss {
|
|
return (fetch);
|
|
}
|
|
|
|
sub vcl_deliver {
|
|
return (deliver);
|
|
}
|
|
|
|
/*
|
|
* We can come here "invisibly" with the following errors: 500 & 503
|
|
*/
|
|
sub vcl_synth {
|
|
set resp.http.Content-Type = "text/html; charset=utf-8";
|
|
set resp.http.Retry-After = "5";
|
|
set resp.body = {"<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>"} + resp.status + " " + resp.reason + {"</title>
|
|
</head>
|
|
<body>
|
|
<h1>Error "} + resp.status + " " + resp.reason + {"</h1>
|
|
<p>"} + resp.reason + {"</p>
|
|
<h3>Guru Meditation:</h3>
|
|
<p>XID: "} + req.xid + {"</p>
|
|
<hr>
|
|
<p>Varnish cache server</p>
|
|
</body>
|
|
</html>
|
|
"};
|
|
return (deliver);
|
|
}
|
|
|
|
#######################################################################
|
|
# Backend Fetch
|
|
|
|
sub vcl_backend_fetch {
|
|
if (bereq.method == "GET") {
|
|
unset bereq.body;
|
|
}
|
|
return (fetch);
|
|
}
|
|
|
|
sub vcl_backend_response {
|
|
if (bereq.uncacheable) {
|
|
return (deliver);
|
|
} else if (beresp.ttl <= 0s ||
|
|
beresp.http.Set-Cookie ||
|
|
beresp.http.Surrogate-control ~ "no-store" ||
|
|
(!beresp.http.Surrogate-Control &&
|
|
beresp.http.Cache-Control ~ "no-cache|no-store|private") ||
|
|
beresp.http.Vary == "*") {
|
|
# Mark as "Hit-For-Miss" for the next 2 minutes
|
|
set beresp.ttl = 120s;
|
|
set beresp.uncacheable = true;
|
|
}
|
|
return (deliver);
|
|
}
|
|
|
|
sub vcl_backend_error {
|
|
set beresp.http.Content-Type = "text/html; charset=utf-8";
|
|
set beresp.http.Retry-After = "5";
|
|
set beresp.body = {"<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>"} + beresp.status + " " + beresp.reason + {"</title>
|
|
</head>
|
|
<body>
|
|
<h1>Error "} + beresp.status + " " + beresp.reason + {"</h1>
|
|
<p>"} + beresp.reason + {"</p>
|
|
<h3>Guru Meditation:</h3>
|
|
<p>XID: "} + bereq.xid + {"</p>
|
|
<hr>
|
|
<p>Varnish cache server</p>
|
|
</body>
|
|
</html>
|
|
"};
|
|
return (deliver);
|
|
}
|
|
|
|
#######################################################################
|
|
# Housekeeping
|
|
|
|
sub vcl_init {
|
|
return (ok);
|
|
}
|
|
|
|
sub vcl_fini {
|
|
return (ok);
|
|
}
|