Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package haproxy for openSUSE:Factory checked 
in at 2026-10-09 21:43:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/haproxy (Old)
 and      /work/SRC/openSUSE:Factory/.haproxy.new.3698736 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "haproxy"

Fri Oct  9 21:43:28 2026 rev:194 rq:1383351 version:3.4.6+git1.3ce8f6169

Changes:
--------
--- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes  2026-09-24 
23:04:35.954169858 +0200
+++ /work/SRC/openSUSE:Factory/.haproxy.new.3698736/haproxy.changes     
2026-10-09 21:43:31.254621460 +0200
@@ -1,0 +2,20 @@
+Thu Oct 01 15:49:07 UTC 2026 - Marcus Rueckert <[email protected]>
+
+- Update to version 2.3.0+git2.b031728:
+  * DOC: otel: added a security policy to the repository
+  * MINOR: otel: test: added a test with an optional upstream context
+
+-------------------------------------------------------------------
+Thu Oct 01 15:49:06 UTC 2026 - Marcus Rueckert <[email protected]>
+
+- Update to version 3.4.6+git1.3ce8f6169:
+  * MEDIUM: jwt: Reject "none" alg in jwt_verify by default
+  * [RELEASE] Released version 3.4.6
+  * REGTESTS: log: check that a ring's internal server may target a UNIX socket
+  * BUG/MEDIUM: server: skip log backend addr checks for internal proxies
+  * BUG/MEDIUM: sink: reconnect attempt not working after session lasted more 
than ~25 days
+  * BUG/MAJOR: mux_quic: fix potential crash on RESET_STREAM receive
+  * MINOR: log: add the +utf8 encoding option to let valid UTF-8 pass
+  * MINOR: log: pass the input end to the _lf_encode_bytes() byte encoders
+
+-------------------------------------------------------------------

Old:
----
  haproxy-3.4.5+git0.c28c410a7.tar.gz
  haproxy-opentelemetry-2.3.0+git0.4d52326.tar.gz

New:
----
  haproxy-3.4.6+git1.3ce8f6169.tar.gz
  haproxy-opentelemetry-2.3.0+git2.b031728.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ haproxy.spec ++++++
--- /var/tmp/diff_new_pack.fZX0vD/_old  2026-10-09 21:43:32.406669743 +0200
+++ /var/tmp/diff_new_pack.fZX0vD/_new  2026-10-09 21:43:32.409669869 +0200
@@ -44,10 +44,10 @@
 %bcond_with opentelemetry
 
 Name:           haproxy
-Version:        3.4.5+git0.c28c410a7
+Version:        3.4.6+git1.3ce8f6169
 Release:        0
 %if %{with opentelemetry}
-%global otel_revision 2.3.0+git0.4d52326
+%global otel_revision 2.3.0+git2.b031728
 %global otel_subdir   haproxy-opentelemetry-%{otel_revision}
 %global otel_additional_source -a9
 %endif

++++++ _service ++++++
--- /var/tmp/diff_new_pack.fZX0vD/_old  2026-10-09 21:43:32.483672970 +0200
+++ /var/tmp/diff_new_pack.fZX0vD/_new  2026-10-09 21:43:32.486673096 +0200
@@ -1,25 +1,26 @@
 <services>
   <service name="tar_scm" mode="manual">
-    <param name="url">http://git.haproxy.org/git/haproxy-3.4.git/</param>
+    <param 
name="url">https://github.com/haproxytech/haproxy-opentelemetry.git/</param>
     <param name="scm">git</param>
-    <param name="filename">haproxy</param>
+    <param name="filename">haproxy-opentelemetry</param>
     <param name="versionformat">@PARENT_TAG@+git@TAG_OFFSET@.%h</param>
-    <param name="revision">master</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="versionrewrite-replacement">\1</param>
+    <param name="revision">main</param>
     <param name="changesgenerate">enable</param>
   </service>
 
   <service name="tar_scm" mode="manual">
-    <param 
name="url">https://github.com/haproxytech/haproxy-opentelemetry.git/</param>
+    <param name="url">http://git.haproxy.org/git/haproxy-3.4.git/</param>
     <param name="scm">git</param>
-    <param name="filename">haproxy-opentelemetry</param>
+    <param name="filename">haproxy</param>
     <param name="versionformat">@PARENT_TAG@+git@TAG_OFFSET@.%h</param>
+    <param name="revision">master</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="versionrewrite-replacement">\1</param>
-    <param name="revision">main</param>
     <param name="changesgenerate">enable</param>
   </service>
+
   <service name="recompress" mode="manual">
     <param name="file">haproxy*.tar</param>
     <param name="compression">gz</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.fZX0vD/_old  2026-10-09 21:43:32.512674186 +0200
+++ /var/tmp/diff_new_pack.fZX0vD/_new  2026-10-09 21:43:32.516674353 +0200
@@ -1,11 +1,11 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">http://git.haproxy.org/git/haproxy-3.4.git/</param>
-    <param 
name="changesrevision">c28c410a73af38da8300ff7d95b2af3c30bdc68d</param>
+    <param 
name="changesrevision">3ce8f616974b28fdb289cf179818696cd8a6abf7</param>
   </service>
   <service name="tar_scm">
     <param 
name="url">https://github.com/haproxytech/haproxy-opentelemetry.git/</param>
-    <param 
name="changesrevision">4d52326b45c6211436b76e609030568974017db7</param>
+    <param 
name="changesrevision">b03172819d4180e71b8c6e436c562573491cd707</param>
   </service>
 </servicedata>
 (No newline at EOF)

++++++ haproxy-3.4.5+git0.c28c410a7.tar.gz -> 
haproxy-3.4.6+git1.3ce8f6169.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/CHANGELOG 
new/haproxy-3.4.6+git1.3ce8f6169/CHANGELOG
--- old/haproxy-3.4.5+git0.c28c410a7/CHANGELOG  2026-09-24 15:57:40.000000000 
+0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/CHANGELOG  2026-09-30 17:24:40.000000000 
+0200
@@ -1,6 +1,14 @@
 ChangeLog :
 ===========
 
+2026/09/28 : 3.4.6
+    - MINOR: log: pass the input end to the _lf_encode_bytes() byte encoders
+    - MINOR: log: add the +utf8 encoding option to let valid UTF-8 pass
+    - BUG/MAJOR: mux_quic: fix potential crash on RESET_STREAM receive
+    - BUG/MEDIUM: sink: reconnect attempt not working after session lasted 
more than ~25 days
+    - BUG/MEDIUM: server: skip log backend addr checks for internal proxies
+    - REGTESTS: log: check that a ring's internal server may target a UNIX 
socket
+
 2026/09/24 : 3.4.5
     - BUG/MINOR: cache: Manage collisions on primary key
     - BUG/MINOR: cache: Seed cache primary hash
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/VERDATE 
new/haproxy-3.4.6+git1.3ce8f6169/VERDATE
--- old/haproxy-3.4.5+git0.c28c410a7/VERDATE    2026-09-24 15:57:40.000000000 
+0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/VERDATE    2026-09-30 17:24:40.000000000 
+0200
@@ -1,2 +1,2 @@
 $Format:%ci$
-2026/09/24
+2026/09/28
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/VERSION 
new/haproxy-3.4.6+git1.3ce8f6169/VERSION
--- old/haproxy-3.4.5+git0.c28c410a7/VERSION    2026-09-24 15:57:40.000000000 
+0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/VERSION    2026-09-30 17:24:40.000000000 
+0200
@@ -1 +1 @@
-3.4.5
+3.4.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/doc/configuration.txt 
new/haproxy-3.4.6+git1.3ce8f6169/doc/configuration.txt
--- old/haproxy-3.4.5+git0.c28c410a7/doc/configuration.txt      2026-09-24 
15:57:40.000000000 +0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/doc/configuration.txt      2026-09-30 
17:24:40.000000000 +0200
@@ -3,7 +3,7 @@
                           Configuration Manual
                          ----------------------
                               version 3.4
-                              2026/09/24
+                              2026/09/28
 
 
 This document covers the configuration language as implemented in the version
@@ -1791,6 +1791,7 @@
    - insecure-fork-wanted
    - insecure-setuid-wanted
    - issuers-chain-path
+   - jwt.allow_none_alg
    - jwt.decrypt_alg_list
    - jwt.decrypt_enc_list
    - key-base
@@ -2907,6 +2908,12 @@
   The OCSP features are able to use the completed chain when no .issuer was
   used, or no chain was provided in the PEM.
 
+jwt.allow_none_alg
+  Allow JWT signed token with the "none" algorithm in the 'jwt_verify'
+  converter. They will always be considered valid when this option is set. By
+  default unsigned tokens are rejected since they are considered unsafe (see
+  RFC8725 section 3.1).
+
 jwt.decrypt_alg_list <list>
   Set the list of algorithms allowed in the jwt_decrypt_XXX converters. JWT
   tokens using an unsupported or disabled algorithms will never be decrypted.
