Re: #385: HTTP2 Upgrade / Negotiation

On Oct 23, 2012 6:25 PM, "Amos Jeffries" <squid3@treenet.co.nz> wrote:
>
> On 24.10.2012 05:50, James M Snell wrote:
>>
>> On Mon, Oct 22, 2012 at 7:03 PM, Mark Nottingham <mnot@mnot.net> wrote:
>>
>>> [snip]
>>>
>>> 1) Using a SRV (or other DNS) record. There seems to be a fair amount of
>>> interest in this from the browser implementers; the only resistance
seems
>>> to be around how hard this would be to deploy, but if it's not the only
>>> mechanism for upgrading to HTTP/2, it shouldn't be a concern.
>>>
>>> Presumably, we'd define a default port for HTTP/2-only communication
when
>>> used in conjunction with this, so that firewalls would know to open it,
etc.
>>>
>>>
>> Such a dedicated default port definitely needs to be defined. There are
>> many scenarios where upgrade negotiation simply is not going to be
required
>> at all.
>>
>
> My understanding of the charter was that defining a new scheme was out of
bounds. A *default* port would mean a new scheme name was mandatory to
identify default http://*:80 from default http://*:443 from default http2
port.
>
> I find it highly undesirable either way. Lets make HTTP/2 the successor
to merge both HTTP/1.1 port 80 and HTTP/1.1 port 443 safely with scheme
http:// and default port 80. Note that this does not require it being ASCII
text initial request. We can easily and safely prefix with a TLS-follows
frame to determine HTTPS over port 80.
>
>
>>
>>> Does anyone object to us defining such a record (type TBD), as long as
>>> it's not the only way to get to HTTP/2 for HTTP URIs?
>>>
>>
>> Defining a new dns record type would be unnecessary and would be the
wrong
>> approach. SRV records were made specifically for this kind of use.
They're
>> certainly not perfect but inventing a new record type specifically for
>> http2 stuff is even less so.
>>
>>
>
> +1 on that.
>
>
>>>
>>> 2) Using a response header to hint that HTTP/2 is available on another
>>> port.
>>>
>>> This approach hasn't been talked about in detail yet, but it apparently
>>> (as some have noted) has the disadvantage of not upgrading the first
>>> interaction, and of requiring a separate cache (and caching model) for
this
>>> information.
>>>
>>> Who wants to pursue this approach? If so, we need a small proposal
>>> written, preferably as an I-D, but an e-mail would do.
>>>
>>>
>> This is one of those ideas that sounds interesting in theory but I don't
>> see how it would be effective in practice.
>>
>
> Maybe yes maybe no. This seems to me to be a repetition of the Via:
header with its path version hints. Equally valid in HTTP/1.a and 2.0 and
covers this use-case already.
>
>
>>
>>> And, are there any other approaches we want to put on the table?
>>>
>>>
>> For browsers, upgrading on the first connection is obviously going to be
>> critical. The DNS option seems like the best approach for the most
general
>> case, despite the various flaws in that approach.
>
>
> *except* for all those cases where middleware exists. In which case DNS
hinting will be the cause of problems, not the solution.
>
>
>> montenegro-httpbis-http2-negotiation seems to provide a reasonable
fallback
>> when we're talking primarily about GET/HEAD traffic, but it has obvious
>> issues when dealing with POST/PUT/PATCH type operations. I do not really
>> want to always have to send PUT requests as HTTP/1.1 when what I really
>> want is to use HTTP/2.0 for the entire flow. For payload-bearing
requests,
>> upgrade needs to be negotiated before the initial request is sent.
>
>
> That said, how prevalent is first-contact PUT/POST as opposed to a page
GET followed by further interaction from scripts and forms?
>  Is it just from badly designed sites using cross-domain PUT/POST?
>  or from non-browser agents which should be able to know better anyway
with less critical timing requirements?
>
>
>>
>> One possible way to mitigate this would be to combine the Upgrade header
>> approach with a new Expect token. For instance...
>>
>>   POST /default.htm HTTP/1.1
>>   Host: server.example.com
>>   Connection: Upgrade
>>   Upgrade: HTTP/2.0
>>   Expect: 101-upgrade
>>
>> The addition of the Expect header does two things...
>>
>> 1. It makes the upgrade a requirement rather than optional...
>> 2. The client would then wait as reasonable time for the 101 Switching
>> Protocols before it proceeds to send the http/2.0 encoded data...
>>
>> When the client does start sending the data (after receiving the 101
>> response), it would do so by first sending a SYN_STREAM.. To http/1.1
>> servers, this would appear to be nothing more than regular POST payload
>> data. For http/2 traffic, this requires an initial round trip but it
>> addresses the upgrade on payload-bearing request issue... and is exactly
>> the kind of thing the Expect header was intended for. The scheme is
>> obviously far from perfect, however.
>
>
> +1.
>
> Also note that the new Expect token needs to be defined as hop-by-hop to
prevent its relay.
>
> This is also just as useful for Upgrade:HTTP/1.1 to mandate HTTP/1.1
feature support on the connection.
>
>
>
>>
>> Alternatively, I firmly believe that a http2 URI scheme as a reasonable
>> fallback needs to be considered as an option here... particularly if we
do
>> define a dedicated http/2 default port. Yes, I agree with the whole "we
>> want to do existing http:// and https:// traffic over http/2
transparently"
>> argument and fully understand the challenges of introducing a new URI
>> scheme. However, there will be instances where upgrade negotiation is
>> simply not going to be necessary and for which backwards compatibility
with
>> existing infrastructure is going to be unnecessary. For those cases, the
>> ability to pass a URL like "http2://example.org" and have it just
>> automatically understood that it's "http/2 over port whatever" will be
>> extremely useful. A no brainer even. So much so that if the working group
>> here doesn't choose to define it, I'll likely just end up writing it up
as
>> an individual submission. That way, when I write.. <form method="post"
>> action="http2://example.org">...</form> the notion that http/2 is being
>> used is explicit and no upgrade discovery/negotiation is required at all.
>> That's what url schemes are for in the first place, right?
>
>
> Consider whether you are making HTTP/2 an second protocol to exist in
parallel to HTTP/1 or a replacement version of the protocol.
>
> A parallel protocol would have a separate scheme (eg. HTTP vs HTTPS
today). And may as well be called HTTP2/1.1 or "HTTP/1.1 over port 1234" as
HTTP/2.0.
>
> A replacement would use the same scheme and let the agents negotiate the
version level between themselves without the web developers getting
involved with specific URL versions.
>
> Also, how would one go about re-writing the entire legacy web page set to
use http2:// URLs when the server (or even just its frontend proxy!)
upgrades?

