The server is receiving thousands of OPTIONS requests due to CORS (Cross-Origin Resource Sharing). Right now, every options request is being sent to one of the servers, which is a bit wasteful, knowing that HAProxy can add the CORS headers itself without the help of a web server.
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
However for this to work I need to specify at least one live server in cors_headers backend and that server will still receive the requests.
How can I handle the request in the backend without specifying any servers? How can I stop the propagation of the request to servers, while sending the response to the browser and keeping the connection alive?
Good news, HAProxy 2.2 just introduced the "Native Response Generator" feature. It works with the http-request return
directive, and can be used for serving static files or text strings, including dynamic parameters.
The goal is to avoid the usual hacks with errorfile
.
Taking advantage of another directive introduced in version 2.2 (http-after-response
), the OP goal could be achieved with the following:
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 "" if TRUE
The set-header
and http-request return
can be made conditional with an if
clause based on the request headers or origin, depending on your needs (see the doc for examples).
With this technique the headers and response can use variables:
http-request return status 200 content-type "text/plain" \
lf-string "Hello, you are: %[src]"