Re: HTTP/2: Race between PUSH_PROMISE and exclusive PRIORITY

Martin Thomson <> Fri, 16 September 2016 00:08 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 6F73112B098 for <>; Thu, 15 Sep 2016 17:08:22 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -8.528
X-Spam-Status: No, score=-8.528 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, 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 (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 1jJ3JjfsyErg for <>; Thu, 15 Sep 2016 17:08:21 -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 EEBB712B09B for <>; Thu, 15 Sep 2016 17:08:20 -0700 (PDT)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1bkgdf-0000Yi-B3 for; Fri, 16 Sep 2016 00:04:19 +0000
Resent-Date: Fri, 16 Sep 2016 00:04:19 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1bkgdY-0000XB-Cv for; Fri, 16 Sep 2016 00:04:12 +0000
Received: from ([]) by with esmtps (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1bkgdT-0003lz-Pl for; Fri, 16 Sep 2016 00:04:11 +0000
Received: by with SMTP id h8so68673618qka.1 for <>; Thu, 15 Sep 2016 17:03:47 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=5J6CgFU7TBrOsUF+5oStnrKlXksum0yNAiiClSy0VK4=; b=KNGXfs6kKh11vLYCIjEWT1DW5RLBLPcqETn2F9NI/ffolsFizfGccUswfkDEmaxumE xyt86Z5y7+c8F7enTh6PsAOBpD1c1dGnqqvGS+qxgjFtu1pKKCQVVAsBOKGFyl/QgJZi YGlSseSHYjgNezvlTM/y4OdGg5JNJuvStNMt49AAoDSt9hdGX9O4dri1mQxq3O7vqgZu ruSupUt+1xqem5/D+ZyHB63uSJQbKNidPg9c6+FVl0aMM2diadl2iemRczLaVCtZD2fc nuJ0W1sATzqFiYJrYXYCpmCHmIG0NeLckhA0KxGzRxdrGDsn8n/I8j/BoSaIdQCuU1xe hPeQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=5J6CgFU7TBrOsUF+5oStnrKlXksum0yNAiiClSy0VK4=; b=kG88y7iOVSLN6Cnu94GPCFfUFFX4zcnuZ3ilQA5lv0g6CHC2e1gg+kaW29qhWBNq6C YxoB6ULd9/xLVnmbTJf/6anefJ9Z5b8R3RoESAYMBdosgY+sr7MXSc2jtxUARU9sUOV3 SLh/F+70aDrjgR5cYewvWuh9NAerts25cp5moYKK360Y2QJGf3hW6qKAZcdEV238OA1d 4+WKFYXfKvKbwc9WKGBiNlg20FkoqQxv1QMeEWtQ+x7j/Y7O3j+WNeiyTdu3rqP0wE+D 2LXiMdoNWNPDqEV2m83Dc+hMfEo6qIiyLJeK7XDg55c26l13E6IBpYi9CQQnPPYjkH2e yEXg==
X-Gm-Message-State: AE9vXwPhcBgqTmdxI+hXtFeg4RDrW5o3R2LWn4RridRfOgYLBV2qx0w1CDz/ofWVOGXtKW9Z+p6qtK65OasRjQ==
X-Received: by with SMTP id r63mr12555269qka.81.1473984221751; Thu, 15 Sep 2016 17:03:41 -0700 (PDT)
MIME-Version: 1.0
Received: by with HTTP; Thu, 15 Sep 2016 17:03:41 -0700 (PDT)
In-Reply-To: <>
References: <>
From: Martin Thomson <>
Date: Thu, 15 Sep 2016 17:03:41 -0700
Message-ID: <>
To: Tom Bergan <>
Cc: HTTP Working Group <>
Content-Type: text/plain; charset=UTF-8
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-7.6
X-W3C-Hub-Spam-Report: AWL=1.582, BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_SORBS_SPAM=0.5, SPF_PASS=-0.001, W3C_AA=-1, W3C_DB=-1, W3C_IRA=-1, W3C_IRR=-3, W3C_WL=-1
X-W3C-Scan-Sig: 1bkgdT-0003lz-Pl 545106122d41bfef6c831901ed260c0c
Subject: Re: HTTP/2: Race between PUSH_PROMISE and exclusive PRIORITY
Archived-At: <>
X-Mailing-List: <> archive/latest/32408
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

Hey Tom,

This is a good bug.  I think that we built the exclusive thing without
considering that possibility.  The problem is that there is no knowing
what streams the sender of priority frame knew about when they send
the PRIORITY frame.

The same problem exists for PRIORITY sent by the server, but that's
far less of a problem because we don't see anyone using that (or if
they do, we don't agree on what that means).

A simple "fix" here is to prohibit PRIORITY+exclusive from affecting
streams that haven't been "mentioned" by the endpoint sending
PRIORITY.  That is, each endpoint maintains a watermark (for both odd
and even stream numbers) that increases every time they receive a
frame from their peer and any stream number below that is assumed to
be known to the other side.  That means tracking mentions though,
which is a little cumbersome.


On 15 September 2016 at 16:31, Tom Bergan <> wrote:
> 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.
> -Tom