As I understand the suggestion, that want required. What I understood was
that a scheme of http2 meant one should assume you can use HTTP/2. An HTTP
scheme , however didn't mean only http/1.x-- it could also be http/2 after
negotiations.

Proxies make any of this moot, however, if they are used-- a negotiation
must happen if there is ever anything other than direct connectivity. If
the scheme is just used as a hint instead of an assertion (I.e. one can
always fall back to 1.1) it is technically useful in potentially , maybe,
saving an rtt... but ugly and it could end up costing more in the case
where a proxy doesn't understand http/2 and where the session must be
restarted...

-=R

>
>
> Amos
>
 On Oct 23, 2012 6:25 PM, "Amos Jeffries" <squid3@treenet.co.nz> wrote:

> On 24.10.2012 05:50, James M Snell wrote:
>
>> On Mon, Oct 22, 2012 at 7:03 PM, Mark Nottingham <mnot@mnot.net> wrote:
>>
>>  [snip]
>>>
>>> 1) Using a SRV (or other DNS) record. There seems to be a fair amount of
>>> interest in this from the browser implementers; the only resistance seems
>>> to be around how hard this would be to deploy, but if it's not the only
>>> mechanism for upgrading to HTTP/2, it shouldn't be a concern.
>>>
>>> Presumably, we'd define a default port for HTTP/2-only communication when
>>> used in conjunction with this, so that firewalls would know to open it,
>>> etc.
>>>
>>>
>>>  Such a dedicated default port definitely needs to be defined. There are
>> many scenarios where upgrade negotiation simply is not going to be
>> required
>> at all.
>>
>>
> My understanding of the charter was that defining a new scheme was out of
> bounds. A *default* port would mean a new scheme name was mandatory to
> identify default http://*:80 from default http://*:443 from default http2
> port.
>
> I find it highly undesirable either way. Lets make HTTP/2 the successor to
> merge both HTTP/1.1 port 80 and HTTP/1.1 port 443 safely with scheme http://and default port 80. Note that this does not require it being ASCII text
> initial request. We can easily and safely prefix with a TLS-follows frame
> to determine HTTPS over port 80.
>
>
>>  Does anyone object to us defining such a record (type TBD), as long as
>>> it's not the only way to get to HTTP/2 for HTTP URIs?
>>>
>>>
>> Defining a new dns record type would be unnecessary and would be the wrong
>> approach. SRV records were made specifically for this kind of use. They're
>> certainly not perfect but inventing a new record type specifically for
>> http2 stuff is even less so.
>>
>>
>>
> +1 on that.
>
>
>>> 2) Using a response header to hint that HTTP/2 is available on another
>>> port.
>>>
>>> This approach hasn't been talked about in detail yet, but it apparently
>>> (as some have noted) has the disadvantage of not upgrading the first
>>> interaction, and of requiring a separate cache (and caching model) for
>>> this
>>> information.
>>>
>>> Who wants to pursue this approach? If so, we need a small proposal
>>> written, preferably as an I-D, but an e-mail would do.
>>>
>>>
>>>  This is one of those ideas that sounds interesting in theory but I don't
>> see how it would be effective in practice.
>>
>>
> Maybe yes maybe no. This seems to me to be a repetition of the Via: header
> with its path version hints. Equally valid in HTTP/1.a and 2.0 and covers
> this use-case already.
>
>
>>  And, are there any other approaches we want to put on the table?
>>>
>>>
>>>  For browsers, upgrading on the first connection is obviously going to be
>> critical. The DNS option seems like the best approach for the most general
>> case, despite the various flaws in that approach.
>>
>
> *except* for all those cases where middleware exists. In which case DNS
> hinting will be the cause of problems, not the solution.
>
>  montenegro-httpbis-http2-**negotiation seems to provide a reasonable
>> fallback
>> when we're talking primarily about GET/HEAD traffic, but it has obvious
>> issues when dealing with POST/PUT/PATCH type operations. I do not really
>> want to always have to send PUT requests as HTTP/1.1 when what I really
>> want is to use HTTP/2.0 for the entire flow. For payload-bearing requests,
>> upgrade needs to be negotiated before the initial request is sent.
>>
>
> That said, how prevalent is first-contact PUT/POST as opposed to a page
> GET followed by further interaction from scripts and forms?
>  Is it just from badly designed sites using cross-domain PUT/POST?
>  or from non-browser agents which should be able to know better anyway
> with less critical timing requirements?
>
>
>> One possible way to mitigate this would be to combine the Upgrade header
>> approach with a new Expect token. For instance...
>>
>>   POST /default.htm HTTP/1.1
>>   Host: server.example.com
>>   Connection: Upgrade
>>   Upgrade: HTTP/2.0
>>   Expect: 101-upgrade
>>
>> The addition of the Expect header does two things...
>>
>> 1. It makes the upgrade a requirement rather than optional...
>> 2. The client would then wait as reasonable time for the 101 Switching
>> Protocols before it proceeds to send the http/2.0 encoded data...
>>
>> When the client does start sending the data (after receiving the 101
>> response), it would do so by first sending a SYN_STREAM.. To http/1.1
>> servers, this would appear to be nothing more than regular POST payload
>> data. For http/2 traffic, this requires an initial round trip but it
>> addresses the upgrade on payload-bearing request issue... and is exactly
>> the kind of thing the Expect header was intended for. The scheme is
>> obviously far from perfect, however.
>>
>
> +1.
>
> Also note that the new Expect token needs to be defined as hop-by-hop to
> prevent its relay.
>
> This is also just as useful for Upgrade:HTTP/1.1 to mandate HTTP/1.1
> feature support on the connection.
>
>
>
>> Alternatively, I firmly believe that a http2 URI scheme as a reasonable
>> fallback needs to be considered as an option here... particularly if we do
>> define a dedicated http/2 default port. Yes, I agree with the whole "we
>> want to do existing http:// and https:// traffic over http/2
>> transparently"
>> argument and fully understand the challenges of introducing a new URI
>> scheme. However, there will be instances where upgrade negotiation is
>> simply not going to be necessary and for which backwards compatibility
>> with
>> existing infrastructure is going to be unnecessary. For those cases, the
>> ability to pass a URL like "http2://example.org" and have it just
>> automatically understood that it's "http/2 over port whatever" will be
>> extremely useful. A no brainer even. So much so that if the working group
>> here doesn't choose to define it, I'll likely just end up writing it up as
>> an individual submission. That way, when I write.. <form method="post"
>> action="http2://example.org">.**..</form> the notion that http/2 is being
>> used is explicit and no upgrade discovery/negotiation is required at all.
>> That's what url schemes are for in the first place, right?
>>
>
> Consider whether you are making HTTP/2 an second protocol to exist in
> parallel to HTTP/1 or a replacement version of the protocol.
>
> A parallel protocol would have a separate scheme (eg. HTTP vs HTTPS
> today). And may as well be called HTTP2/1.1 or "HTTP/1.1 over port 1234" as
> HTTP/2.0.
>
> A replacement would use the same scheme and let the agents negotiate the
> version level between themselves without the web developers getting
> involved with specific URL versions.
>
> Also, how would one go about re-writing the entire legacy web page set to
> use http2:// URLs when the server (or even just its frontend proxy!)
> upgrades?
>
>
> Amos
>
>

Received on Wednesday, 24 October 2012 02:29:56 UTC