如何在不将请求传递给Web服务器的情况下使用HAProxy发送响应

时间:2014-10-24 21:52:37

标签: http cors haproxy

由于 CORS (跨域资源共享),服务器正在接收数千个 OPTIONS 请求。现在,每个选项请求都被发送到其中一个服务器,这有点浪费,因为HAProxy可以在没有Web服务器帮助的情况下自行添加 CORS 标头。

frontend https-in
    ...
    use_backend cors_headers if METH_OPTIONS
    ...

backend cors_headers
    rspadd Access-Control-Allow-Origin:\ https://www.example.com
    rspadd Access-Control-Max-Age:\ 31536000

但要实现此目的,我需要在 cors_headers 后端指定至少一个实时服务器,该服务器仍会收到请求。

如何在不指定任何服务器的情况下处理后端中的请求?如何将请求传播到服务器,同时将响应发送到浏览器并保持连接活动?

2 个答案:

答案 0 :(得分:13)

执行此操作的唯一方法是在HAProxy 1.5.14中手动触发503错误(没有可用于处理请求的服务器)并将错误页面设置为具有自定义CORS标头的文件。

backend cors_headers
    errorfile 503 /path/to/custom/file.http

file.http应包含所需的标题,并在末尾包含2个空行

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Max-Age: 31536000
Content-Length: 0
Cache-Control: private


<REMOVE THIS LINE COMPLETELY>

这种“方法”有一些限制:

  • 在发送CORS标头之前无法检查原点,因此您必须拥有允许来源的静态列表,否则您将不得不允许所有来源
  • 缺少动态标题:你做不到

    http-response set-header Date%[date(),http_date]

或设置Expires标题。

注意:如果您要动态更新HTTP文件,要将更改应用于HAProxy,您必须重新启动它。它可以是正常重启或硬重启,在任何一种情况下都会立即加载,缓存和提供新文件。

答案 1 :(得分:6)

好消息,HAProxy 2.2 just introduced是“本机响应生成器”功能。它与http-request return指令一起使用,可用于提供静态文件或文本字符串,包括动态参数。 目的是避免使用urlpatterns进行常见的黑客攻击。

利用版本2.2(http-after-response)中引入的另一条指令,可以通过以下方式实现OP目标:

errorfile

backend cors_headers # http-response won't work here as the response is generated by HAP http-after-response set-header Access-Control-Allow-Origin \ "%[req.hdr(Origin)]" http-after-response set-header Access-Control-Max-Age "31536000" http-request return status 200 content-type "text/plain" string "" set-header可以使用http-request return子句作为条件,该子句基于请求标头或源,具体取决于您的需求(有关示例,请参见文档)。

通过这种技术,标题和响应可以使用变量:

if