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 sa...@econda.de<mailto:sa...@econda.de>

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




Reply via email to