if (
fastly.ff.visits_this_service == 0 &&
req.restarts == 0
) {
unset ;
if (waitingroom_config_enabled()) {
declare local var.logger_prefix STRING = "syslog " + req.service_id + " " + table.lookup(waitingroom_config, "logger_name") + " :: [WAITINGROOM] ";
declare local var.authed_user_id STRING = client.ip;
set var.authed_user_id = ;
declare local var.percentage INTEGER = waitingroom_config_allow_percentage();
declare local var.decision STRING;
declare local var.set_cookie BOOL = true;
if (var.percentage >= 100) {
set var.decision = "allow";
} else if (!:waiting_room) {
set var.decision = "wait";
} else {
declare local var.request_cookie_decoded STRING = digest.base64_decode(:waiting_room);
declare local var.request_cookie_expires INTEGER = std.atoi(subfield(var.request_cookie_decoded, "exp", "&"));
declare local var.request_cookie_signature STRING = subfield(var.request_cookie_decoded, "sig", "&");
declare local var.request_cookie_key_id STRING = subfield(var.request_cookie_decoded, "kid", "&");
declare local var.request_cookie_user_id STRING = subfield(var.request_cookie_decoded, "uid", "&");
declare local var.request_cookie_decision STRING = subfield(var.request_cookie_decoded, "dec", "&");
if (var.request_cookie_user_id != var.authed_user_id) {
set var.decision = "wait";
log var.logger_prefix + "User " + var.authed_user_id + " denied while using a token generated for user " + var.request_cookie_user_id;
} else if (!table.lookup(waitingroom_signingkeys, var.request_cookie_key_id)) {
set var.decision = "wait";
log var.logger_prefix + "Unable to check signature due to missing key " + var.request_cookie_key_id;
} else {
declare local var.request_cookie_string_to_sign STRING = "dec=" + var.request_cookie_decision + "&exp=" + var.request_cookie_expires + "&uid=" + var.request_cookie_user_id + "&kid=" + var.request_cookie_key_id;
declare local var.calculated_signature STRING = digest.hmac_sha256(table.lookup(waitingroom_signingkeys, var.request_cookie_key_id), var.request_cookie_string_to_sign);
if (digest.secure_is_equal(var.request_cookie_signature, var.calculated_signature)) {
set var.decision = var.request_cookie_decision;
set var.set_cookie = false;
} else {
set var.decision = "wait";
}
}
if (time.is_after(now, std.integer2time(var.request_cookie_expires))) {
if (var.decision == "allow") {
log var.logger_prefix + "Expired allow token reverted to wait";
set var.decision = "wait";
set var.set_cookie = true;
} else if (var.decision == "wait") {
declare local var.seed INTEGER = std.strtol(substr(var.request_cookie_signature, 0, 8), 16);
set var.decision = if (randombool_seeded(var.percentage, 100, var.seed), "allow", "re-wait");
set var.set_cookie = true;
}
}
}
log var.logger_prefix + "Waiting room state: " + var.decision;
if (var.set_cookie) {
declare local var.expires INTEGER = now;
if (var.decision == "allow") {
set var.expires += waitingroom_config_allow_period_timeout();
} else {
declare local var.duration INTEGER = waitingroom_config_wait_period_duration();
set var.expires += var.duration;
set var.expires += randomint(0, var.duration);
}
declare local var.key_id STRING = table.lookup(waitingroom_config, "active_key", "key1");
declare local var.string_to_sign STRING = "dec=" + if (var.decision == "allow", "allow", "wait") + "&exp=" + var.expires + "&uid=" + var.authed_user_id + "&kid=" + var.key_id;
declare local var.signature STRING = digest.hmac_sha256(table.lookup(waitingroom_signingkeys, var.key_id), var.string_to_sign);
set = "waiting_room=" + digest.base64(var.string_to_sign + "&sig=" + var.signature) + "; path=/; max-age=" + table.lookup(waitingroom_config, "cookie_lifetime", "7200") + "; domain=" + table.lookup(waitingroom_config, "cookie_domain", ) + "; secure; HttpOnly";
}
if (var.decision == "wait") {
error 718 "waitingroom:startwaiting";
} else if (var.decision == "re-wait") {
error 718 "waitingroom:keepwaiting";
}
}
}