Re: Design: Ignored Unknown Frame Types and Intermediaries

James M Snell <> Tue, 14 May 2013 15:02 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 97FF421F856D for <>; Tue, 14 May 2013 08:02:24 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -9.818
X-Spam-Status: No, score=-9.818 tagged_above=-999 required=5 tests=[AWL=0.781, BAYES_00=-2.599, RCVD_IN_DNSWL_HI=-8]
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id xHsOuEw59CAp for <>; Tue, 14 May 2013 08:02:18 -0700 (PDT)
Received: from ( []) by (Postfix) with ESMTP id 85DA721F8709 for <>; Tue, 14 May 2013 08:02:17 -0700 (PDT)
Received: from lists by with local (Exim 4.72) (envelope-from <>) id 1UcGjV-0008Eh-Jr for; Tue, 14 May 2013 15:01:41 +0000
Resent-Date: Tue, 14 May 2013 15:01:41 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtp (Exim 4.72) (envelope-from <>) id 1UcGjJ-00082Y-Ka for; Tue, 14 May 2013 15:01:29 +0000
Received: from ([]) by with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.72) (envelope-from <>) id 1UcGjE-0003QD-WF for; Tue, 14 May 2013 15:01:29 +0000
Received: by with SMTP id un3so672798obb.33 for <>; Tue, 14 May 2013 08:00:59 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20120113; h=x-received:mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type:content-transfer-encoding; bh=y5M9cWiRlDtfNTzDomVOr08Sdng/XiT6U5iAMRGYYwc=; b=q3j0jLaPGWF8ddJAqS2FiVRYgM1FqUc4/9vBgPeixf7v/RunKnlfMJNRayyp1ziYMP cynnsMMFX1mKV2b6PpGYUhIQKMcUA/h2pdFFJyXctkFM/znZ//6d1Xk6KVQYqinaUpyc USImnhqPxv9KMhXIkkXVQlXx2FPuxJdP55i+4YfQxnoo26EmJtWsSiWEzodefZF+8SZm ntaUSnq6VO3c9A6ezSt+v8uYbswmpn7nRg83pdhWX0k1yBuwqJK2MpUt60Y7ZoYe+FIR Pke3qQOQ2ksEyvo3cLEcv0FK1y4Qz0P9Wrz9Pl2EIoncAE67zZfsPinmK9XWdZsajRW3 mV+w==
X-Received: by with SMTP id xy6mr14704617obc.1.1368543658940; Tue, 14 May 2013 08:00:58 -0700 (PDT)
MIME-Version: 1.0
Received: by with HTTP; Tue, 14 May 2013 08:00:38 -0700 (PDT)
In-Reply-To: <>
References: <> <> <> <> <> <> <> <> <> <> <> <> <>
From: James M Snell <>
Date: Tue, 14 May 2013 08:00:38 -0700
Message-ID: <>
To: Yoav Nir <>
Cc: Albert Lunde <>, "" <>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-3.5
X-W3C-Hub-Spam-Report: AWL=-2.702, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001
X-W3C-Scan-Sig: 1UcGjE-0003QD-WF 1062933eecf6428d9e9d648732711533
Subject: Re: Design: Ignored Unknown Frame Types and Intermediaries
Archived-At: <>
X-Mailing-List: <> archive/latest/17990
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

I personally think that's getting all too complicated. It ought to be
very simple.

1. The middlebox can choose to ignore extension frames and pass them
thru untouched, or
2. The middlebox can choose to reject extension frames, in which case
it rejects the remainder of the stream using an RST_STREAM with a
specific error code.

If a client receives an RST_STREAM[UNSUPPORTED_FRAME] error, the
connection remains intact but that one extended stream is closed.
That's really not that big of a deal, the client can fall back to some
alternative behavior or just give up. There's nothing wrong with that.
No negotiation is required, and I don't need to know in advance
whether something is going to work or not.

Which, btw, is EXACTLY how things work today... I can send, for
instance, a PATCH request to any server I want. When I do, I have
absolutely no guarantees that some piece of middleware in the path is
going to let that method thru... I just have to be prepared to deal
with the possible "Method Not Allowed" response.

The range types that I suggested (CONTROL vs. DATA frames) do not
require that we keep track of any kind of proxy. Consider, in HTTP/1
today we already have the notion of Hop-by-hop headers and end-to-end
headers. We specifically define that some headers are connection
specific and MUST NOT be forwarded, and we specifically define that
some headers MUST always be forwarded. What I'm suggesting is
absolutely no different than this... only instead of using a header to
define which items are end-to-end vs. connection-specific, we would
just use a range of type codes.

These kinds of distinctions ALREADY exist in HTTP/1 and do not, imho,
add unwarranted complexity to HTTP/2. No negotiation is required, no
tracking table of who supports what is required, no prior knowledge of
what kinds of proxies are deployed in the path are required...
extension frames are either passed thru or the whole stream is
rejected; it either works or it doesn't. Simple.

The issue of whether or not extension frames ought to be flow
controlled is very closely related to this, which is another
justification for the CONTROL vs. DATA frame distinction. We cannot
predict exactly how extension frames will be defined. Some may be
intended to provide *optional* extension to the connection -- for
instance, a checksum frame that provides an ok-to-ignore hash of
previously received frames. Some may be intended to provide structured
application data as opposed to just using a DATA frame blob. It stands
to reason that some extension frames might make sense to flow control
while others do not.

- James

On Tue, May 14, 2013 at 7:36 AM, Yoav Nir <> wrote:
> On May 14, 2013, at 4:39 PM, Albert Lunde <> wrote:
>> On 5/14/2013 4:46 AM, Yoav Nir wrote:
>>> But I agree that we should limit what non-version-changing extensions
>>> are allowed to do. We should require that if the extension is either
>>> ignored by the recipient or removed by a middlebox, no harm would be
>>> done (except the new functionality not working)
>> It's hard to tell if an extension may be safely ignored at the protocol level.  Would there be any use in having a "critical extension" bit, indicating an extension frame that must not be silently dropped by intermediaries or ignored by the destination server?
> I don't know. If you send a critical extension to an old(*) server, it's going to reset the stream or the connection. If you send a critical extension through an old firewall, it will reset your stream or connection, so that the new extension would sometimes work and sometimes won't.
> Any proxy other than a firewall cannot tell whether the critical extension is something that should affect it or not. So it has the choice of resetting the stream (which goes against the design goal of such proxies to be as transparent to the client as possible) or it could forward the frame, which is equivalent to ignoring it. There is no way to know if it should have changed its behavior because of that ignored frame.
> So you could have two bits, one as your described, and the other for whether an intermediary can ignore it (similar to the ranges of types that James suggested). But that assumes that whoever designs these extensions knows about all the kinds of proxies that exist, and what is relevant for them.
> We could have some kind of negotiation on extension capability in the SETTINGS frame, and explicitly allow middleware to remove capabilities that they don't support to prevent their use. But if we've gone to negotiate it at the start, I can see Roberto's point that we might as well negotiate it in version strings.
> Yoav
> (*) "old" means a server conforming to the base HTTP/2.0 specification