]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: h2: reject again empty :path pseudo-headers
authorWilly Tarreau <w@1wt.eu>
Wed, 26 Feb 2020 12:51:38 +0000 (13:51 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 26 Feb 2020 12:56:24 +0000 (13:56 +0100)
Since commit 92919f7fd5 ("MEDIUM: h2: make the request parser rebuild
a complete URI") we make sure to rebuild a complete URI. Unfortunately
the test for an empty :path pseudo-header that is mandated by #8.1.2.3
appened to be performed on the URI before this patch, which is never
empty anymore after being rebuilt, causing h2spec to complain :

  8. HTTP Message Exchanges
    8.1. HTTP Request/Response Exchange
      8.1.2. HTTP Header Fields
        8.1.2.3. Request Pseudo-Header Fields
          - 1: Sends a HEADERS frame with empty ":path" pseudo-header field
            -> The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
               Expected: GOAWAY Frame (Error Code: PROTOCOL_ERROR)
                         RST_STREAM Frame (Error Code: PROTOCOL_ERROR)
                         Connection closed
                 Actual: DATA Frame (length:0, flags:0x01, stream_id:1)

It's worth noting that this error doesn't trigger when calling h2spec
with a timeout as some scripts do, which explains why it wasn't detected
after the patch above.

This fixes one half of issue #471 and should be backported to 2.1.

src/h2.c

index c5307d9a0aca71aa072dc12375bd2c505db7469f..fa118689a9d3a3555201146291322983f87fad7f 100644 (file)
--- a/src/h2.c
+++ b/src/h2.c
@@ -239,6 +239,9 @@ static struct htx_sl *h2_prepare_htx_reqline(uint32_t fields, struct ist *phdr,
                 * use the trash to concatenate them since all of them MUST fit
                 * in a bufsize since it's where they come from.
                 */
+               if (unlikely(!phdr[H2_PHDR_IDX_PATH].len))
+                       goto fail;   // 7540#8.1.2.3: :path must not be empty
+
                uri = ist2bin(trash.area, phdr[H2_PHDR_IDX_SCHM]);
                istcat(&uri, ist("://"), trash.size);
                istcat(&uri, phdr[H2_PHDR_IDX_AUTH], trash.size);