]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux_h2: generate Extended CONNECT response
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 11 Dec 2020 16:53:08 +0000 (17:53 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 28 Jan 2021 15:37:14 +0000 (16:37 +0100)
Support for the rfc 8441 Bootstraping WebSockets with HTTP/2

Convert a 101 htx response message to a 200 HTTP/2 response.

src/mux_h2.c

index 25cf98ebcb78013c575d6417f82ae373009ba641..1fc6ca0b897f95abf685f5477f530bc8b7f34a75 100644 (file)
@@ -194,6 +194,7 @@ enum h2_ss {
 #define H2_SF_KILL_CONN         0x00020000  // kill the whole connection with this stream
 
 #define H2_SF_EXT_CONNECT_SENT  0x00040000  // rfc 8441 an Extended CONNECT has been sent
+#define H2_SF_EXT_CONNECT_RCVD  0x00080000  // rfc 8441 an Extended CONNECT has been received and parsed
 
 #define H2_SF_TUNNEL_ABRT       0x00100000  // A tunnel attempt was aborted
 
@@ -4733,6 +4734,9 @@ next_frame:
                htx->flags |= HTX_FL_EOM;
        }
 
+       if (msgf & H2_MSGF_EXT_CONNECT)
+               *flags |= H2_SF_EXT_CONNECT_RCVD;
+
        /* success */
        ret = 1;
 
@@ -4958,9 +4962,16 @@ static size_t h2s_frt_make_resp_headers(struct h2s *h2s, struct htx *htx)
                                goto fail;
                        }
                        else if (h2s->status == 101) {
-                               /* 101 responses are not supported in H2, so return a error (RFC7540#8.1.1) */
-                               TRACE_ERROR("will not encode an invalid status code", H2_EV_TX_FRAME|H2_EV_TX_HDR|H2_EV_H2S_ERR, h2c->conn, h2s);
-                               goto fail;
+                               if (unlikely(h2s->flags & H2_SF_EXT_CONNECT_RCVD)) {
+                                       /* If an Extended CONNECT has been received, we need to convert 101 to 200 */
+                                       h2s->status = 200;
+                                       h2s->flags &= ~H2_SF_EXT_CONNECT_RCVD;
+                               }
+                               else {
+                                       /* Otherwise, 101 responses are not supported in H2, so return a error (RFC7540#8.1.1) */
+                                       TRACE_ERROR("will not encode an invalid status code", H2_EV_TX_FRAME|H2_EV_TX_HDR|H2_EV_H2S_ERR, h2c->conn, h2s);
+                                       goto fail;
+                               }
                        }
                        else if ((h2s->flags & H2_SF_BODY_TUNNEL) && h2s->status >= 300) {
                                /* Abort the tunnel attempt */