# customers moving from CenturyLink to Fastly 
# don't need to reprogram their token generation scripts
# as Fastly is able to validate them as they are

declare local var.secret STRING;
declare local var.nva STRING;
declare local var.dirs STRING;
declare local var.hash STRING;
declare local var.path STRING;
declare local var.token STRING;
declare local var.expectedDirs INTEGER;
declare local var.expectedHash STRING;

# Store the secret hmac key value.  You may prefer to use a private
# edge dictionary to inject this value into your configuration
set var.secret = "THESECRET";

if (fastly.ff.visits_this_service == 0 && req.url.basename ~ "playlist.m3u8|manifest.mpd") {

  # Extract the token from the URL
  if (req.url.path ~ "/token=nva=(\d+)~dirs=(\d+)~hash=0([[:xdigit:]]{20})(/.*)") {
    set var.nva = re.group.1;
    set var.dirs = re.group.2;
    set var.hash = re.group.3;
    set var.path = re.group.4;
    log "nva=" + var.nva + "; dirs=" + var.dirs + "; hash=" + var.hash + "; path=" + var.path;
  } else {
    log "Missing 'token' in url path";
    error 600;
  }

  set var.token = var.path + "?nva=" + var.nva + "&dirs=" + var.dirs;
  log "token=" + var.token;

  # Validate the number of dirs
  set var.expectedDirs = std.strlen(regsuball(var.path, "[^/]",""));
  set var.expectedDirs -= 1;
  log "expectedDirs=" + var.expectedDirs;
  if (std.atoi(var.dirs) != var.expectedDirs) {
    error 601;
  }

  # Extract token expiration and signature
  if (digest.hmac_sha1(var.secret, var.token) ~ "0x(.{20})") {
    set var.expectedHash = re.group.1;
    log "expectedHash=" + var.expectedHash;
    if (var.expectedHash == var.hash) {
      # Check that expiration time has not elapsed
      if (time.is_after(now, std.integer2time(std.atoi(var.nva)))) {
        log "Token has expired";
        error 602;
      }
    } else {
      log "Token is incorrect, expected " var.expectedHash;
      error 603;
    }
  }

  # Remove the query strings from the URL before cache lookup, 
  # preventing the cache from fragmenting
  set req.url = "/resources" + querystring.remove(var.token);
  log "Token is good";
}