Subject: Issue 240: Migrate Upgrade details from RFC2817

From: Julian Reschke <[email-masked]>
Date: Thu, 28 Oct 2010 15:55:39 +0200

Hi,

quoting the issue:

"RFC2817 contains advice and details about how Upgrade works in HTTP; 
e.g., the 426 status code, and the upgrade token registry."

We already took over the upgrade token registry in draft -07, see 
<http://trac.tools.ietf.org/wg/httpbis/trac/ticket/172>.

This leaves us with:

1) Extending the definition of "Upgrade", and

2) Defining 426.

With respect to 1, let's have a look at 
<http://greenbytes.de/tech/webdav/rfc2817.html#rfc.section.4.1>:

> 4.1 Optional Advertisement
>
> As specified in HTTP/1.1 [1], the server MAY include an Upgrade header in any response other than 101 or 426 to indicate a willingness to switch to any (combination) of the protocols listed.

 From my reading of 2616 and P1, this is partly wishful thinking. 
<http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-12.html#rfc.section.9.8> 
says:

> 9.8 Upgrade
>
> The "Upgrade" general-header field allows the client to specify what additional communication protocols it would like to use, if the server chooses to switch protocols. Additionally, the server MUST use the Upgrade header field within a 101 (Switching Protocols) response to indicate which protocol(s) are being switched to.

...but it doesn't really say what Upgrade means in responses other than 
101. I assume we are ok with adopting the RFC 2817 interpretation?

With respect to 2):

<http://greenbytes.de/tech/webdav/rfc2817.html#rfc.section.4.2> says:

"4.2 Mandatory Advertisement

A server MAY indicate that a client request can not be completed without 
TLS using the "426 Upgrade Required" status code, which MUST include an 
an Upgrade header field specifying the token of the required TLS version.

     HTTP/1.1 426 Upgrade Required
     Upgrade: TLS/1.0, HTTP/1.1
     Connection: Upgrade

The server SHOULD include a message body in the 426 response which 
indicates in human readable form the reason for the error and describes 
any alternative courses which may be available to the user."

This would need to be a bit rephrased to remove the TLS stuff.

Here are the proposed changes:

Part 1, Upgrade:

"The "Upgrade" general-header field allows the client to specify what 
additional communication protocols it would like to use, if the server 
chooses to switch protocols. Additionally, the server MUST use the 
Upgrade header field within a 101 (Switching Protocols) response to 
indicate which protocol(s) are being switched to."

-->

"The "Upgrade" general-header field allows the client to specify what 
additional communication protocols it would like to use, if the server 
chooses to switch protocols.

Servers MAY include the "Upgrade" header field in any response other 
than 101 (Switching Protocols) or 426 (Upgrade Required) to indicate 
that they are willing to upgrade to one of the specified protocols.

Servers MUST include it in 101 (Switching Protocols) responses to 
indicate which protocol(s) are being switched to, and MUST include it in 
426 (Upgrade Required) responses to indicate acceptable protocols to 
upgrade to."

Part 2, add Status 426 as:

"8.4.19 426 Upgrade Required

The request can not be completed without a prior protocol upgrade. This 
response MUST include an Upgrade header field specifying the tokens of 
the required protocol.

Example:

     HTTP/1.1 426 Upgrade Required
     Upgrade: HTTP/2.0
     Connection: Upgrade

The server SHOULD include a message body in the 426 response which 
indicates in human readable form the reason for the error and describes 
any alternative courses which may be available to the user."

Question: what exactly would it mean if the Upgrade header in a 426 
response contains multiple tokens? Are all of them required, or can the 
client pick one?

Best regards, Julian

---

From: Julian Reschke <[email-masked]>
Date: Sat, 30 Oct 2010 19:05:39 +0200

OK,

I have made the following changes in 
<http://trac.tools.ietf.org/wg/httpbis/trac/changeset/1071>:

P1: rephrase definition of Upgrade header field so that it states the 
semantics for status codes != 101:

