0

I would like to setup Varnish 2.1.5 rules to show content from another page in some cases, yet keep the original URL intact.

eg When user requests /page/a s/he will be shown /page/b instead, but still see the /page/a URL in the browser.

This specific use case I need it for gracefully handling 404 errors on translated pages. Im not sure how to send the request back through to vcl_recv

The as I understand, the lifecycle flow, and current logic looks like this:

sub vcl_recv {  
  if(req.http.cookie ~ "lang_pref") {
    # Redirect to Preferred Language
    error 999 "i18n cookie";
  }...

sub vcl_deliver {
  if (resp.status == 999 ) {
     set resp.status = 302;
     set resp.response = "Found";
  }... # more i18n logic

sub vcl_fetch {
  # Set Varnish error if backend cant find requested i18n page
  if (beresp.status == 404 && req.url ~ "^\/(en|fr|de)(\/.*)?$") {
    error 494;
  }...

sub vcl_error {
  # Double check i18n pages for English before 404
  if (obj.status == 494) {
    set obj.http.Location = "https://site/page/a";
    }
    set obj.status = 302;

    return(deliver);
  }

What I'm assuming, instead of set obj.http.Location "https://site/page/a";, I need to somehow send the request back to vcl_recv then use regsub().

How would I go about that?

Etienne Martin
  • 10,018
  • 3
  • 35
  • 47
Vinnie James
  • 5,763
  • 6
  • 43
  • 52

1 Answers1

2

Should be as easy as:

sub vcl_error {
    # Double check i18n pages for English before 404
    if (obj.status == 494 && req.url == "/page/a") {
        set req.url = "/page/b";
        return(restart);
    }
}
Danila Vershinin
  • 8,725
  • 2
  • 29
  • 35
  • Yes, that is what I am reading as well. However, it is a bit more complicated. Could you take a look at my revised question? How can I send the request back through the lifecycle from `vcl_error` back to `vcl_recv`? Or can I simply set `req.url` within `vcl_error` and call it a day? – Vinnie James Jul 10 '17 at 20:21
  • You will need to then ```return (restart)``` after "rewriting" the URL via Varnish. This will allow it to pass through ```vcl_recv```, etc. all over again. See updated answer. – Danila Vershinin Jul 10 '17 at 22:06
  • Yes, I believe that's what I was looking for. Thanks! – Vinnie James Jul 10 '17 at 22:17