Hello,
when testing with HTTP/2 we found a behaviour, we did not expect:
we use switching between different backends by use of a map file, e.g.:
use_backend %[url,map_beg(/etc/haproxy/pool.map,defaultbackend)]
With HTTP/1.1 this works fine in haproxy.
But with HTTP/2, it does not work.
Here's a minimal configuration file to reproduce this:
----------------------------------------------------
global
log /dev/log local0 warning
# log /dev/log local0
# log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd
listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See:
https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites
TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
# option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
backend defaultbackend
log global
mode http
http-response set-header X-Info "defaultbackend : %s"
server default_1 127.0.0.1:81
backend backend_2
log global
mode http
http-response set-header X-Info "backend_2 : %s"
server default_2 127.0.0.1:81
backend backend_3
log global
mode http
http-response set-header X-Info "backend_3 : %s"
server default_3 127.0.0.1:81
frontend ssl
log global
mode http
option httplog
bind *:443 alpn h2,http/1.1 ssl crt /etc/haproxy/x.pem
acl is_path_3 path_beg /3
use_backend backend_3 if is_path_3
use_backend %[url,map_beg(/etc/haproxy/pool.map,defaultbackend)]
default_backend defaultbackend
----------------------------------------------------
Content of /etc/haproxy/pool.map is:
/2 backend_2
----------------------------------------------------
HAProxy Version:
haproxy -vvv
HAProxy version 2.5.5-1ppa1~focal 2022/03/14 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2023.
Known bugs: http://www.haproxy.org/bugs/bugs-2.5.5.html
Running on: Linux 5.4.0-104-generic #118-Ubuntu SMP Wed Mar 2 19:02:41 UTC 2022
x86_64
Build options :
TARGET = linux-glibc
CPU = generic
CC = cc
CFLAGS = -O2 -g -O2 -fdebug-prefix-map=/build/haproxy-d3zlWl/haproxy-2.5.5=.
-fstack-protector-strong -Wformat -Werror=format-security -Wdate-time
-D_FORTIFY_SOURCE=2 -Wall -Wextra -Wundef -Wdeclaration-after-statement -fwrapv
-Wno-address-of-packed-member -Wno-unused-label -Wno-sign-compare
-Wno-unused-parameter -Wno-clobbered -Wno-missing-field-initializers
-Wno-cast-function-type -Wtype-limits -Wshift-negative-value -Wshift-overflow=2
-Wduplicated-cond -Wnull-dereference
OPTIONS = USE_PCRE2=1 USE_PCRE2_JIT=1 USE_OPENSSL=1 USE_LUA=1 USE_SLZ=1
USE_SYSTEMD=1 USE_PROMEX=1
DEBUG =
Feature list : +EPOLL -KQUEUE +NETFILTER -PCRE -PCRE_JIT +PCRE2 +PCRE2_JIT
+POLL +THREAD +BACKTRACE -STATIC_PCRE -STATIC_PCRE2 +TPROXY +LINUX_TPROXY
+LINUX_SPLICE +LIBCRYPT +CRYPT_H +GETADDRINFO +OPENSSL +LUA +ACCEPT4 -CLOSEFROM
-ZLIB +SLZ +CPU_AFFINITY +TFO +NS +DL +RT -DEVICEATLAS -51DEGREES -WURFL
+SYSTEMD -OBSOLETE_LINKER +PRCTL -PROCCTL +THREAD_DUMP -EVPORTS -OT -QUIC
+PROMEX -MEMORY_PROFILING
Default settings :
bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with multi-threading support (MAX_THREADS=64, default=1).
Built with OpenSSL version : OpenSSL 1.1.1f 31 Mar 2020
Running on OpenSSL version : OpenSSL 1.1.1f 31 Mar 2020
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
Built with Lua version : Lua 5.3.3
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")
Support for malloc_trim() is enabled.
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT
IP_FREEBIND
Built with PCRE2 version : 10.34 2019-11-21
PCRE2 library supports JIT : yes
Encrypted password support via crypt(3): yes
Built with gcc compiler version 9.4.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|CLEAN_ABRT|HOL_RISK|NO_UPG
fcgi : mode=HTTP side=BE mux=FCGI
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
<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 :
[SPOE] spoe
[CACHE] cache
[FCGI] fcgi-app
[COMP] compression
[TRACE] trace
----------------------------------------------------
We set response-header "X-Info", to see which backend is chosen.
When we use http/1.1 everything works fine:
root@ubuntu2004:/etc/haproxy# curl --http1.1 -kv https://127.0.0.1/x
...
< HTTP/1.1 200 OK
< date: Wed, 30 Mar 2022 12:05:21 GMT
< server: Apache/2.4.41 (Ubuntu)
< last-modified: Wed, 30 Mar 2022 11:25:27 GMT
< etag: "5-5db6dcd63b259"
< accept-ranges: bytes
< content-length: 5
< x-info: defaultbackend : default_1 <--default backend OK
<
test
* Connection #0 to host 127.0.0.1 left intact
root@ubuntu2004:/etc/haproxy# curl --http1.1 -kv https://127.0.0.1/2/x
...
< HTTP/1.1 200 OK
< date: Wed, 30 Mar 2022 12:05:24 GMT
< server: Apache/2.4.41 (Ubuntu)
< last-modified: Wed, 30 Mar 2022 11:28:30 GMT
< etag: "7-5db6dd8521aec"
< accept-ranges: bytes
< content-length: 7
< x-info: backend_2 : default_2 <-- backend_2 OK
<
test 2
* Connection #0 to host 127.0.0.1 left intact
root@ubuntu2004:/etc/haproxy# curl --http1.1 -kv https://127.0.0.1/3/x
...
< HTTP/1.1 200 OK
< date: Wed, 30 Mar 2022 12:05:26 GMT
< server: Apache/2.4.41 (Ubuntu)
< last-modified: Wed, 30 Mar 2022 11:46:32 GMT
< etag: "7-5db6e18c50c11"
< accept-ranges: bytes
< content-length: 7
< x-info: backend_3 : default_3 <-- backend_3 OK
<
test 3
* Connection #0 to host 127.0.0.1 left intact
When we use HTTP/2, switching to backend_2 does not work:
root@ubuntu2004:/etc/haproxy# curl --http2 -kv https://127.0.0.1/2/x
...
< HTTP/2 200
< date: Wed, 30 Mar 2022 12:09:04 GMT
< server: Apache/2.4.41 (Ubuntu)
< last-modified: Wed, 30 Mar 2022 11:28:30 GMT
< etag: "7-5db6dd8521aec"
< accept-ranges: bytes
< content-length: 7
< x-info: defaultbackend : default_1 <-- here we expect backend_2
<
test 2
* Connection #0 to host 127.0.0.1 left intact
Can you please check this?
Kind Regards
Ralf Saier
Senior Software Developer
Tel. +49 721 663035-253
E-Mail [email protected]<mailto:[email protected]>
Angaben zum Absender:
econda GmbH<https://www.econda.de/?newsletter=ma_email_signatur/econda>,
Zimmerstr. 6, 76137 Karlsruhe
Geschäftsführer: Christian Hagemeyer, Dr. Philipp Sorg
Handelsregister: Amtsgericht Mannheim HRB 110559