@@ -22302,9 +22309,13 @@
    | PS256        | RSASSA-PSS using SHA-256 and MGF1 with SHA-256          |
    | PS384        | RSASSA-PSS using SHA-384 and MGF1 with SHA-384          |
    | PS512        | RSASSA-PSS using SHA-512 and MGF1 with SHA-512          |
-   | none         | No digital signature or MAC performed                   |
+   | none         | No digital signature or MAC performed (see note below)  |
    +--------------+---------------------------------------------------------+
 
+   Please note that the "none" algorithm is not allowed by default to follow
+   the recommendations in RFC8725 section 3.2. Set global option
+   'jwt.allow_none_alg' to explicitely allow it.
+
   - <key> can be either a string or a variable name (See also "set-var") that
     holds a secret or a public key path.
 
@@ -29497,6 +29508,24 @@
           Incomplete numerical values (e.g.: '%B' when logasap is used),
           which are normally prefixed with '+' without encoding, will be
           encoded as-is. Also, '+E' option will be ignored.
+          As described in section 8.6, characters outside the 32..126 range
+          are escaped one byte at a time, using the JSON escape sequences,
+          so that the output remains pure printable ASCII whatever the
+          input. This includes valid UTF-8 sequences, meaning that non-ASCII
+          text will appear as its individual bytes once decoded (e.g.
+          U+00E9, encoded as 0xC3 0xA9, is logged as "\u00C3\u00A9"). See
+          "utf8" below to preserve such text.
+  * utf8: combined with "json", permits to let valid multi-byte UTF-8 sequences
+          pass unescaped. The C1 control characters (U+0080 to U+009F) are
+          still escaped, represented by their code point. Invalid sequences are
+          escaped one byte at a time so that the output always remains valid
+          UTF-8. Note that since valid UTF-8 is emitted as-is, a client may use
+          some special characters to alter the rendering of a log line on a
+          terminal or in a log viewer, such as direction changes, zero-width
+          characters, or line and paragraph separators. Thus it is recommended
+          to only use it for contents coming from trusted sources, or when logs
+          are not meant to be displayed on a terminal. It has no effect without
+          "json".
   * cbor: automatically encode value in CBOR format
           (when set globally, only named logformat items are considered)
           By default, cbor encoded data is represented in HEX form so
@@ -29517,6 +29546,7 @@
     log-format-sd %{+Q,+E}o\ [exampleSDID@1234\ header=%[capture.req.hdr(0)]]
 
     log-format "%{+json}o %(request)r %(custom_expr)[str(custom)]"
+    log-format "%{+json,+utf8}o %(request)r %(custom_expr)[str(custom)]"
     log-format "%{+cbor}o %(request)r %(custom_expr)[str(custom)]"
 
 Please refer to the table below for currently defined aliases :
@@ -30495,6 +30525,10 @@
 digits, or properly delimited binary blocks that will not be sent to a terminal
 but will be consumed by a CBOR parser.
 
+The json encoding uses the JSON escape sequences instead, and the +utf8 option
+also lets valid multi-byte UTF-8 sequences pass as-is (see the "utf8" flag in
+section 8.2.6).
+
 Note that the space character (' ') is not encoded in headers, which can cause
 issues for tools relying on space count to locate fields. A typical header
 containing spaces is "User-Agent".
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/include/haproxy/log-t.h 
new/haproxy-3.4.6+git1.3ce8f6169/include/haproxy/log-t.h
--- old/haproxy-3.4.5+git0.c28c410a7/include/haproxy/log-t.h    2026-09-24 
15:57:40.000000000 +0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/include/haproxy/log-t.h    2026-09-30 
17:24:40.000000000 +0200
@@ -48,7 +48,8 @@
 #define LOG_OPT_ESC             0x00000040
 #define LOG_OPT_MERGE_SPACES    0x00000080
 #define LOG_OPT_BIN             0x00000100
-/* unused: 0x00000200 ... 0x00000800 */
+#define LOG_OPT_UTF8            0x00000200 // only used with 
LOG_OPT_ENCODE_JSON (utf-8 pass-through)
+/* unused: 0x00000400 ... 0x00000800 */
 #define LOG_OPT_ENCODE_JSON     0x00001000
 #define LOG_OPT_ENCODE_CBOR     0x00002000
 #define LOG_OPT_ENCODE          0x00003000
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.4.5+git0.c28c410a7/include/haproxy/sink-t.h 
new/haproxy-3.4.6+git1.3ce8f6169/include/haproxy/sink-t.h
--- old/haproxy-3.4.5+git0.c28c410a7/include/haproxy/sink-t.h   2026-09-24 
15:57:40.000000000 +0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/include/haproxy/sink-t.h   2026-09-30 
17:24:40.000000000 +0200
@@ -40,7 +40,7 @@
 struct sink_forward_target {
        struct server *srv;    // used server
        struct appctx *appctx; // appctx of current session
-       uint last_conn;        // copy of now_ms for last session establishment 
attempt
+       uint last_close;       // copy of now_ms for last session destroy/close
        size_t ofs;            // ring buffer reader offset
        size_t e_processed;    // processed events
        struct sink *sink;     // the associated sink
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.4.5+git0.c28c410a7/reg-tests/jwt/jws_verify.vtc 
new/haproxy-3.4.6+git1.3ce8f6169/reg-tests/jwt/jws_verify.vtc
--- old/haproxy-3.4.5+git0.c28c410a7/reg-tests/jwt/jws_verify.vtc       
2026-09-24 15:57:40.000000000 +0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/reg-tests/jwt/jws_verify.vtc       
2026-09-30 17:24:40.000000000 +0200
@@ -32,6 +32,7 @@
     .endif
         tune.ssl.capture-buffer-size 1
         stats socket "${tmpdir}/h1/stats" level admin
+        jwt.allow_none_alg
 
     defaults
         mode http
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.4.5+git0.c28c410a7/reg-tests/log/log_json.vtc 
new/haproxy-3.4.6+git1.3ce8f6169/reg-tests/log/log_json.vtc
--- old/haproxy-3.4.5+git0.c28c410a7/reg-tests/log/log_json.vtc 2026-09-24 
15:57:40.000000000 +0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/reg-tests/log/log_json.vtc 2026-09-30 
17:24:40.000000000 +0200
@@ -6,7 +6,9 @@
 # JSON encoding has no reason to be more permissive than the plain one.
 # Escaping them all also makes the output valid UTF-8, which RFC 8259 #8.1
 # requires, without having to guess what the logged bytes represent: a header
-# value is arbitrary bytes, not text.
+# value is arbitrary bytes, not text. The +utf8 option bypasses this, letting
+# valid multi-byte UTF-8 sequences pass as-is, and still escapes all other
+# bytes above 126 one at a time so that the output remains valid UTF-8.
 
 haproxy h1 -conf {
     global
@@ -18,6 +20,10 @@
         size 16384
         format raw
 
+    ring rawring
+        size 16384
+        format raw
+
     defaults
         mode http
         timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
@@ -30,6 +36,13 @@
         log ring@myring local0
         log-format 
"{\"hdr\":%{+json}[capture.req.hdr(0)],\"bin\":%{+json}[str(Gw==),b64dec]}"
         http-request return status 200
+
+    frontend fe_raw
+        bind "fd@${fe_raw}"
+        capture request header x len 64
+        log ring@rawring local0
+        log-format "%{+json,+utf8}o %(hdr)[capture.req.hdr(0)] 
%(bin)[str(w6nCm+KC),b64dec]"
+        http-request return status 200
 } -start
 
 # an ESC, which has no two-character form, a tab, which has one, a double quote
@@ -48,6 +61,15 @@
     expect resp.status == 200
 } -run
 
+# in raw mode: a valid UTF-8 sequence, a lone continuation byte, an overlong
+# form, an encoded surrogate, a C1 control character, a 4-byte sequence, one
+# beyond U+10FFFF and a sequence truncated by the end of the value
+client c3 -connect ${h1_fe_raw_sock} {
+    txreq -url "/raw" -hdr "x: 
A\xc3\xa9B\xaaC\xc0\x81D\xed\xa0\x80E\xc2\x9bF\xf0\x9f\x98\x80G\xf4\x90\x80\x80H\xe2\x82"
+    rxresp
+    expect resp.status == 200
+} -run
+
 delay 0.2
 
 # the ESC comes out as the six-character form and the tab as the short one, in
@@ -75,3 +97,18 @@
     send "show events myring -s"
     expect !~ "\\?"
 }
