robsf
robsf

Reputation: 1733

Varnish vcl_hash to remove a parameter

I'm using Varnish 2.0.6 and I'm having trouble with finding good documentation to write the vcl_hash function.

I need to remove a few parameters from the URL of my API before caching. In particular a userid that is passed to track analytics but not to change the results.

URL: /api/browse?node=123&userid=3432432564363

I wrote this but it's not cleat to me if the vcl_hash function needs to end with 'hash' or 'return(hash)' or NOTHING and if I need to handle all the cases or just my special case. It's not clear to me if I'm overwriting method or I'm extending it.

I have:

sub vcl_hash {
  if (req.url ~ "^/api/browse") {
    set req.hash += regsuball(req.url,"&userid=([A-z0-9]+)","");
  } 
  hash;
}

Is it missing something?

Upvotes: 4

Views: 4111

Answers (2)

rudi
rudi

Reputation: 791

The following is a general solution that works for me (starting from varnish v4), to remove several unwanted parameters.

The list of parameters can be extended easily, as long as the value-regex matches: The value regex matches all URL-safe characters, so it should match for all URL-encoded parameters.

sub vcl_hash {
    # conditional replacement is faster then evaluating regexes all the time
    if (req.method == "GET" || req.method == "HEAD") {
        hash_data(regsuball(req.url, "(userid|sid|uid)=[%.-_~A-z0-9]+&?", ""));
    }
    else {
        hash_data(req.url);
    }
    hash_data(req.http.host);
    return (lookup);
}

Upvotes: 1

robsf
robsf

Reputation: 1733

I tested a few things, and this one seems to work:

sub vcl_hash {
  if (req.url ~ "^/api/browse") {
    set req.hash += regsuball(req.url,"&userid=([A-z0-9]+)","");
  } else {
    set req.hash += req.url;
  }
  set req.hash += req.http.host;
  hash;
}

So it looks like you also have to handle the default case when you rewrite vcl_hash.

Upvotes: 1

Related Questions