-
Notifications
You must be signed in to change notification settings - Fork 913
acl method misbehaves when multiple methods are defined #3060
Copy link
Copy link
Closed
Labels
status: works as designedThis issue stems from a misunderstanding of how HAProxy is supposed to work.This issue stems from a misunderstanding of how HAProxy is supposed to work.
Description
Detailed Description of the Problem
Let's say we have the following acl definition:
acl acl1 path -m beg /one/ -m str /one
It should match all the requests coming to /one/<,,,> and /one exactly, and nothing else. However in this case str method stops working as an exact match and request to /onetwothree/oopsie still matches this ACL!
If I swap methods, subpaths of /one/ stop working:
acl acl1 path -m str /one -m beg /one/
Expected Behavior
Only requests to /one and /one/ subpaths work.
Steps to Reproduce the Behavior
haproxy.conf: see below.
Docker-compose.yml:
services:
haproxy:
image: haproxy:3.2.3
container_name: haproxy
ports:
- "80:80"
- "443:443"
- "8404:8404"
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
restart: unless-stoppedand curl command:
curl http://localhost/onetwothree/oopsieDo you have any idea what may have caused this?
Using multiple methods doesn't seem to be well documented. There's some evidence only last one should work, but that's not true.
Do you have an idea how to solve the issue?
No response
What is your configuration?
global
log stdout format raw daemon
defaults
log global
mode http
option httplog
option http-server-close
timeout connect 5s
timeout client 30s
timeout server 30s
frontend http
bind *:80
mode http
# acl acl1 path -m str /one -m beg /one/
acl acl1 path -m beg /one/ -m str /one
acl acl2 path -m beg /onetwo/ -m str /onetwo
# acl acl1 path -m beg /one/
# acl acl2 path -m beg /onetwo/
# acl acl1 path -m str /one
# acl acl2 path -m str /onetwo
# acl acl3 path -m beg /three/ -m str /tri
acl acl3 path -m str /tri -m beg /three/
# acl acl3 path -m str /tri
use_backend backend1 if acl1
use_backend backend2 if acl2
use_backend backend3 if acl3
backend backend1
mode http
http-request return status 200 content-type "text/plain" string "Hello from backend ONE\n"
backend backend2
mode http
http-request return status 200 content-type "text/plain" string "Hello from backend ONETWO\n"
backend backend3
mode http
http-request return status 200 content-type "text/plain" string "Hello from backend 3\n"Output of haproxy -vv
HAProxy version 3.2.3-1844da7 2025/07/09 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2030.
Known bugs: http://www.haproxy.org/bugs/bugs-3.2.3.html
Running on: Linux 6.14.10-orbstack-00291-g1b252bd3edea #1 SMP Sat Jun 7 02:45:18 UTC 2025 aarch64
Build options :
TARGET = linux-glibc
CC = cc
CFLAGS = -O2 -g -fwrapv
OPTIONS = USE_GETADDRINFO=1 USE_OPENSSL=1 USE_LUA=1 USE_PROMEX=1 USE_PCRE2=1 USE_PCRE2_JIT=1
DEBUG =
Feature list : -51DEGREES +ACCEPT4 +BACKTRACE -CLOSEFROM +CPU_AFFINITY +CRYPT_H -DEVICEATLAS +DL -ENGINE +EPOLL -EVPORTS +GETADDRINFO -KQUEUE -LIBATOMIC +LIBCRYPT +LINUX_CAP +LINUX_SPLICE +LINUX_TPROXY +LUA +MATH -MEMORY_PROFILING +NETFILTER +NS -OBSOLETE_LINKER +OPENSSL -OPENSSL_AWSLC -OPENSSL_WOLFSSL -OT -PCRE +PCRE2 +PCRE2_JIT -PCRE_JIT +POLL +PRCTL -PROCCTL +PROMEX -PTHREAD_EMULATION -QUIC -QUIC_OPENSSL_COMPAT +RT +SLZ +SSL -STATIC_PCRE -STATIC_PCRE2 +TFO +THREAD +THREAD_DUMP +TPROXY -WURFL -ZLIB
Default settings :
bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with multi-threading support (MAX_TGROUPS=32, MAX_THREADS=1024, default=8).
Built with SSL library version : OpenSSL 3.0.16 11 Feb 2025
Running on SSL library version : OpenSSL 3.0.16 11 Feb 2025
SSL library supports TLS extensions : yes
SSL library supports SNI : yes
SSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
OpenSSL providers loaded : default
Built with Lua version : Lua 5.4.4
Built with the Prometheus exporter as a service
Built with network namespace support.
Built with libslz for stateless compression.
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with PCRE2 version : 10.42 2022-12-11
PCRE2 library supports JIT : yes
Encrypted password support via crypt(3): yes
Built with gcc compiler version 12.2.0
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
h2 : mode=HTTP side=FE|BE mux=H2 flags=HTX|HOL_RISK|NO_UPG
<default> : mode=HTTP side=FE|BE mux=H1 flags=HTX
h1 : mode=HTTP side=FE|BE mux=H1 flags=HTX|NO_UPG
fcgi : mode=HTTP side=BE mux=FCGI flags=HTX|HOL_RISK|NO_UPG
<default> : mode=SPOP side=BE mux=SPOP flags=HOL_RISK|NO_UPG
spop : mode=SPOP side=BE mux=SPOP flags=HOL_RISK|NO_UPG
<default> : mode=TCP side=FE|BE mux=PASS flags=
none : mode=TCP side=FE|BE mux=PASS flags=NO_UPG
Available services : prometheus-exporter
Available filters :
[BWLIM] bwlim-in
[BWLIM] bwlim-out
[CACHE] cache
[COMP] compression
[FCGI] fcgi-app
[SPOE] spoe
[TRACE] trace
Last Outputs and Backtraces
Additional Information
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
status: works as designedThis issue stems from a misunderstanding of how HAProxy is supposed to work.This issue stems from a misunderstanding of how HAProxy is supposed to work.