-- snip --
9.8.  Upgrade

    The "Upgrade" general-header field allows the client to specify what
    additional communication protocols it would like to use, if the
    server chooses to switch protocols.  Servers can use it to indicate
    what protocols they are willing to switch to.

      Upgrade   = "Upgrade" ":" OWS Upgrade-v
      Upgrade-v = 1#product

    For example,

      Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11

    The Upgrade header field is intended to provide a simple mechanism
    for transition from HTTP/1.1 to some other, incompatible protocol.
    It does so by allowing the client to advertise its desire to use
    another protocol, such as a later version of HTTP with a higher major
    version number, even though the current request has been made using
    HTTP/1.1.  This eases the difficult transition between incompatible
    protocols by allowing the client to initiate a request in the more
    commonly supported protocol while indicating to the server that it
    would like to use a "better" protocol if available (where "better" is
    determined by the server, possibly according to the nature of the
    method and/or resource being requested).

    The Upgrade header field only applies to switching application-layer
    protocols upon the existing transport-layer connection.  Upgrade
    cannot be used to insist on a protocol change; its acceptance and use
    by the server is optional.  The capabilities and nature of the
    application-layer communication after the protocol change is entirely
    dependent upon the new protocol chosen, although the first action
    after changing the protocol MUST be a response to the initial HTTP
    request containing the Upgrade header field.

    The Upgrade header field only applies to the immediate connection.
    Therefore, the upgrade keyword MUST be supplied within a Connection
    header field (Section 9.1) whenever Upgrade is present in an HTTP/1.1
    message.

    The Upgrade header field cannot be used to indicate a switch to a
    protocol on a different connection.  For that purpose, it is more
    appropriate to use a 3xx redirection response (Section 8.3 of
    [Part2]).

    Servers MUST include the "Upgrade" header field in 101 (Switching
    Protocols) responses to indicate which protocol(s) are being switched
    to, and MUST include it in 426 (Upgrade Required) responses to
    indicate acceptable protocols to upgrade to.  Servers MAY include it
    in any other response to indicate that they are willing to upgrade to
    one of the specified protocols.

    This specification only defines the protocol name "HTTP" for use by
    the family of Hypertext Transfer Protocols, as defined by the HTTP
    version rules of Section 2.5 and future updates to this
    specification.  Additional tokens can be registered with IANA using
    the registration procedure defined below.
-- snip --

In Part 2, add definition of status code 426:

-- snip --
8.4.19.  426 Upgrade Required

    The request can not be completed without a prior protocol upgrade.
    This response MUST include an Upgrade header field (Section 9.8 of
    [Part1]) specifying the required protocols.

    Example:

    The server SHOULD include a message body in the 426 response which
    indicates in human readable form the reason for the error and
    describes any alternative courses which may be available to the user.
-- snip --

I believe we are done with ticket 240, and should treat all remaining 
issues as separate bugs...

Feedback appreciated,

Julian

---

From: Adrien de Croy <[email-masked]>
Date: Sun, 31 Oct 2010 11:28:10 +1300

one comment I'd like to make.

When I first read the definition for Upgrade in RFC2616, I switched
off as soon as I saw the word "additional communications protocols"
which didn't make any sense to me.

IMO it should read "alternative communications protocols", since if
the header is acted on, the protocol will be changed to rather than
added.

Also, this is a classic case of why HTTP/1.1 intermediaries MUST
strip headers matching tokens in the Connection header.  It makes me
wonder what will happen if an HTTP/1.0 proxy receives one of these
and forwards it.  Is there a requirement on servers to ignore
upgrade on an HTTP/1.0 request?

I also wonder what an HTTP/2.0 proxy should send upstream when
receiving Upgrade: HTTP/2.0 in an HTTP/1.1 request.

The example is also slightly confusing.

It refers to "Upgrade: HTTP/2.0"

however the registered key-word with the IANA is only "HTTP", and
doesn't include any version number.

I don't see any discussion for the production of "product" in the
BNF for Upgrade, which would need to include version number (as
opposed to it being optional in the product production in S 3.8) in
order for this example to be correct according to the current IANA
registry, or would we need to register a separate value with the
IANA of "HTTP/2.0" (which is in keeping with the way TLS/1.0 is
registered)?  On that note, it may be prudent to consider versioning
in this aspect for WebSocket.  At the very least there is
inconsistency about how the 3 tokens are currently registered, with
TLS including version and the others not.

Without version number, registering the bare "HTTP" token is
probably of little use.  Especially since if the version defines
aspects such as new (incompatible) framing etc, then the version is
a key part of the actual protocol being referred to and can't really
be omitted.  In that sense, if a server received

Upgrade: HTTP

then the only sensible thing to do is ignore it.

It makes me wonder whether the BNF for Upgrade should have referred
to product or some other production requiring version, and being
designed to be the name of a protocol (non-optional version) rather
than the name of a product.  c.f.

product = token ["/" product-version]
product-version = token

Regards

Adrien

On 31/10/2010 6:05 a.m., Julian Reschke wrote:

OK,

P1: rephrase definition of Upgrade header field so that it states
the semantics for status codes != 101:

-- snip --

9.8.  Upgrade

The "Upgrade" general-header field allows the client to specify
what

server chooses to switch protocols.  Servers can use it to
indicate

Upgrade-v = 1#product

For example,

The Upgrade header field is intended to provide a simple
mechanism

for transition from HTTP/1.1 to some other, incompatible
protocol.

It does so by allowing the client to advertise its desire to
use

another protocol, such as a later version of HTTP with a higher
major

version number, even though the current request has been made
using

HTTP/1.1.  This eases the difficult transition between
incompatible

protocols by allowing the client to initiate a request in the
more

commonly supported protocol while indicating to the server that
it

