HAProxy community

CORS configuration is not working on HAProxy. How to enable it properly?

I’m running HAproxy as a proxy for backend APIs on Docker Swarm. Haproxy config supports CORS, but when I try to access one of the API endpoints, it results in the following error:

"Access to XMLHttpRequest at ‘http://10.110.9.101:8080/api-customer1/v1/list’ from origin ‘http://localhost:4201’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status."

When I try to access the same API endpoint by Postman or by disabling CORS on the browser, the API is reachable and retrieves expected data.

Dockerfile:

FROM 10.110.9.100/haproxy:2.0-alpine COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg

RUN ln -sf /dev/stdout /var/log/haproxy.log

haproxy.cfg

global
    maxconn 2046
    log 127.0.0.1 local0  debug
defaults
    log global
    mode    http
    option httpclose
    option httplog
    option dontlognull
    retries 3
    timeout connect  20s
    timeout client  3m
    timeout server  20m

frontend http-in
    bind *:80
    acl api-customer1 path_beg /api-customer1
    acl api-customer2 path_beg /api-customer2
    acl api-customer3 path_beg /api-customer3
    acl api-docs path_beg /api-docs
    mode http
    option httplog
    use_backend customer1-backend if api-customer1
    use_backend customer2-backend if api-customer2
    use_backend customer3-backend if api-customer3
    use_backend docs-backend if api-docs
    default_backend default-backend
    timeout client 30m

    Add CORS headers when Origin header is present
    capture request header origin len 128
    http-response add-header Access-Control-Allow-Origin '*'
    http-response add-header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS, POST, PUT, DELETE'
    http-response add-header Access-Control-Allow-Credentials true
    http-response add-header Access-Control-Allow-Headers 'Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, APP-SESSION'

backend customer2-backend
    http-request set-header Orig-Path /api-customer2/
    http-request set-header X-Script-Path /api-customer2/
    reqirep ^([^\ :]*)\ /api-customer2/(.*)  \1\ /\2
    server customer2-balancer api-customer2-v2:8080

backend customer1-backend
    http-request set-header Orig-Path /api-customer1/
    http-request set-header X-Script-Path /api-customer1/
    reqirep ^([^\ :]*)\ /api-customer1/(.*)  \1\ /\2
    server customer1-balancer api-customer1-v2:8080

backend customer3-backend
    http-request set-header Orig-Path /api-customer3/
    http-request set-header X-Script-Path /api-customer3/
    reqirep ^([^\ :]*)\ /api-customer3/(.*)  \1\ /\2
    server customer3-balancer api-customer3-v2:8080

backend docs-backend
    http-request set-header Orig-Path /api-docs/
    http-request set-header X-Script-Path /api-docs/
    reqirep ^([^\ :]*)\ /api-docs/(.*)  \1\ /\2
    server docs-balancer api-docs:7070/docs

backend default-backend
    http-request deny deny_status 400

Docker swarm services:

user@node:~$ docker service ls
ID                  NAME                    MODE                REPLICAS            IMAGE                                              PORTS
s35d89o1n078        api-customer3-v2        replicated          1/1                 10.110.9.100/api-v2:latest
98h25nxy8pe0        api-docs                replicated          1/1                 10.110.9.100/api-docs:latest
wthb7i2s306k        api-customer2-v2        replicated          1/1                 10.110.9.100/api-v2:latest
46t89abwcada        api-customer1-v2        replicated          1/1                 10.110.9.100/api-v2:latest
kvuwekfdbnwe        haproxy                 replicated          1/1                 10.110.9.100/maxx-proxy-api:latest                 *:8080->80/tcp