使用 Varnish 作为 Web 服务器

使用 Varnish 作为 Web 服务器

我正在寻找一种方法来配置 Varnish 以处理 Varnish 内的 HTTP 请求。

更具体地说,对于特定路径(例如在 */foo/** 下),我希望 Varnish 以 200 HTTP 状态代码和空(或固定消息)正文进行响应,而不是将请求转发到后端服务器。

答案1

我同意 Michael 对滥用/使用 vcl_error 的简短回应,并想在下面的示例代码中向您展示我们的意思。

为了滥用 vcl_error,我在这里使用了 HTTP 标准之外的错误代码并对此类错误实施了特殊处理。

VCL_RECV 中的示例:

sub vcl_recv {
  ...
  # respond HTTP 200 to /ping requests
  if (req.url ~ "^/ping") {
    error 700;
  }
  # return a 301 redirect
  if (req.url ~ "^/wrong-target") {
    error 751 "http://www.example.com/correct-target";
  }
}

VCL_ERROR中的示例:

sub vcl_error {
  # send response "Pong" (HTTP 200)
  if (obj.status == 700) {
    set obj.status = 200;
    set obj.response = "OK";
    set obj.http.Content-Type = "text/plain";
    synthetic {"Pong"};
    return (deliver);
  }
  # send empty response (HTTP 204)
  if (obj.status == 701) {
    set obj.status = 204;
    set obj.response = "No Content";
    synthetic {""};
    return (deliver);
  }
  # redirect 301
  if (obj.status == 751) {
    set obj.http.Location = obj.response;
    set obj.status = 301;
    set obj.response = "Moved Permanently";
    return (deliver);
  }
  # redirect 302
  if (obj.status == 752) {
    set obj.http.Location = obj.response;
    set obj.status = 302;
    set obj.response = "Found";
    return (deliver);
  }
  # Fall through to default behavior for all other exceptions
}

答案2

对于这个问题的未来读者,我将@jens-bradler 的 vcl 移植到了 Varnish 4。(Serverfault 不允许我将多行代码作为评论发布,因此我在这里发布作为另一个答案)

vcl 4.0;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_recv {
    if (req.url ~ "^/ping") {
        return (synth(700, "Ping"));
    }

    if (req.url ~ "^/wrong-target") {
        return (synth(751, "http://www.example.com/correct-target"));
    }
}

sub vcl_synth {
    set resp.http.Retry-After = "5";
    if (resp.status == 700) {
        set resp.status = 200;
        set resp.reason = "OK";
        set resp.http.Content-Type = "text/plain;";
        synthetic( {"Pong"} );
        return (deliver);
    }
    if (resp.status == 701) {
        set resp.status = 204;
        set resp.reason = "No Content";
        set resp.http.Content-Type = "text/plain;";
        synthetic( {""} );
        return (deliver);
    }
    if (resp.status == 751) {
        set resp.http.Location = resp.reason;
        set resp.status = 301;
        set resp.reason = "Moved Permanently";
        return (deliver);
    }

    if (resp.status == 752) {
        set resp.http.Location = resp.reason;
        set resp.status = 302;
        set resp.reason = "Found";
        return (deliver);
    }

    return (deliver);
}

sub vcl_backend_response {
    # Happens after we have read the response headers from the backend.
    #
    # Here you clean the response headers, removing silly Set-Cookie headers
    # and other mistakes your backend does.
}

sub vcl_deliver {
    # Happens when we have all the pieces we need, and are about to send the
    # response to the client.
    #
    # You can do accounting or modifying the final object here.
}

相关内容