4

Is there any way to send back custom responses from varnish itself?

if (req.url ~ "^/hello") {
  return "hello world";
}
Vlad the Impala
  • 15,572
  • 16
  • 81
  • 124

2 Answers2

11

You would do this with a synthetic response. For example:

sub vcl_recv {
  if (req.url ~ "^/hello") {
    error 700 "OK";
  }
}

sub vcl_error {
  if (obj.status == 700) {
    set obj.http.Content-Type = "text/html; charset=utf-8";
    set obj.status = 200;
    synthetic {"
     <html>
       <head>
          <title>Hello!</title>
       </head>
       <body>
          <h1>Hello world!</h1>
       </body>
     </html>
    "};
  }
}
Ketola
  • 2,767
  • 18
  • 21
  • 1
    You should really do `return (deliver);` at the end of the if block as otherwise it will drop through to the next bit of code (if you have some). Also you might want to use a name as well as a status code for readability. https://support.fastly.com/hc/en-us/community/posts/360040168631-How-Does-vcl-error-Work- – Daniel Worthington-Bodart Jul 11 '19 at 11:41
7

I think the preferred way to do this in Varnish 4 via the vcl_synth subroutine:

sub vcl_recv {
    if (req.url ~ "^/hello") {
        # We set a status of 750 and use the synth subroutine
        return (synth(750));
    }
}

sub vcl_synth {
    if (resp.status == 750) {
        # Set a status the client will understand
        set resp.status = 200;
        # Create our synthetic response
        synthetic("hello world");
        return(deliver);
    }
}

There's some more info about the built-in subroutines at:

http://book.varnish-software.com/4.0/chapters/VCL_Built_in_Subroutines.html#vcl-vcl-synth

Ross Motley
  • 210
  • 3
  • 5