HTTP/2: Race between PUSH_PROMISE and exclusive PRIORITY

Tom Bergan <> Thu, 15 September 2016 23:36 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id EC27512B0C2 for <>; Thu, 15 Sep 2016 16:36:34 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -8.527
X-Spam-Status: No, score=-8.527 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_SORBS_SPAM=0.001, RP_MATCHES_RCVD=-1.508, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (1024-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 11dTwvtjOSrC for <>; Thu, 15 Sep 2016 16:36:33 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 1943312B0BC for <>; Thu, 15 Sep 2016 16:36:32 -0700 (PDT)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1bkg8Y-0003Vi-CX for; Thu, 15 Sep 2016 23:32:10 +0000
Resent-Date: Thu, 15 Sep 2016 23:32:10 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1bkg8R-0003UI-OV for; Thu, 15 Sep 2016 23:32:03 +0000
Received: from ([]) by with esmtps (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1bkg8P-0008Jk-W0 for; Thu, 15 Sep 2016 23:32:03 +0000
Received: by with SMTP id q92so8325244ioi.1 for <>; Thu, 15 Sep 2016 16:31:41 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=google; h=mime-version:from:date:message-id:subject:to; bh=caZsXF/BJKV52KGpmCjx04B0zkn4dYb+640CEbxnn2o=; b=dpHIKDkt5XnCpaqzIh9TuMEl///37hIRH+Q4N6qr0igXZhXBVn1blZgJo2vlqNlJSi wWo2IQhP/kMtjqYwd9RHJrd18zbXKiTzQiUEcVkNaHpakJwfnYtG86aYC1n7xGRqduj6 04/sqxcsBeYYC5W7YiOlwur4XbdD/cCTJtlEI=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=caZsXF/BJKV52KGpmCjx04B0zkn4dYb+640CEbxnn2o=; b=P50o/D2hwrTnpwHZ3wD2MnR/mTlNC0oJHcOPx49hwvWIa4bGX6FpZjyKYco6gQ7Gtj tbCrKaL1K/oUO5dcbo6KRf92hGmKBsj3xcBuAB1XqTovq1MLFkHMwbBtgTdymoG8dFbn EBa+RUF5Oo/P7xaf233fIBL82+KNC5+5FeFqwCLr53G4sSyUZNt1RZ9uhxf4NYKCcCzC mrMOyDZ5hDdKkEc9zsmmKASZLGyvDJrM5QSPbW5Xi56hh2mh7gFOHKfYEZlrTwV8gECt YrmkKSSpVQZ0frw75SysfWLUxBk14ju/Gtl2aRHg37D3jaf7NYHbL6/T0iEG5EmKtz87 Q7Pw==
X-Gm-Message-State: AE9vXwOkH+qryQJKMkhiPNJ++QdjX270S+Wf/sKPJ7F3gTRTBAXPkRGT+QaXopYITKbO3y7b
X-Received: by with SMTP id a201mr20159868ioa.23.1473982294820; Thu, 15 Sep 2016 16:31:34 -0700 (PDT)
Received: from ( []) by with ESMTPSA id e65sm2631484ioi.3.2016. for <> (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Sep 2016 16:31:34 -0700 (PDT)
Received: by with SMTP id m79so8346710ioo.3 for <>; Thu, 15 Sep 2016 16:31:33 -0700 (PDT)
X-Received: by with SMTP id z143mr20021734ioz.190.1473982293393; Thu, 15 Sep 2016 16:31:33 -0700 (PDT)
MIME-Version: 1.0
Received: by with HTTP; Thu, 15 Sep 2016 16:31:32 -0700 (PDT)
From: Tom Bergan <>
Date: Thu, 15 Sep 2016 16:31:32 -0700
X-Gmail-Original-Message-ID: <>
Message-ID: <>
To: HTTP Working Group <>
Content-Type: multipart/alternative; boundary=001a11441aa001184c053c943fe2
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-5.2
X-W3C-Hub-Spam-Report: AWL=-1.010, BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_SORBS_SPAM=0.5, SPF_PASS=-0.001, W3C_AA=-1, W3C_WL=-1
X-W3C-Scan-Sig: 1bkg8P-0008Jk-W0 b06d4e2f081718321276392fb87d6b50
Subject: HTTP/2: Race between PUSH_PROMISE and exclusive PRIORITY
Archived-At: <>
X-Mailing-List: <> archive/latest/32407
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

I believe the following example has a race:

1. Server receives request A.
2. Server sends PUSH_PROMISE frames for B, C, D.
3. Client sends PRIORITY to make B the exclusive parent of C
4. Server receives that PRIORITY frame.

After step 2, the server's local priority tree is A -> {B,C,D}, due to the
default priority rules in RFC 7540 Section 5.3.5. At step 4, the server
cannot know if the client has received the PUSH_PROMISE for D yet. This
makes it ambiguous whether the client intended the tree to be A -> B ->
{C,D} or A -> {B->C, D}. I believe this race can happen any time a
PUSH_PROMISE and exclusive PRIORITY can pass each other on the wire. I
think the race is impossible for non-exclusive PRIORITYs.

This is the simplest example of the race, but it's admittedly strange that
the client would send that specific PRIORITY frame. Here's slightly more
complex, but less strange example:

1. Client requests A then B, where B's HEADERS frame makes A the exclusive
parent of B
2. Server receives request A
3. Server sends PUSH_PROMISE frames for C, D.
4. Server receives request B
5. Client receives PUSH_PROMISE frames for C, D

At each step, the priority trees are updated like this:

1. Client's tree is A -> B
2. Server's tree is A
3. Server's tree is A -> {C,D}
4. Server's tree is A -> B -> {C,D}
5. Client's tree is A -> {B,C,D}

If steps 3 and 4 are swapped, the client and server will finish with the
same priority tree. As-is, they finish with different priority trees.

Does that sound right? If so, is this worth mentioning in some kind of
errata or other note? Apologies if this was brought up previously -- I
searched through the mailing list archives and did not see a mention.