would like to use a "better" protocol if available (where
"better" is

determined by the server, possibly according to the nature of
the

The Upgrade header field only applies to switching
application-layer

protocols upon the existing transport-layer connection.
Upgrade

cannot be used to insist on a protocol change; its acceptance
and use

application-layer communication after the protocol change is
entirely

dependent upon the new protocol chosen, although the first
action

after changing the protocol MUST be a response to the initial
HTTP

The Upgrade header field only applies to the immediate
connection.

Therefore, the upgrade keyword MUST be supplied within a
Connection

header field (Section 9.1) whenever Upgrade is present in an
HTTP/1.1

message.

The Upgrade header field cannot be used to indicate a switch to
a

protocol on a different connection.  For that purpose, it is
more

[Part2]).

Servers MUST include the "Upgrade" header field in 101
(Switching

Protocols) responses to indicate which protocol(s) are being
switched

indicate acceptable protocols to upgrade to.  Servers MAY
include it

in any other response to indicate that they are willing to
upgrade to

This specification only defines the protocol name "HTTP" for
use by

the family of Hypertext Transfer Protocols, as defined by the
HTTP

specification.  Additional tokens can be registered with IANA
using

-- snip --

-- snip --

The request can not be completed without a prior protocol
upgrade.

This response MUST include an Upgrade header field (Section 9.8
of

Example:

Upgrade: HTTP/2.0

Connection: Upgrade

The server SHOULD include a message body in the 426 response
which

describes any alternative courses which may be available to the
user.

-- snip --

I believe we are done with ticket 240, and should treat all
remaining issues as separate bugs...

Feedback appreciated,

Julian

--
Adrien de Croy - WinGate Proxy Server - http://www.wingate.com

---

From: Julian Reschke <[email-masked]>
Date: Sun, 31 Oct 2010 11:06:08 +0100

Hi Adrien,

On 31.10.2010 00:28, Adrien de Croy wrote:
> When I first read the definition for Upgrade in RFC2616, I switched off
> as soon as I saw the word "additional communications protocols" which
> didn't make any sense to me.
>
> IMO it should read "alternative communications protocols", since if the
> header is acted on, the protocol will be changed to rather than added.

I don't think it makes a big difference; these are communication 
protocols in *addition* to HTTP/1.1, right?

> Also, this is a classic case of why HTTP/1.1 intermediaries MUST strip
> headers matching tokens in the Connection header. It makes me wonder
> what will happen if an HTTP/1.0 proxy receives one of these and forwards
> it. Is there a requirement on servers to ignore upgrade on an HTTP/1.0
> request?

Maybe:

"A system receiving an HTTP/1.0 (or lower-version) message that includes 
a Connection header field MUST, for each connection-token in this field, 
remove and ignore any header field(s) from the message with the same 
name as the connection-token."

?

> I also wonder what an HTTP/2.0 proxy should send upstream when receiving
> Upgrade: HTTP/2.0 in an HTTP/1.1 request.

I don't think we need to answer that know.

> doesn't include any version number.

Yes. RFC2817 and RFC2616 did not agree on whether the registry takes 
tokens or products. The current registry contains both.

According to RFC2616: "This specification only defines the protocol name 
"HTTP" for use by the family of Hypertext Transfer Protocols, as defined 
by the HTTP version rules of Section 3.1 and future updates to this 
specification."

> I don't see any discussion for the production of "product" in the BNF
> for Upgrade, which would need to include version number (as opposed to
> it being optional in the product production in S 3.8) in order for this
> example to be correct according to the current IANA registry, or would
> we need to register a separate value with the IANA of "HTTP/2.0" (which
> is in keeping with the way TLS/1.0 is registered)? On that note, it may

I think the idea is that the prefix "HTTP" is reserved for HTTP, and 
future versions of HTTP can then register HTTP with a version in the 
IANA registry.

> be prudent to consider versioning in this aspect for WebSocket. At the
> very least there is inconsistency about how the 3 tokens are currently
> registered, with TLS including version and the others not.

Yes. Assuming we want to allow both formats, we may have to clarify the 
registration procedure. Proposals are welcome.

> Without version number, registering the bare "HTTP" token is probably of
> little use. Especially since if the version defines aspects such as new
> (incompatible) framing etc, then the version is a key part of the actual
> protocol being referred to and can't really be omitted. In that sense,
> if a server received
>
> Upgrade: HTTP
>

Yes.

> It makes me wonder whether the BNF for Upgrade should have referred to
> product or some other production requiring version, and being designed
> to be the name of a protocol (non-optional version) rather than the name
> of a product. c.f.
>

I'm not sure I understand the issue, except for the lack of consistency 
(which is historic).

A software component needs to understand the whole "product", no matter 
whether it's token or token/token. If it does, it will know what do do 
anyway, right? There's no generic processing possible here.

Best regards, Julian