Skip to content

Instantly share code, notes, and snippets.

@section-io-gists
Last active April 23, 2018 02:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save section-io-gists/0596b0765194996048e279a072eab492 to your computer and use it in GitHub Desktop.
Save section-io-gists/0596b0765194996048e279a072eab492 to your computer and use it in GitHub Desktop.
Add fallback values to stdtime2integer functions.
#vcl 4.0;
# comment the following imports if imported elsewhere
import cookie;
import header;
import std;
import var;
sub vcl_synth {
if (resp.status == 837) {
set resp.status = 204;
return (deliver);
}
if (resp.status == 838) {
set resp.status = 403;
return (deliver);
}
}
sub vcl_recv {
if (req.method == "PUT" && req.url ~ "^/\.well-known/section-io/visitor-count/") {
if (req.http.Section-Visitor-Count-Secret != req.http.Section-Visitors-Expected-Secret) {
return (synth(838, "Forbidden"));
}
if (req.url ~ "^/\.well-known/section-io/visitor-count/set\?value=[0-9]+$") {
var.global_set(req.http.Host + "-visitor-count", regsuball(req.url, "[^0-9]", ""));
return (synth(837, "No Content"));
} else if (req.url ~ "^/\.well-known/section-io/visitor-count/threshold-reached\?value=[0-9]+$") {
set req.http.x-now-unix-string = std.time2integer(now, 0);
var.global_set(
req.http.Host + "-visitor-count-threshold-" + regsuball(req.url, "[^0-9]", "") + "-reached",
req.http.x-now-unix-string
);
unset req.http.x-now-unix-string;
return (synth(837, "No Content"));
}
}
if (req.http.Section-ResourceProxy) {
set req.http.Section-Visitors = "";
} else {
set req.http.Section-Visitors = var.global_get(req.http.Host + "-visitor-count");
}
cookie.parse(req.http.Cookie);
if (!cookie.get("sqshowmaintenance." + req.http.Section-Visitors-Version)) {
# no cookie yet, make a decision
if (req.http.Section-Visitors != "") {
if (std.integer(req.http.Section-Visitors, 0) > std.integer(req.http.Section-Visitors-Threshold, 0)) {
std.log("overflow:count-block");
set req.http.X-SQ-ShowMaintenance = "true-count";
return (synth(800, "Maintenance Page"));
} else {
std.log("overflow:count-allow");
set req.http.X-SQ-ShowMaintenance = "false";
# increment count if the site has recently reached the threshold
if (
std.time2integer(now, 0) < 300 +
std.integer(
var.global_get(req.http.Host + "-visitor-count-threshold-" + req.http.Section-Visitors-Threshold + "-reached"),
0
)
) {
set req.http.x-new-visitor-count = 1 + std.integer(var.global_get(req.http.Host + "-visitor-count"), 0);
var.global_set(
req.http.Host + "-visitor-count",
req.http.x-new-visitor-count
);
unset req.http.x-new-visitor-count;
}
}
} else {
set req.http.x-random-100 = std.random(1, 100);
set req.http.x-random-100 = regsub(req.http.x-random-100, "\..*$", ""); # remove fraction
if (std.integer(req.http.x-random-100, 1) <= std.integer(req.http.Section-Visitors-Fallback-Block-Percentage, 0)) {
# fallback to percentage when visitor count data is unavailable ...
std.log("overflow:percentage-block");
set req.http.X-SQ-ShowMaintenance = "true";
return (synth(800, "Maintenance Page"));
} else {
std.log("overflow:percentage-allow");
set req.http.X-SQ-ShowMaintenance = "false";
}
unset req.http.x-random-100;
}
} else {
# read the cookie, if true, show maintenance page, if false allow through
if (cookie.get("sqshowmaintenance." + req.http.Section-Visitors-Version) == "true") {
std.log("overflow:cookie-block");
return (synth(800, "Maintenance Page"));
} else {
std.log("overflow:cookie-allow");
}
}
}
sub vcl_deliver {
set resp.http.Section-Visitors = req.http.Section-Visitors;
# Set the maintenance page cookie
std.log("overflow:deliver-block");
if (req.http.X-SQ-ShowMaintenance) {
if (req.http.X-SQ-ShowMaintenance == "true-count") {
# visitors blocked due to exceeding the count threshold, get a shorter block cookie expiration
# so that they can be re-evaluated against the latest count sooner.
std.log("overflow:add-cookie-overflow-true");
header.append(
resp.http.Set-Cookie,
"sqshowmaintenance." +
req.http.Section-Visitors-Version +
"=true;Path=/; Expires=" +
cookie.format_rfc1123(now, 3m) +
";"
);
} else {
header.append(
resp.http.Set-Cookie,
"sqshowmaintenance." +
req.http.Section-Visitors-Version +
"=" +
req.http.X-SQ-ShowMaintenance +
";Path=/; Expires=" +
cookie.format_rfc1123(now, 1h) +
";"
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment