Hi list, We observed a weird behavior yesterday at introducing h2 in a preproduction environment: *the connection is being closed by haproxy both on server and client side by immediately sending a FIN/ACK when using SSE (text/event-stream)*.
Let me know if you see something obvious here, or if this is candidate to a bug. We have a service using SSE through text/event-stream content-type. In HTTP/1.1 we have a normal stream as expected : < HTTP/1.1 200 OK < Content-Type: text/event-stream data: {"a": "b"} data: {"a": "b"} data: {"a": "b"} (...) HAProxy on its side adds the `Connection: close` header. When adding 'alpn h2,http/1.1' to the bind directive, we observe the following: after the first 200OK, the connection is closed by haproxy both on server and client side by sending a FIN/ACK. It's obviously the same pattern than above on LB<>backend side, since there is a translation h2 to http/1.1. On client side it gives: $ curl -vv (...) (...) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: none (...) * ALPN, server accepted to use h2 * Server certificate: (...) * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x55d5e9228de0) > GET /something HTTP/2 > Host: <REDACTED> > User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 > Firefox/62.0 > Accept: text/event-stream > Accept-Language: en-US,en;q=0.5 > Accept-Encoding: gzip, deflate, br > Referer: <REDACTED > Cookie: jwt=<REDACTED> > Connection: keep-alive > Pragma: no-cache > Cache-Control: no-cache > * Connection state changed (MAX_CONCURRENT_STREAMS == 100)! < HTTP/2 200 < content-type: text/event-stream < * Connection #0 to host <REDACTED> left intact So the connection is abruptly closed. Here is the config: $ haproxy -vv HA-Proxy version 1.8.14-52e4d43 2018/09/20 Copyright 2000-2018 Willy Tarreau <wi...@haproxy.org> Build options : TARGET = linux2628 CPU = generic CC = gcc CFLAGS = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement -fwrapv -fno-strict-overflow -Wno-unused-label -DTCP_USER_TIMEOUT=18 OPTIONS = USE_LINUX_TPROXY=1 USE_GETADDRINFO=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_SYSTEMD=1 USE_PCRE=1 USE_PCRE_JIT=1 USE_TFO=1 USE_NS=1 Default settings : maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200 Built with OpenSSL version : OpenSSL 1.1.1 11 Sep 2018 Running on OpenSSL version : OpenSSL 1.1.1 11 Sep 2018 OpenSSL library supports TLS extensions : yes OpenSSL library supports SNI : yes OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3 Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND Encrypted password support via crypt(3): yes Built with multi-threading support. Built with PCRE version : 8.32 2012-11-30 Running on PCRE version : 8.32 2012-11-30 PCRE library supports JIT : yes Built with zlib version : 1.2.7 Running on zlib version : 1.2.7 Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip") Built with network namespace support. 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 filters : [SPOE] spoe [COMP] compression [TRACE] trace $ sudo cat /etc/haproxy/haproxy.cfg | head -70 global (...) nbproc 1 daemon stats socket /var/lib/haproxy/stats level admin mode 644 expose-fd listeners stats timeout 2m tune.bufsize 33792 ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets (...) hard-stop-after 5400s nbthread 6 cpu-map auto:1/1-6 0-5 defaults mode http (...) timeout connect 10s timeout client 180s timeout server 180s timeout http-keep-alive 10s timeout http-request 10s timeout queue 1s timeout check 5s (...) option http-keep-alive option forwardfor except 127.0.0.0/8 balance roundrobin maxconn 262134 http-reuse safe (...) frontend fe_main bind *:80 name http_1 process 1/1 bind *:80 name http_2 process 1/2 bind *:80 name http_3 process 1/3 bind *:443 name https_4 ssl crt /etc/haproxy/tls/fe_main process 1/4 alpn http/1.1,h2 bind *:443 name https_5 ssl crt /etc/haproxy/tls/fe_main process 1/5 alpn http/1.1,h2 bind *:443 name https_6 ssl crt /etc/haproxy/tls/fe_main process 1/6 alpn http/1.1,h2 (...) # Nothing specific in the backend (no override of the aforementioned settings). Any idea? Best regards, Pierre Cheynier