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

Xeo*_*eos 11 http haproxy cors

由于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
Run Code Online (Sandbox Code Playgroud)

但是为了实现这一点,我需要在cors_headers后端指定至少一个实时服务器,该服务器仍将接收请求.

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

Xeo*_*eos 15

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

backend cors_headers
    errorfile 503 /path/to/custom/file.http
Run Code Online (Sandbox Code Playgroud)

所述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>
Run Code Online (Sandbox Code Playgroud)

这种"方法"有一些限制:

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

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

或设置Expires标题.

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


odo*_*ony 11

好消息,HAProxy 2.2 刚刚引入了“Native Response Generator”功能。它与http-request return指令一起工作,可用于提供静态文件或文本字符串,包括动态参数。目标是避免使用errorfile.

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

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 ""
Run Code Online (Sandbox Code Playgroud)

可以根据您的需要,使用基于请求标头或来源的子句将set-headerandhttp-request return设为条件if(请参阅文档以获取示例)。

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

http-request return status 200 content-type "text/plain" \
    lf-string "Hello, you are: %[src]"
Run Code Online (Sandbox Code Playgroud)