Re: HTTP/2 Upgrade with content?

Greg Wilkins <> Fri, 13 March 2015 01:09 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id E115B1AC3E8 for <>; Thu, 12 Mar 2015 18:09:12 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -6.289
X-Spam-Status: No, score=-6.289 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001, 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 1lE_PHfcIiQb for <>; Thu, 12 Mar 2015 18:09:10 -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 E1A261A8977 for <>; Thu, 12 Mar 2015 18:09:09 -0700 (PDT)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1YWE2h-0000oa-Nc for; Fri, 13 Mar 2015 01:05:35 +0000
Resent-Date: Fri, 13 Mar 2015 01:05:35 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtp (Exim 4.80) (envelope-from <>) id 1YWE2X-0000nX-AN for; Fri, 13 Mar 2015 01:05:25 +0000
Received: from ([]) by with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.72) (envelope-from <>) id 1YWE2V-0005Tm-52 for; Fri, 13 Mar 2015 01:05:25 +0000
Received: by lbiz11 with SMTP id z11so19641420lbi.13 for <>; Thu, 12 Mar 2015 18:04:55 -0700 (PDT)
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:date :message-id:subject:from:to:cc:content-type; bh=xyA9PMYBzUyTwz7k9DRvczKYTBra3AF5I+6GZl9WxQY=; b=L3V9T7b1+bDywaVyGuXIi0DXD9DENIDm2yM8130RHSPIuXjr8ukQO2qAkUTai5JDIM kS+Eh/iltRhEICy6uc4EwgUjCykcLQlTHZNIHYfaQmIa7FNn8O/EZ5EjssDd0XFGUHdY mjDywhOXAm1ee9YhfVPcmQgXq7Wcr4Ph0YrFCFZi+fCQYMZTYYZbKZmpkw23IhemDESR aOlxhLr/ESLVJ3n+RFo1SAltoNgLXfyNgPDRHs59CegkOlkRwH7YzaY8xTndyW2/zeL5 5zm0AP7HWcDLfDRzGEApCHrO/cPc8xECSzNvEvzG0gCEvHRmk1Yg/WRA5CqLbbpTJYrS GNBQ==
X-Gm-Message-State: ALoCoQkuax0wy86Oyb2SNtToaITEQr7zEQuasxG9cXhIjdQPHsytibdx2vUwc5rwFqaui6vVKrvn
MIME-Version: 1.0
X-Received: by with SMTP id n5mr41279806lbk.1.1426208695430; Thu, 12 Mar 2015 18:04:55 -0700 (PDT)
Received: by with HTTP; Thu, 12 Mar 2015 18:04:55 -0700 (PDT)
In-Reply-To: <>
References: <> <>
Date: Fri, 13 Mar 2015 12:04:55 +1100
Message-ID: <>
From: Greg Wilkins <>
To: Mike Bishop <>
Cc: HTTP Working Group <>
Content-Type: multipart/alternative; boundary="001a11349d20aac9f4051121162f"
Received-SPF: permerror client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-3.6
X-W3C-Hub-Spam-Report: AWL=-2.918, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, URIBL_BLOCKED=0.001
X-W3C-Scan-Sig: 1YWE2V-0005Tm-52 8f5e7ef25029a07c43ab24fe780dc46e
Subject: Re: HTTP/2 Upgrade with content?
Archived-At: <>
X-Mailing-List: <> archive/latest/28948
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>


the requirement of 3.2 is different to a normal HTTP/1.1 request.
Normally there is no requirement for a server to buffer the entire request
body before commencing handing of a normal HTTP/1.1 request.    Typically
the application is called and a streaming API used to provide the content
to the request handler.   Note that this is not a block or not to block
question - modern HTTP/1.1 servers are perfectly capable of consuming
content via asynchronous IO.

Thus from the servers point of view, the memory commitment required to
service a single connection is the buffer size that it uses to read the
request content.   Now applications might then aggregate those buffers and
attempt to hold the entire content in memory, but that is an application
responsibility and the server cannot do much about that.

This requirement is different.  It is allowing an arbitrary sized body
content to be sent in the HTTP/1.1 request that must be held by the server
so that it can be fed to the HTTP/2 handling of the request that takes
place after the upgrade and after the 101 has been sent.

I guess technically the new HTTP2 connection could work in a mode where it
receives content as HTTP/1.1 but sends the response as HTTP/2.... but that
is a) stupidly complex for a mechanism that browser say they will not
implement anyway; b) just asking for a deadlock if the response is large
and requires flow control frames to be received that cannot be sent until
the entire body is consumed.

But you point about upgrades failing for all sorts of reasons is a valid
one.  So I agree that 413 is not the right response and that simply
ignoring the upgrade on requests that have too large bodies (or perhaps any
body at all for simplicity), is probably the right thing to do.


On 13 March 2015 at 10:47, Mike Bishop <> wrote:

>  A server is blocked on the connection, just as it would be in HTTP/1.1.
> The situation for the server is no worse than if the client weren’t
> offering Upgrade.  Servers will enforce the same limits of large bodies
> they’re not willing to handle.  Issuing a 413, telling the client that the
> reason their request isn’t being serviced is due to the size of the body,
> is confusing if the actual way to make it be serviced is to omit the
> Upgrade header.  That’s a bizarre use of 413.
> My inclination would be for servers to ignore the Upgrade header if they
> don’t want to be blocked.  Clients will always need to handle Upgrade
> headers being ignored, since they can legitimately be stripped by
> intermediaries.  Clients will never understand all the reasons why some
> Upgrades work and some don’t – they have to handle both cases cleanly.
> *From:* Greg Wilkins []
> *Sent:* Thursday, March 12, 2015 4:10 PM
> *To:* HTTP Working Group
> *Subject:* HTTP/2 Upgrade with content?
> Section 3.2 describes the upgrade to HTTP/2 and it allows support for
> upgrade requests with bodies:
>    Requests that contain an entity body MUST be sent in their entirety
>    before the client can send HTTP/2 frames. This means that a large
>    request entity can block the use of the connection until it is
>    completely sent.
>  Servers will need to protect themselves from DoS attacks via such
> requests as buffering arbitrary large content in their entirety is a
> commitment that servers cannot generally give.
> Thus servers will have to limit the size of the entities they are prepared
> to hold in this situation (and the size of a single normal request buffers
> is probably the memory commitment they are prepared to make for any given
> connection).
> My question is, what should a server do if it receives an otherwise valid
> upgrade request that it could handle but with content that exceeds this
> memory limit?      Should it respond with a 413 REQUEST_ENTITY_TOO_LARGE or
> should it just ignore the upgrade and let the request be handled via
> HTTP/1.1 (which can stream the content into the request handler and it
> becomes somebody else's problem to limit memory usage).
> My problem with ignoring the upgrade is that it is an arbitrary limit and
> it will be hard for clients to tell why some upgrades work and others do
> not.
> Alternately my problem with 413 is that some servers might wish to avoid
> the whole upgrade with content path and thus send a 413 for any upgrade
> with content, which may break some clients that could otherwise proceed
> with HTTP/1.1
> thoughts?
> PS. in hindsight, I would rather that we had not allowed upgrades with
> content and instead told clients to upgrade with an OPTION request prior to
> any PUT/POST request.... gallop... gallop... gallop.... SLAM!
> --
> Greg Wilkins <>  @  Webtide - *an Intalio subsidiary*
> HTTP, SPDY, Websocket server and client that
> scales
>  advice and support for jetty and cometd.

Greg Wilkins <>  @  Webtide - *an Intalio subsidiary* HTTP, SPDY, Websocket server and client that scales  advice and support for jetty and cometd.