+
+# in raw mode, the valid UTF-8 sequences are emitted as-is, the C1 control
+# character as its code point's escape sequence, and all other bytes above the
+# printable range get one escape per byte, so that the output remains valid
+# UTF-8
+haproxy h1 -cli {
+    send "show events rawring"
+    expect ~ "\"hdr\": 
\"A\xc3\xa9B\\\\u00AAC\\\\u00C0\\\\u0081D\\\\u00ED\\\\u00A0\\\\u0080E\\\\u009BF\xf0\x9f\x98\x80G\\\\u00F4\\\\u0090\\\\u0080\\\\u0080H\\\\u00E2\\\\u0082\""
+}
+
+# same in the binary sample path, where the truncated sequence ends the sample
+haproxy h1 -cli {
+    send "show events rawring"
+    expect ~ "\"bin\": \"\xc3\xa9\\\\u009B\\\\u00E2\\\\u0082\""
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.4.5+git0.c28c410a7/reg-tests/log/ring_unix_log_forward.vtc 
new/haproxy-3.4.6+git1.3ce8f6169/reg-tests/log/ring_unix_log_forward.vtc
--- old/haproxy-3.4.5+git0.c28c410a7/reg-tests/log/ring_unix_log_forward.vtc    
1970-01-01 01:00:00.000000000 +0100
+++ new/haproxy-3.4.6+git1.3ce8f6169/reg-tests/log/ring_unix_log_forward.vtc    
2026-09-30 17:24:40.000000000 +0200
@@ -0,0 +1,83 @@
+varnishtest "ring section's internal server may target a UNIX socket"
+
+# 23e5f18b8 ("MEDIUM: sink: change the sink mode type to PR_MODE_SYSLOG")
+# tagged a sink's forward_px (the internal proxy backing a "ring" section)
+# with PR_MODE_SYSLOG. As an unintended side effect, this made ring's own
+# "server" line subject to _srv_check_proxy_mode()'s log-backend
+# address-family check (added by 64e0b6344 for real "mode log" backends),
+# which rejects AF_UNIX. This broke the common "ring -> UNIX socket ->
+# log-forward" pattern, which worked fine before 23e5f18b8.
+#
+# This test declares a ring whose server targets a UNIX socket bound by a
+# log-forward section, which itself relays to a vtest syslog receiver. It
+# fails to parse on an affected, unpatched build ("log server address
+# family not supported for log backend server").
+
+feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(3.3-dev2)'"
+feature ignore_unknown_macro
+
+syslog Slg1 -level info {
+    recv
+    expect ~ "GET /client_c1 HTTP/1.1"
+} -start
+
+server s1 {
+    rxreq
+    txresp
+} -start
+
+haproxy h1 -conf {
+    global
+    .if feature(THREAD)
+        thread-groups 1
+    .endif
+    # when run as root without an explicit "chroot" directive, haproxy's
+    # automatic "chroot auto" (see 641fe4f11) isolates the process into
+    # an empty directory right after startup. That breaks the ring's own
+    # UNIX-socket "server" connect (a runtime, repeatedly-retried client
+    # connection), unlike the log-forward listener's "bind unix@..."
+    # which is already open before the chroot happens. Pin "chroot /" so
+    # this test behaves the same whether run as root or not.
+    chroot /
+
+       defaults
+               mode http
+               option httplog
+               timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+               timeout client  "${HAPROXY_TEST_TIMEOUT-5s}"
+               timeout server  "${HAPROXY_TEST_TIMEOUT-5s}"
+
+       frontend fe1
+               bind "fd@${fe_1}"
+               log ring@buf1 local0
+               default_backend be
+
+       backend be
+               server app1 ${s1_addr}:${s1_port}
+
+       ring buf1
+               description "ring fed via a UNIX-socket server"
+               format rfc5424
+               maxlen 1200
+               size 32764
+               timeout connect 5s
+               timeout server 10s
+               # note: format/maxlen/size above are required for the ring's
+               # forwarder to actually flush to its server - omitting them
+               # leaves the ring silently unable to forward (unrelated to the
+               # fix under test, just a config-authoring trap)
+               # the whole point of this test: a UNIX socket server on a ring
+               server relay unix@"${tmpdir}/ring_unix_log_forward.sock"
+
+       log-forward relay
+               bind unix@"${tmpdir}/ring_unix_log_forward.sock" mode 660
+               log ${Slg1_addr}:${Slg1_port} local0
+} -start
+
+client c1 -connect ${h1_fe_1_sock} {
+    txreq -url "/client_c1"
+    rxresp
+    expect resp.status == 200
+} -run
+
+syslog Slg1 -wait
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/src/jwt.c 
new/haproxy-3.4.6+git1.3ce8f6169/src/jwt.c
--- old/haproxy-3.4.5+git0.c28c410a7/src/jwt.c  2026-09-24 15:57:40.000000000 
+0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/src/jwt.c  2026-09-30 17:24:40.000000000 
+0200
@@ -30,6 +30,8 @@
 /* Tree into which the public certificates used to validate JWTs will be 
stored. */
 static struct eb_root jwt_cert_tree = EB_ROOT_UNIQUE;
 
+/* Set whether "none" algorithm should be allowed or not */
+static int jwt_verify_allow_none_alg = 0;
 
 /*
  * The possible algorithm strings that can be found in a JWS's JOSE header are
@@ -508,6 +510,9 @@
        if (ctx.alg == JWT_ALG_DEFAULT)
                return JWT_VRFY_UNKNOWN_ALG;
 
+       if (ctx.alg == JWS_ALG_NONE && !jwt_verify_allow_none_alg)
+               return JWT_VRFY_UNMANAGED_ALG;
+
        if (jwt_tokenize(token, items, item_num))
                return JWT_VRFY_INVALID_TOKEN;
 
@@ -575,6 +580,23 @@
        return retval;
 }
 
+/* Parse 'jwt.allow_none_arg' option */
+static int cfg_parse_global_jwt_none_alg(char **args, int section_type, struct 
proxy *curpx,
+                                         const struct proxy *defpx, const char 
*file, int linenum, char **err)
+{
+       if (*args[1]) {
+               memprintf(err, "parsing [%s:%d]: keyword '%s' in '%s' section 
does not take any arguments.\n", file, linenum, args[0], cursection);
+               goto error;
+       }
+
+       jwt_verify_allow_none_alg = 1;
+
+       return 0;
+
+error:
+       return -1;
+}
+
 
 static void jwt_deinit(void)
 {
@@ -592,5 +614,12 @@
 }
 REGISTER_POST_DEINIT(jwt_deinit);
 
+static struct cfg_kw_list cfg_kws = {ILH, {
+       { CFG_GLOBAL, "jwt.allow_none_alg", cfg_parse_global_jwt_none_alg },
+       { 0, NULL, NULL },
+}};
+
+INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
+
 
 #endif /* USE_OPENSSL */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/src/log.c 
new/haproxy-3.4.6+git1.3ce8f6169/src/log.c
--- old/haproxy-3.4.5+git0.c28c410a7/src/log.c  2026-09-24 15:57:40.000000000 
+0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/src/log.c  2026-09-30 17:24:40.000000000 
+0200
@@ -428,6 +428,7 @@
        { "X", LOG_OPT_HEXA },
        { "E", LOG_OPT_ESC },
        { "bin", LOG_OPT_BIN },
+       { "utf8", LOG_OPT_UTF8 },
        { "json", LOG_OPT_ENCODE_JSON },
        { "cbor", LOG_OPT_ENCODE_CBOR },
        {  0,  0 }
@@ -2023,6 +2024,7 @@
        int options;   /* LOG_OPT_* options */
        int typecast;  /* same as logformat_node->typecast */
        int in_text;   /* inside variable-length text */
+       int utf8_skip; /* JSON: continuation bytes of an already emitted UTF-8 
sequence */
        union {
                struct cbor_encode_ctx cbor; /* cbor-encode specific ctx */
        } encode;
@@ -2140,13 +2142,16 @@
 /* helper function for _lf_encode_bytes() to encode a single byte
  * and escape it with <escape> if found in <map>
  *
+ * All these helpers receive the current byte in <byte> and the end of the
+ * input in <end>, which is NULL when the input is NUL-terminated.
+ *
  * The function assumes that at least 1 byte is available for writing
  *
  * Returns the address of the byte immediately after the last written byte
  * on success, or NULL on error. It will not append terminating NULL byte.
  */
 static inline char *_lf_map_escape_byte(char *start, char *stop,
-                                        const char *byte,
+                                        const char *byte, const char *end,
                                         const char escape, const long *map,
                                         const char **pending, uint8_t 
cbor_string_prefix,
                                         struct lf_buildctx *ctx)
@@ -2169,7 +2174,7 @@
  * on success, or NULL on error. It will not append terminating NULL byte.
  */
 static inline char *_lf_cbor_map_escape_byte(char *start, char *stop,
-                                             const char *byte,
+                                             const char *byte, const char *end,
                                              const char escape, const long 
*map,
                                              const char **pending, uint8_t 
cbor_string_prefix,
                                              struct lf_buildctx *ctx)
@@ -2213,7 +2218,7 @@
  * on success, or NULL on error. It will not append terminating NULL byte.
  */
 static inline char *_lf_rfc5424_escape_byte(char *start, char *stop,
-                                            const char *byte,
+                                            const char *byte, const char *end,
                                             const char escape, const long *map,
                                             const char **pending, uint8_t 
cbor_string_prefix,
                                             struct lf_buildctx *ctx)
@@ -2276,9 +2281,57 @@
        return start;
 }
 
+/* Checks whether <s> starts with a multi-byte UTF-8 sequence which is valid as
+ * per RFC 3629 and does not span more than <len> bytes: no overlong form, no
+ * surrogate (U+D800..U+Dfff), nothing beyond U+10FFFF (U+FFFE and U+FFFF,
+ * which utf8_next() rejects as well, are simply escaped). The sequence may be
+ * terminated by a NUL byte before <len> bytes, since it is not a continuation
+ * byte. On success the code point is stored into <c> and the sequence length
+ * (2 to 4) is returned, otherwise zero is returned.
+ */
+static inline int _lf_json_utf8_len(const char *s, size_t len, unsigned int *c)
+{
+       unsigned char ret;
+
+       ret = utf8_next(s, MIN(len, 4), c);
+       if (utf8_return_code(ret) != UTF8_CODE_OK)
+               return 0;
+
+       ret = utf8_return_length(ret);
+       if (ret < 2 || ret > 4 || *c > 0x10FFFF)
+               return 0;
+
+       return ret;
+}
+
+/* Writes at <start> the valid UTF-8 sequence of <len> bytes found at <seq> and
+ * representing code point <c>, as reported by _lf_json_utf8_len(). It is
+ * copied as-is, except for the C1 control characters (U+0080 .. U+009F) which,
+ * just like the C0 ones (U+0000 .. U+001F), could be interpreted by a
+ * terminal, and which are written as their \u00XX escape sequence instead.
+ *
+ * The function returns the address of the byte immediately after the last
+ * written byte, or NULL if the whole sequence does not fit before <stop>, so
+ * that a sequence is never truncated. It will not append a terminating NULL
+ * byte.
+ */
+static inline char *_lf_json_utf8_seq(char *start, char *stop,
+                                      const char *seq, int len, unsigned int c)
+{
+       if (c < 0xa0)
+               return _lf_json_escape_seq(start, stop, c);
+
+       if (start + len > stop)
+               return NULL;
+       memcpy(start, seq, len);
+       return start + len;
+}
+
 /* helper function for _lf_encode_bytes() to encode a single byte
  * and escape it with <escape> if found in <map> or escape it with
- * '\' if found in json_escape_map
+ * '\' if found in json_escape_map. With LOG_OPT_UTF8, valid multi-byte
+ * UTF-8 sequences are emitted at once when their first byte is met
+ * instead, the following ones being skipped.
  *
  * The function assumes that at least 1 byte is available for writing
  *
@@ -2286,14 +2339,29 @@
  * on success, or NULL on error. It will not append terminating NULL byte.
  */
 static inline char *_lf_json_escape_byte(char *start, char *stop,
-                                         const char *byte,
+                                         const char *byte, const char *end,
                                          const char escape, const long *map,
                                          const char **pending, uint8_t 
cbor_string_prefix,
                                          struct lf_buildctx *ctx)
 {
+       unsigned int c;
+       int len;
+
+       if (ctx->utf8_skip) {
+               /* already emitted with the sequence's first byte */
+               ctx->utf8_skip--;
+               return start;
+       }
+
        if (!ha_bit_test((unsigned char)(*byte), map)) {
                if (!ha_bit_test((unsigned char)(*byte), json_escape_map))
                        *start++ = *byte;
+               else if ((ctx->options & LOG_OPT_UTF8) &&
+                        (len = _lf_json_utf8_len(byte, end ? end - byte : 4, 
&c))) {
+                       start = _lf_json_utf8_seq(start, stop, byte, len, c);
+                       if (start)
+                               ctx->utf8_skip = len - 1;
+               }
                else
                        start = _lf_json_escape_seq(start, stop, *byte);
        }
@@ -2330,13 +2398,15 @@
        const char *pending;
        uint8_t cbor_string_prefix = 0;
        char *(*encode_byte)(char *start, char *stop,
-                            const char *byte,
+                            const char *byte, const char *bytes_stop,
                             const char escape, const long *map,
                             const char **pending, uint8_t cbor_string_prefix,
                             struct lf_buildctx *ctx);
 
-       if (ctx->options & LOG_OPT_ENCODE_JSON)
+       if (ctx->options & LOG_OPT_ENCODE_JSON) {
                encode_byte = _lf_json_escape_byte;
+               ctx->utf8_skip = 0;
+       }
        else if (ctx->options & LOG_OPT_ENCODE_CBOR)
                encode_byte = _lf_cbor_map_escape_byte;
        else if (ctx->options & LOG_OPT_ESC)
@@ -2374,7 +2444,8 @@
                 */
                if (bytes && !bytes_stop) {
                        while (start < stop && *bytes != '\0') {
-                               ret = encode_byte(start, stop, bytes, escape, 
map,
+                               ret = encode_byte(start, stop, bytes, 
bytes_stop,
+                                                 escape, map,
                                                  &pending, cbor_string_prefix,
                                                  ctx);
                                if (ret == NULL)
@@ -2384,7 +2455,8 @@
                        }
                } else if (bytes) {
                        while (start < stop && bytes < bytes_stop) {
-                               ret = encode_byte(start, stop, bytes, escape, 
map,
+                               ret = encode_byte(start, stop, bytes, 
bytes_stop,
+                                                 escape, map,
                                                  &pending, cbor_string_prefix,
                                                  ctx);
                                if (ret == NULL)
@@ -2445,26 +2517,40 @@
 
 /* Same as escape_string() but for a JSON string content: the bytes tagged in
  * json_escape_map cannot all be expressed with the two-character form that
- * escape_string() emits, the others need the \u00XX one.
+ * escape_string() emits, the others need the \u00XX one. When <raw> is set,
+ * valid multi-byte UTF-8 sequences are emitted as-is instead (see
+ * _lf_json_utf8_seq()).
  *
  * Return the address of the \0 character, or NULL on error
  */
 static char *_lf_json_escape_string(char *start, char *stop,
-                                    const char *string, const char 
*string_stop)
+                                    const char *string, const char 
*string_stop,
+                                    int raw)
 {
        if (start < stop) {
                stop--; /* reserve one byte for the final '\0' */
                while (start < stop && string < string_stop && *string != '\0') 
{
-                       if (!ha_bit_test((unsigned char)(*string), 
json_escape_map))
-                               *start++ = *string;
-                       else {
-                               char *next = _lf_json_escape_seq(start, stop, 
*string);
+                       unsigned int c;
+                       char *next;
+                       int len;
+
+                       if (!ha_bit_test((unsigned char)(*string), 
json_escape_map)) {
+                               *start++ = *string++;
+                               continue;
+                       }
 
-                               if (!next)
-                                       break; /* does not fit, truncate here */
-                               start = next;
+                       len = raw ? _lf_json_utf8_len(string, string_stop - 
string, &c) : 0;
+                       if (len)
+                               next = _lf_json_utf8_seq(start, stop, string, 
len, c);
+                       else {
+                               len = 1;
+                               next = _lf_json_escape_seq(start, stop, 
*string);
                        }
-                       string++;
+
+                       if (!next)
+                               break; /* does not fit, truncate here */
+                       start = next;
+                       string += len;
                }
                *start = '\0';
                return start;
@@ -2516,7 +2602,8 @@
                else if (ctx->options & LOG_OPT_ENCODE_JSON) {
                        char *ret;
 
-                       ret = _lf_json_escape_string(dst, dst + size, src, src 
+ len);
+                       ret = _lf_json_escape_string(dst, dst + size, src, src 
+ len,
+                                                    !!(ctx->options & 
LOG_OPT_UTF8));
                        if (ret == NULL)
                                return NULL;
                        len = ret - dst;
@@ -3765,7 +3852,9 @@
         * spares us from having to care about the UTF-8 validity that RFC 8259
         * #8.1 demands, since a header value is made of arbitrary bytes and not
         * of text. On top of that, RFC 8259 #7 mandates escaping the double
-        * quote, the backslash and everything below 0x20.
+        * quote, the backslash and everything below 0x20. The raw JSON encoding
+        * is the only exception: its encoders detect the valid multi-byte UTF-8
+        * sequences by themselves and emit them as-is.
         */
        memset(json_escape_map, 0, sizeof(json_escape_map));
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/src/mux_quic.c 
new/haproxy-3.4.6+git1.3ce8f6169/src/mux_quic.c
--- old/haproxy-3.4.5+git0.c28c410a7/src/mux_quic.c     2026-09-24 
15:57:40.000000000 +0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/src/mux_quic.c     2026-09-30 
17:24:40.000000000 +0200
@@ -720,7 +720,17 @@
                LIST_DEL_INIT(&qcs->el_send);
                TRACE_STATE("stream sent done", QMUX_EV_QCS_SEND, qcc->conn, 
qcs);
 
-               if (qcs->flags & (QC_SF_FIN_STREAM|QC_SF_DETACH)) {
+               /* Everything sent, close the stream if no new data will come.
+                * This is the case if either FIN has been sent or upper layer
+                * is detached.
+                *
+                * This is also performed if peer has resetted its input as no
+                * more transfer should occur on this QCS instance.
+                * TODO this assumption may be invalid depending on QUIC stream
+                * type - app proto should be responsible to deal with RS.
+                */
+               if ((qcs->flags & (QC_SF_FIN_STREAM|QC_SF_DETACH)) ||
+                   (!qcs_sc(qcs) && (qcs->flags & QC_SF_RECV_RESET))) {
                        /* Close stream locally. */
                        qcs_close_local(qcs);
 
@@ -2356,13 +2366,11 @@
                qcs_free_rxbuf(qcs, b);
        }
 
-       /* Check if RESET_STREAM received before stream layer initialization.
-        * If true, prepare QCS purgeing immediately.
+       /* No more data will be received after peer reset. QCS can be purged
+        * if there is nothing to sent on our side.
         */
-       if (!qcs_sc(qcs) && !(qcs->flags & QC_SF_DETACH)) {
+       if (!qcs_sc(qcs) && !LIST_INLIST(&qcs->el_send)) {
                qcs_close_local(qcs);
-
-               BUG_ON(LIST_INLIST(&qcs->el_send));
                TRACE_STATE("add stream in purg_list", 
QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV, qcc->conn, qcs);
                LIST_APPEND(&qcs->qcc->purg_list, &qcs->el_send);
                tasklet_wakeup(qcs->qcc->wait_event.tasklet);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/src/server.c 
new/haproxy-3.4.6+git1.3ce8f6169/src/server.c
--- old/haproxy-3.4.5+git0.c28c410a7/src/server.c       2026-09-24 
15:57:40.000000000 +0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/src/server.c       2026-09-30 
17:24:40.000000000 +0200
@@ -3546,9 +3546,15 @@
                goto out;
        }
 
-       if (srv->proxy->mode == PR_MODE_SYSLOG) {
+       if (srv->proxy->mode == PR_MODE_SYSLOG && !(srv->proxy->cap & 
PR_CAP_INT)) {
                /* log backend server (belongs to proxy with mode log enabled):
-                * perform some compatibility checks
+                * perform some compatibility checks. Internal proxies 
(PR_CAP_INT,
+                * e.g. a sink's forward_px backing a "ring" section) are 
excluded:
+                * they are tagged PR_MODE_SYSLOG for type-awareness purposes 
only
+                * (see 23e5f18b8) and are not real user-configured log 
backends,
+                * so they may legitimately target a UNIX socket (e.g. to feed a
+                * local "log-forward" section). They still go through the 
regular
+                * STREAM-transport check below, in the "else" branch.
                 */
 
                /* supported address family types are:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.4.5+git0.c28c410a7/src/sink.c 
new/haproxy-3.4.6+git1.3ce8f6169/src/sink.c
--- old/haproxy-3.4.5+git0.c28c410a7/src/sink.c 2026-09-24 15:57:40.000000000 
+0200
+++ new/haproxy-3.4.6+git1.3ce8f6169/src/sink.c 2026-09-30 17:24:40.000000000 
+0200
@@ -612,6 +612,7 @@
        HA_SPIN_LOCK(SFT_LOCK, &sft->lock);
        BUG_ON(sft->appctx != appctx);
        __sink_forward_session_deinit(sft);
+       sft->last_close = now_ms;
        HA_SPIN_UNLOCK(SFT_LOCK, &sft->lock);
 }
 
@@ -686,7 +687,6 @@
                goto out_close;
        appctx->svcctx = (void *)sft;
        appctx_wakeup(appctx);
-       sft->last_conn = now_ms;
        return appctx;
 
        /* Error unrolling */
@@ -714,11 +714,19 @@
                         *
                         * We enforce a tempo to ensure we don't perform more 
than 1 session
                         * establishment attempt per second.
+                        *
+                        * Note: last_close will wrap after 24.85 days, which 
may happen if
+                        * the server remains unavailable for that long, in 
that case it will
+                        * cause the tick_is_expired() test to always fail 
since tempo will be
+                        * in the future. This means the applet will stop 
trying to reconnect
+                        * to the server. We accept this pitfall because a 
server that was
+                        * unavailable for that long can be considered as 
definitely dead, but
+                        * this is something to keep in mind.
                         */
                        if (!sft->appctx) {
-                               int tempo = tick_add(sft->last_conn, 
MS_TO_TICKS(1000));
+                               int tempo = tick_add(sft->last_close, 
MS_TO_TICKS(1000));
 
-                               if (sft->last_conn == TICK_ETERNITY || 
tick_is_expired(tempo, now_ms))
+                               if (sft->last_close == TICK_ETERNITY || 
tick_is_expired(tempo, now_ms))
                                        sft->appctx = 
sink_forward_session_create(sink, sft);
                                else if (task->expire == TICK_ETERNITY)
                                        task->expire = tempo;

++++++ haproxy-opentelemetry-2.3.0+git0.4d52326.tar.gz -> 
haproxy-opentelemetry-2.3.0+git2.b031728.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-opentelemetry-2.3.0+git0.4d52326/README 
new/haproxy-opentelemetry-2.3.0+git2.b031728/README
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/README 2026-09-09 
00:38:11.000000000 +0200
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/README 2026-09-24 
18:50:06.000000000 +0200
@@ -1,7 +1,7 @@
                    -----------------------------------------
                       The HAProxy OpenTelemetry filter (OTel)
                                  Version 2.3.0
-                          ( Last update: 2026-09-14 )
+                          ( Last update: 2026-09-16 )
                    -----------------------------------------
                            Author : Miroslav Zagorac
                      Contact : mzagorac at haproxy dot com
@@ -1973,6 +1973,7 @@
   % ./run-updown.sh
   % ./run-err.sh
   % ./run-empty.sh
+  % ./run-optctx.sh
 
 The parser test runs the same way but starts no proxy.  It checks a series of
 generated configuration files with 'haproxy -c' against the keyword rules of
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-opentelemetry-2.3.0+git0.4d52326/README-configuration 
new/haproxy-opentelemetry-2.3.0+git2.b031728/README-configuration
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/README-configuration   
2026-09-09 00:38:11.000000000 +0200
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/README-configuration   
2026-09-24 18:50:06.000000000 +0200
@@ -1,7 +1,7 @@
                    -----------------------------------------
                     HAProxy OTel filter configuration guide
                                Version 2.3.0
-                        ( Last update: 2026-09-14 )
+                        ( Last update: 2026-09-16 )
                    -----------------------------------------
                          Author : Miroslav Zagorac
                    Contact : mzagorac at haproxy dot com
@@ -1829,3 +1829,38 @@
 
 This is useful for testing the OTel filter initialization behavior without any
 actual telemetry processing.
+
+
+6.9. Optional upstream context example (optctx)
+-------------------------------------------------
+
+Traces a request whether or not it arrives with an upstream context.  An ACL
+over the 'otel.context' fetch picks between two root spans, one that continues
+the trace the request brings and one that opens a trace of its own.  A 'span'
+line takes no condition, so the two stand in scopes of their own, bound to the
+same event, and the extraction goes into a third one placed before them, 
because
+the fetch answers only once it has run:
+
+--- test/optctx/otel.cfg (excerpt) -------------------------------------
+
+    otel-instrumentation otel-test-instrumentation
+        acl otel-ctx-valid otel.context(-otel-ctx)
+
+    otel-scope http_request_extract
+        extract "-otel-ctx" use-headers
+        otel-event on-frontend-http-request
+
+    otel-scope http_request_child
+        span "HAProxy session" parent "-otel-ctx" root
+        otel-event on-frontend-http-request if otel-ctx-valid
+
+    otel-scope http_request_new
+        span "HAProxy session" root
+        otel-event on-frontend-http-request unless otel-ctx-valid
+
+---------------------------------------------------------------------
+
+The fetch reports the validity of the context rather than its presence, so a
+malformed 'traceparent' takes the second branch as well.  The 'require-context'
+option has to stay off, since it suppresses the telemetry of every stream that
+brings no context.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-opentelemetry-2.3.0+git0.4d52326/README-implementation 
new/haproxy-opentelemetry-2.3.0+git2.b031728/README-implementation
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/README-implementation  
2026-09-09 00:38:11.000000000 +0200
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/README-implementation  
2026-09-24 18:50:06.000000000 +0200
@@ -67,6 +67,7 @@
       |-- run-updown.sh  Up-down counter test runner (symlink)
       |-- run-err.sh     Error-logging test runner (symlink)
       |-- run-empty.sh   Empty configuration test runner (symlink)
+      |-- run-optctx.sh  Optional upstream context test runner (symlink)
       |-- run-parser.sh  Configuration parser test driver (real file)
       |-- otlp_http-recorder.py  OTLP/HTTP traffic recorder
       |-- otlp_http-replay.py    OTLP/HTTP traffic replayer
@@ -84,6 +85,7 @@
       |-- updown/        Up-down counter test configs
       |-- err/           Error-logging test configs
       |-- empty/         Minimal/empty configuration test
+      |-- optctx/        Optional upstream context test configs
       `-- parser/        Parser test cases, tables and generators
 
 
@@ -1244,8 +1246,9 @@
   run-test-config.sh  Single-instance runner: derives the configuration
                 directory from the name it is invoked under (run-<dir>.sh).
                 run-sa.sh, run-full.sh, run-cmp.sh, run-ctx.sh, run-tcp.sh,
-                run-updown.sh, run-err.sh and run-empty.sh are symlinks to it,
-                each starting one HAProxy instance with its own config.
+                run-updown.sh, run-err.sh, run-empty.sh and run-optctx.sh are
+                symlinks to it, each starting one HAProxy instance with its
+                own config.
   run-fe-be.sh  Launches two HAProxy instances (frontend on port 10080, backend
                 on port 11080) forming a trace propagation chain.  Handles
                 graceful shutdown via SIGUSR1.  A separate script, not a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-opentelemetry-2.3.0+git0.4d52326/README.md 
new/haproxy-opentelemetry-2.3.0+git2.b031728/README.md
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/README.md      2026-09-09 
00:38:11.000000000 +0200
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/README.md      2026-09-24 
18:50:06.000000000 +0200
@@ -390,6 +390,7 @@
   costs
 - [dummy/README](dummy/README) -- build-only stand-in for the wrapper library
 - [ChangeLog](ChangeLog) -- release notes
+- [SECURITY.md](SECURITY.md) -- security policy and reporting a vulnerability
 
 ### License
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-opentelemetry-2.3.0+git0.4d52326/SECURITY.md 
new/haproxy-opentelemetry-2.3.0+git2.b031728/SECURITY.md
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/SECURITY.md    1970-01-01 
01:00:00.000000000 +0100
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/SECURITY.md    2026-09-24 
18:50:06.000000000 +0200
@@ -0,0 +1,113 @@
+# Security Policy
+
+## Supported Versions
+
+Security fixes go into the next release on the current 2.x line.  There are no
+long term support branches and no backports to earlier releases, so the fix
+for a confirmed issue reaches you by upgrading.
+
+| **Version**          | **Supported** |
+|:---------------------|:-------------:|
+| Latest 2.x release   | Yes           |
+| Earlier 2.x releases | No            |
+| 1.x                  | No            |
+
+The filter runs inside HAProxy 3.2 or newer and builds against the 
OpenTelemetry
+C Wrapper.  A problem that turns out to sit in either of those is handled by
+that project; see the dependencies section below.
+
+## Reporting a Vulnerability
+
+Do not report a suspected vulnerability through a public GitHub issue or a pull
+request, and do not put the details in one.
+
+Report it through GitHub's private vulnerability reporting:
+
+https://github.com/haproxytech/haproxy-opentelemetry/security/advisories/new
+
+If that form is not reachable for you, open a plain issue saying only that you
+have a security report, with no details in it, and a maintainer will arrange a
+private channel.
+
+Include as much of this as you have:
+
+- What the issue is and what an attacker gets out of it.
+- The affected release or commit, and the HAProxy version it runs in.
+- The version of the OpenTelemetry C Wrapper the filter was built against.
+- The HAProxy configuration and the OTel configuration section that set it off,
+  cut down as far as you can get them.
+- The request or the response that triggers it, and the steps to reproduce.
+- Whether the build was a debug or a release one.
+- Any mitigation or fix you already have.
+
+## What to Expect
+
+A maintainer confirms the report, asks for whatever is missing to reproduce it,
+and then says whether it is accepted, with the reasoning either way.  A small
+team maintains the project, so answers come in days rather than hours.
+
+An accepted report gets a severity, a fix, and a release: the next regular one,
+or a release of its own when the issue is bad enough to warrant it.  The fix
+is announced in a GitHub security advisory and in the ChangeLog, and you are
+credited in both unless you ask not to be.  The project does not pay bounties.
+
+## Scope
+
+The filter runs inside the HAProxy process and on the data path.  The header
+values, the URL, the `traceparent`, `tracestate` and `baggage` headers, and
+whatever the sample expressions fetch, all arrive from the client or from the
+server, while the HAProxy configuration and the OTel configuration come from
+the operator.  A crash takes the worker down with it, so anything a remote peer
+can set off counts.
+
+In scope:
+
+- Memory safety in the filter's code: buffer overflows, out of bounds access,
+  use after free and double free, and reads of uninitialized memory.
+- A crash, a hang or unbounded memory growth that a client or a server can set
+  off through a request or a response.
+- A crafted value that escapes the field the filter writes it into, whether a
+  header or a variable.
+- Memory corruption in the configuration parsing, even though the configuration
+  itself is written by the operator.
+- Data races between HAProxy threads that corrupt the filter's state or carry
+  data from one stream into another.
+- Telemetry sent somewhere other than the configured endpoint.
+- Process data that reaches exported telemetry although the configuration never
+  asked for it.
+- A CLI command whose arguments corrupt memory, although CLI access is already
+  privileged.
+
+Out of scope:
+
+- Telemetry that is dropped or never arrives: delivery is best effort by 
design,
+  as [README.md](README.md) says.
+- What the configuration asks for: an attribute that copies a header or a 
cookie
+  into a span, an exporter aimed at the wrong collector, or a sampling rate 
that
+  leaves events out, are deployment decisions.
+- Findings in HAProxy itself.  Those belong to the HAProxy project and go to
+  https://github.com/haproxy/haproxy/security.
+- Findings in the OpenTelemetry C Wrapper, or in the OpenTelemetry C++ SDK it
+  carries.  See below.
+- Behaviour that appears only in a debug build.  Report that as an ordinary
+  issue.
+- The test configurations and scripts under `test/`, and the stand-in library
+  under `dummy/`, which are there for development.
+
+## Dependencies
+
+The filter is built against the OpenTelemetry C Wrapper library, which carries
+the OpenTelemetry C++ SDK and everything that SDK links with it, and it runs
+inside HAProxy 3.2 or newer.
+
+Report a flaw in the wrapper through the security policy of its repository at
+https://github.com/haproxytech/opentelemetry-c-wrapper, and a flaw in HAProxy
+to the HAProxy project.  Report it here as well when the way the filter uses
+either of them is what makes the flaw reachable.
+
+## Coordinated Disclosure
+
+Give the maintainers time to investigate and ship a fix before publishing the
+details.  A confirmed issue is normally fixed in a release within 30 days, and
+the advisory goes out with that release, so the wait is usually shorter.  
Ninety
+days from the report is the outside limit.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/README-optctx 
new/haproxy-opentelemetry-2.3.0+git2.b031728/test/README-optctx
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/README-optctx     
1970-01-01 01:00:00.000000000 +0100
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/test/README-optctx     
2026-09-24 18:50:06.000000000 +0200
@@ -0,0 +1,113 @@
+Optional upstream context test configuration (optctx/)
+======================================================
+
+The 'optctx' test traces a request whether or not it arrives with a W3C trace
+context.  A request that carries a valid 'traceparent' continues the trace it
+names, a request that carries none, or one the propagator cannot read, opens a
+trace of its own.  This is the shape an HAProxy at the edge needs, where part 
of
+the traffic comes from instrumented senders and the rest from browsers, health
+checkers and hand-written clients.
+
+A 'span' line takes no 'if'/'unless' condition, so the two root spans stand in
+two scopes bound to one event, and an ACL over the 'otel.context' fetch decides
+which of them runs.  The fetch answers only once the extraction has run, which
+is why the 'extract' keeps a scope of its own, placed first; scopes run in the
+order their sections appear in the file.
+
+This is the opposite of 'option require-context', which suppresses the 
telemetry
+of a stream that brings no context instead of tracing it on its own.
+
+
+Files
+-----
+
+  optctx/otel.cfg    OTel filter configuration (two conditional root spans)
+  optctx/haproxy.cfg HAProxy frontend/backend configuration
+  optctx/otel.yml    Exporter, processor, reader and provider definitions
+
+
+Events
+------
+
+  on-frontend-http-request  read by four scopes: the extraction, the two root
+                            span branches and the request span they share
+  on-http-response          adds the response span
+  on-server-session-end     closes the spans and the extracted context
+
+  The closing waits for the on-server-session-end event, because a 'finish *' 
on
+  the response event would drop the context before the HTTP response rules of
+  the frontend, the ones that read it through 'otel.context', have run.
+
+
+The decision
+------------
+
+  The context name is written with a leading '-', which keeps the name out of
+  the headers and reads the bare 'traceparent' and 'tracestate' that an outside
+  sender emits:
+
+    acl otel-ctx-valid otel.context(-otel-ctx)
+
+    otel-scope http_request_extract
+        extract "-otel-ctx" use-headers
+        otel-event on-frontend-http-request
+
+    otel-scope http_request_child
+        span "HAProxy session" parent "-otel-ctx" root
+        otel-event on-frontend-http-request if otel-ctx-valid
+
+    otel-scope http_request_new
+        span "HAProxy session" root
+        otel-event on-frontend-http-request unless otel-ctx-valid
+
+  The fetch reports the validity of the extracted context, not its presence,
+  so a malformed 'traceparent' takes the second branch as well.  A '-m found'
+  match would not separate those two cases, since with a name that carries no
+  prefix the extraction registers a context whatever the request holds, and the
+  match then reads as true even for a request without any trace headers.
+
+  Each branch marks its span with a 'haproxy.trace_continued' attribute, and
+  the frontend repeats the decision in an 'X-Otel-Trace-Continued' response
+  header, so a plain curl shows which one ran.
+
+
+Sampling
+--------
+
+  The SDK sampler is 'parent_based' with an 'always_on' delegate, which is what
+  this configuration needs, since a continued trace then follows the decision
+  its sender made and a trace opened here is sampled.
+
+  Keep the 'rate-limit' at 100.0 and sample in the SDK instead when the sender
+  is another HAProxy running this filter.  A rate limit below 100.0 skips the
+  filter for part of the streams, so the sender injects no context for them
+  and this configuration answers every one of those with a trace of its own.
+  A sampler drops the span instead of the filter, the context still travels
+  with the sampled flag cleared, and the two hosts stay on one trace.
+
+
+Running the test
+----------------
+
+The run-optctx.sh script (a symlink to run-test-config.sh) runs this
+configuration.  It invokes haproxy with -f haproxy-common.cfg -f
+optctx/haproxy.cfg, the same as the manual command shown below.  From the
+test/ directory:
+
+  % ./run-optctx.sh
+
+Or run it manually:
+
+  % /path/to/haproxy -f haproxy-common.cfg -f optctx/haproxy.cfg
+
+Then drive one request of each kind and read the response header that reports
+the branch:
+
+  % curl -sSD- -o /dev/null -H \
+      'traceparent: 00-11111111111111111111111111111111-2222222222222222-01' \
+      http://127.0.0.1:10080/
+  % curl -sSD- -o /dev/null http://127.0.0.1:10080/
+
+The first request produces a "HAProxy session" span in trace 1111...1111 with
+2222222222222222 as its parent, the second one a span in a trace of its own
+with an empty parent.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/README.md 
new/haproxy-opentelemetry-2.3.0+git2.b031728/test/README.md
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/README.md 2026-09-09 
00:38:11.000000000 +0200
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/test/README.md 2026-09-24 
18:50:06.000000000 +0200
@@ -46,6 +46,7 @@
 | `full` | Every filter event except `on-http-tarpit-request`, with all three 
signal types on every scope | [README-full](README-full) |
 | `tcp` | A `mode tcp` proxy: one session span per connection and the 
forwarded payload counted | [README-tcp](README-tcp) |
 | `updown` | Metrics only, an up-down counter recording a signed per-session 
delta | [README-updown](README-updown) |
+| `optctx` | A root span picked from the request: the session span continues 
the trace the client sent, or opens one of its own when no usable context 
arrived | [README-optctx](README-optctx) |
 | `empty` | The filter loaded with an instrumentation section and no scopes, 
to prove it starts and stops cleanly | [README-empty](README-empty) |
 | `err` | The runtime error path: hard-error episodes, swallowed soft errors 
and the counters that tally them | [README-err](README-err) |
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/optctx/haproxy.cfg 
new/haproxy-opentelemetry-2.3.0+git2.b031728/test/optctx/haproxy.cfg
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/optctx/haproxy.cfg        
1970-01-01 01:00:00.000000000 +0100
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/test/optctx/haproxy.cfg        
2026-09-24 18:50:06.000000000 +0200
@@ -0,0 +1,25 @@
+global
+    stats socket /tmp/haproxy.sock mode 666 level admin
+
+listen stats
+    mode http
+    bind *:8001
+    stats uri /
+    stats admin if TRUE
+    stats refresh 10s
+
+frontend otel-test-optctx-frontend
+    bind *:10080
+    default_backend servers-backend
+
+    # OTel filter
+    filter opentelemetry id otel-test-optctx config optctx/otel.cfg
+
+    # Report which of the two root-span scopes ran, so that a plain curl
+    # shows the decision the filter made.
+    acl otel-ctx-valid otel.context(-otel-ctx)
+    http-response set-header X-Otel-Trace-Continued 1 if otel-ctx-valid
+    http-response set-header X-Otel-Trace-Continued 0 unless otel-ctx-valid
+
+backend servers-backend
+    server server-1 127.0.0.1:8000
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/optctx/otel.cfg 
new/haproxy-opentelemetry-2.3.0+git2.b031728/test/optctx/otel.cfg
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/optctx/otel.cfg   
1970-01-01 01:00:00.000000000 +0100
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/test/optctx/otel.cfg   
2026-09-24 18:50:06.000000000 +0200
@@ -0,0 +1,58 @@
+[otel-test-optctx]
+    otel-instrumentation otel-test-instrumentation
+        config optctx/otel.yml
+#       log localhost:514 local7 debug
+        option dontlog-normal
+        option hard-errors
+        no option disabled
+        rate-limit 100.0
+
+        # Reports whether a valid upstream context arrived with the request.
+        # The fetch answers only once the extraction has run, so the scope
+        # that extracts is listed, and runs, before the two branches.
+        acl otel-ctx-valid otel.context(-otel-ctx)
+
+        scopes http_request_extract
+        scopes http_request_child
+        scopes http_request_new
+        scopes http_request
+        scopes http_response
+        scopes session_end
+
+    # The '-' prefix reads the bare 'traceparent' and 'tracestate' headers an
+    # instrumented client sends.  A request without them is not an error, the
+    # extraction is simply skipped.
+    otel-scope http_request_extract
+        extract "-otel-ctx" use-headers
+        otel-event on-frontend-http-request
+
+    # A valid context arrived: the session span continues that trace.
+    otel-scope http_request_child
+        span "HAProxy session" parent "-otel-ctx" root
+            attribute "haproxy.trace_continued" int(1)
+        otel-event on-frontend-http-request if otel-ctx-valid
+
+    # Nothing usable arrived: the session span starts a trace of its own.
+    otel-scope http_request_new
+        span "HAProxy session" root
+            attribute "haproxy.trace_continued" int(0)
+        otel-event on-frontend-http-request unless otel-ctx-valid
+
+    # From here on both cases are the same.
+    otel-scope http_request
+        span "HTTP request" parent "HAProxy session"
+            attribute "http.method" method
+            attribute "http.url" url
+        otel-event on-frontend-http-request
+
+    otel-scope http_response
+        span "HTTP response" parent "HAProxy session"
+            attribute "http.status_code" status
+        otel-event on-http-response
+
+    # The spans and the extracted context close here, after the HTTP rules of
+    # the frontend have run: a 'finish *' on on-http-response would drop the
+    # context before the response rules can read it with 'otel.context'.
+    otel-scope session_end
+        finish *
+        otel-event on-server-session-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/optctx/otel.yml 
new/haproxy-opentelemetry-2.3.0+git2.b031728/test/optctx/otel.yml
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/optctx/otel.yml   
1970-01-01 01:00:00.000000000 +0100
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/test/optctx/otel.yml   
2026-09-24 18:50:06.000000000 +0200
@@ -0,0 +1,249 @@
+exporters:
+  exporter_traces_otlp_file:
+    type:           otlp_file
+    thread_name:    "OTLP/file trace"
+    file_pattern:   "__optctx_traces_log-%F-%N"
+    alias_pattern:  "__traces_log-latest"
+    flush_interval: 30000000
+    flush_count:    256
+    file_size:      134217728
+    rotate_size:    5
+
+  exporter_traces_otlp_grpc:
+    type:                             otlp_grpc
+    thread_name:                      "OTLP/gRPC trace"
+    endpoint:                         "http://localhost:4317/v1/traces";
+    use_ssl_credentials:              false
+#   ssl_credentials_cacert_path:      ""
+#   ssl_credentials_cacert_as_string: ""
+#   ssl_client_key_path:              ""
+#   ssl_client_key_string:            ""
+#   ssl_client_cert_path:             ""
+#   ssl_client_cert_string:           ""
+#   timeout:                          10
+#   user_agent:                       ""
+#   max_threads:                      0
+#   compression:                      ""
+#   max_concurrent_requests:          0
+
+  exporter_traces_otlp_http:
+    type:                        otlp_http
+    thread_name:                 "OTLP/HTTP trace"
+    endpoint:                    "http://localhost:4318/v1/traces";
+    content_type:                json
+    json_bytes_mapping:          hexid
+    debug:                       false
+    timeout:                     10
+    http_headers:
+      - X-OTel-Header-1:         "OTLP HTTP traces test header #1"
+      - X-OTel-Header-2:         "OTLP HTTP traces test header #2"
+    max_concurrent_requests:     64
+    max_requests_per_connection: 8
+    ssl_insecure_skip_verify:    true
+#   ssl_ca_cert_path:            ""
+#   ssl_ca_cert_string:          ""
+#   ssl_client_key_path:         ""
+#   ssl_client_key_string:       ""
+#   ssl_client_cert_path:        ""
+#   ssl_client_cert_string:      ""
+#   ssl_min_tls:                 ""
+#   ssl_max_tls:                 ""
+#   ssl_cipher:                  ""
+#   ssl_cipher_suite:            ""
+#   compression:                 ""
+
+  exporter_traces_dev_null:
+    type:     ostream
+    filename: /dev/null
+
+  exporter_traces_ostream:
+    type:     ostream
+    filename: __optctx_traces
+
+  exporter_traces_memory:
+    type:        memory
+    buffer_size: 256
+
+  exporter_traces_zipkin:
+    type:           zipkin
+    endpoint:       "http://localhost:9411/api/v2/spans";
+    format:         json
+    service_name:   "zipkin-service"
+#   ipv4:           ""
+#   ipv6:           ""
+
+  exporter_metrics_otlp_file:
+    type:           otlp_file
+    thread_name:    "OTLP/file metr"
+    file_pattern:   "__optctx_metrics_log-%F-%N"
+    alias_pattern:  "__metrics_log-latest"
+    flush_interval: 30000000
+    flush_count:    256
+    file_size:      134217728
+    rotate_size:    5
+
+  exporter_metrics_otlp_grpc:
+    type:                otlp_grpc
+    thread_name:         "OTLP/gRPC metr"
+    endpoint:            "http://localhost:4317/v1/metrics";
+    use_ssl_credentials: false
+
+  exporter_metrics_otlp_http:
+    type:                        otlp_http
+    thread_name:                 "OTLP/HTTP metr"
+    endpoint:                    "http://localhost:4318/v1/metrics";
+    content_type:                json
+    debug:                       false
+    timeout:                     10
+    http_headers:
+      - X-OTel-Header-1:         "OTLP HTTP metrics test header #1"
+      - X-OTel-Header-2:         "OTLP HTTP metrics test header #2"
+    max_concurrent_requests:     64
+    max_requests_per_connection: 8
+    ssl_insecure_skip_verify:    true
+
+  exporter_metrics_dev_null:
+    type:     ostream
+    filename: /dev/null
+
+  exporter_metrics_ostream:
+    type:     ostream
+    filename: __optctx_metrics
+
+  exporter_metrics_memory:
+    type:        memory
+    buffer_size: 256
+
+  exporter_logs_otlp_file:
+    type:           otlp_file
+    thread_name:    "OTLP/file logs"
+    file_pattern:   "__optctx_logs_log-%F-%N"
+    alias_pattern:  "__logs_log-latest"
+    flush_interval: 30000000
+    flush_count:    256
+    file_size:      134217728
+    rotate_size:    5
+
+  exporter_logs_otlp_grpc:
+    type:                otlp_grpc
+    thread_name:         "OTLP/gRPC logs"
+    endpoint:            "http://localhost:4317/v1/logs";
+    use_ssl_credentials: false
+
+  exporter_logs_otlp_http:
+    type:                        otlp_http
+    thread_name:                 "OTLP/HTTP logs"
+    endpoint:                    "http://localhost:4318/v1/logs";
+    content_type:                json
+    debug:                       false
+    timeout:                     10
+    http_headers:
+      - X-OTel-Header-1:         "OTLP HTTP logs test header #1"
+      - X-OTel-Header-2:         "OTLP HTTP logs test header #2"
+    max_concurrent_requests:     64
+    max_requests_per_connection: 8
+    ssl_insecure_skip_verify:    true
+
+  exporter_logs_dev_null:
+    type:     ostream
+    filename: /dev/null
+
+  exporter_logs_ostream:
+    type:     ostream
+    filename: __optctx_logs
+
+  exporter_logs_elasticsearch:
+    type:             elasticsearch
+    host:             localhost
+    port:             9200
+    index:            logs
+    response_timeout: 30
+    debug:            false
+    http_headers:
+      - X-OTel-Header-1: "Elasticsearch logs test header #1"
+      - X-OTel-Header-2: "Elasticsearch logs test header #2"
+
+readers:
+  reader_metrics:
+    thread_name:     "reader metr"
+    export_interval: 10000
+    export_timeout:  5000
+
+samplers:
+  sampler_traces:
+#   type:  always_on
+#   type:  always_off
+#   type:  trace_id_ratio_based
+#   ratio: 1.0
+    type:     parent_based
+    delegate: always_on
+
+processors:
+  processor_traces_batch:
+    type:                  batch
+    thread_name:           "proc/batch trac"
+    # Note: when the queue is half full, a preemptive notification is sent
+    # to start the export call.
+    max_queue_size:        2048
+    # Time interval (in ms) between two consecutive exports
+    schedule_delay:        5000
+    # Export 'max_export_batch_size' after every `schedule_delay' milliseconds.
+    max_export_batch_size: 512
+
+  processor_traces_single:
+    type:                  single
+
+  processor_logs_batch:
+    type:                  batch
+    thread_name:           "proc/batch logs"
+    max_queue_size:        2048
+    schedule_delay:        5000
+    max_export_batch_size: 512
+
+  processor_logs_single:
+    type:                  single
+
+providers:
+  provider_traces:
+    resources:
+      - service.version:     "1.0.0"
+      - service.instance.id: "id-optctx"
+      - service.name:        "optctx"
+      - service.namespace:   "HAProxy traces test"
+
+  provider_metrics:
+    resources:
+      - service.version:     "1.0.0"
+      - service.instance.id: "id-optctx"
+      - service.name:        "optctx"
+      - service.namespace:   "HAProxy metrics test"
+
+  provider_logs:
+    resources:
+      - service.version:     "1.0.0"
+      - service.instance.id: "id-optctx"
+      - service.name:        "optctx"
+      - service.namespace:   "HAProxy logs test"
+
+signals:
+  traces:
+    default:
+      scope_name: "HAProxy OTEL - traces"
+      exporters:  exporter_traces_otlp_http
+      samplers:   sampler_traces
+      processors: processor_traces_batch
+      providers:  provider_traces
+
+  metrics:
+    default:
+      scope_name: "HAProxy OTEL - metrics"
+      exporters:  exporter_metrics_otlp_http
+      readers:    reader_metrics
+      providers:  provider_metrics
+
+  logs:
+    default:
+      scope_name: "HAProxy OTEL - logs"
+      exporters:  exporter_logs_otlp_http
+      processors: processor_logs_batch
+      providers:  provider_logs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/run-optctx.sh 
new/haproxy-opentelemetry-2.3.0+git2.b031728/test/run-optctx.sh
--- old/haproxy-opentelemetry-2.3.0+git0.4d52326/test/run-optctx.sh     
1970-01-01 01:00:00.000000000 +0100
+++ new/haproxy-opentelemetry-2.3.0+git2.b031728/test/run-optctx.sh     
2026-10-09 21:43:34.232746274 +0200
@@ -0,0 +1 @@
+symbolic link to run-test-config.sh

Reply via email to