Re: HTTP/2 Upgrade with content?

Amos Jeffries <> Fri, 13 March 2015 10:48 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id 2A3B01A012D for <>; Fri, 13 Mar 2015 03:48:02 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -6.912
X-Spam-Status: No, score=-6.912 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=ham
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id W6T4-p1VKsBd for <>; Fri, 13 Mar 2015 03:47:58 -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 E92E51A00E5 for <>; Fri, 13 Mar 2015 03:47:56 -0700 (PDT)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1YWN4S-0001mf-15 for; Fri, 13 Mar 2015 10:44:00 +0000
Resent-Date: Fri, 13 Mar 2015 10:44:00 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtp (Exim 4.80) (envelope-from <>) id 1YWN4K-0001kA-R8 for; Fri, 13 Mar 2015 10:43:52 +0000
Received: from ([] by with esmtp (Exim 4.72) (envelope-from <>) id 1YWN4J-0007Qy-Gv for; Fri, 13 Mar 2015 10:43:52 +0000
Received: from [] ( []) by (Postfix) with ESMTP id 776A7E6EBD for <>; Fri, 13 Mar 2015 23:43:18 +1300 (NZDT)
Message-ID: <>
Date: Fri, 13 Mar 2015 23:43:11 +1300
From: Amos Jeffries <>
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0
MIME-Version: 1.0
References: <> <> <20150313094242.GA16018@LK-Perkele-VII>
In-Reply-To: <20150313094242.GA16018@LK-Perkele-VII>
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-3.4
X-W3C-Hub-Spam-Report: AWL=-3.417, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, TVD_RCVD_IP=0.001
X-W3C-Scan-Sig: 1YWN4J-0007Qy-Gv 28c3ee0fcf1c1f734f043672d163ca76
Subject: Re: HTTP/2 Upgrade with content?
Archived-At: <>
X-Mailing-List: <> archive/latest/28957
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

On 13/03/2015 10:42 p.m., Ilari Liusvaara wrote:
> On Fri, Mar 13, 2015 at 04:28:46AM -0400, Jason T. Greene wrote:
>> What about draining the content and after the 101 the h2 response
>> sends a 307?
> Might work if you never send a 100 (including implicitly by waiting
> too long). 100-Continue may mean that the data transfer can't
> be retried after it starts.
> And if the client app is has simplistic redirect checking (just
> count redirects), one could even 307 to self...
> I.e, as flow:
> - POST to foo (with upgrade to h2c and 100-expect)
> - 101 to h2c
> - 307 to foo

 - <complete payload in 1.x format dumped into the pipe>

> - POST to foo (with 100-expect)
> - 100
> - <payload>
> - 200
> -Ilari

No matter what you do the client has started sending a request specifid
as having a payload in HTTP/1 format. It must finish that request,
including the payload it promised, before any HTTP/2 may happen.
 - if the client is smart it would use chunked encoding then abandon
with 0-sized chunk on seeing the 30x. But that has other nasty problems,
and servers cant rely on it.

All these 30x tricks do is allow you to bit-bucket the 1.x payload
before moving on to the hopefully repeated 2.0 format one. It still
"blocks the connection" while the drain is happening - which may be GB
or TB of bandwidth and duration.

We have some prior painful experience applicable from NTLM vs POST
requests. In all cases there is large bandwidth wastage and latency.

However, that "blocking the connection" only means that the *client*
can't send other requests in parallel or h2 control frames. The server
is still free to PUSH_PROMISE etc. about what will follow once that 1.x
payload is done.

IMHO its actually simpler to implement a 1.1->2.0 converter and use it
as if it were a bit-bucket handler for the initial payload than to
handle all the edges cases involved when avoiding 1.x. Still not nice,
but simpler than any fancy dances with a mandatory bit-bucket anyway.

There is also the possibility of just using 2.0 natively from the start.
Manual tools and web apps with server knowledge should have no problems
just using 2.0 when they know the other end is.