You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Tim Bannister <is...@c8h10n4o2.org.uk> on 2015/12/10 01:16:31 UTC

Re: Upgrades

On 9 Dec 2015, at 23:19, William A Rowe Jr <wr...@rowe-clan.net> wrote:

> Because the request body is inbound already at some state of completion
> or incomplete transmission, it is competing with the TLS handshake, which
> is a bidirectional engagement with the same socket between the user agent
> and server.  Unlike h2c and websocket, where Roy suggests we leave the
> http/1 input filter in place and inject the http/2 output filter for the duration
> of the initial Upgrade: request, we must pass TLS traffic in both directions 
> at once during Upgrade: TLS.
…
> Please remember that a request handler is based on a method and location,
> while Upgrade is not the request itself, but a proposal to switch protocols.
> In the case of TLS and h2c, that request is satisfied over the corresponding 
> HTTP/1 or HTTP/2 output filter, but I'm not clear whether websocket has
> any equivalence in terms of a content handler phase.

In a sense, all upgrades happen after of an existing request (& response). So how about this high level behaviour model:
httpd keeps note, for each connection, of what upgrades are (1) feasible and (2) agreed upon.
At end of any given request, either zero or one of the feasible upgrades will have been agreed between web server and client. That's when the upgrade should happen if it has been negotiated.

Eg, for a new, inbound port 80 connection: an upgrade to TLS or h2c would be feasible. During the first request it may transpire that an upgrade to WebSocket is feasible too (authz having been satisfied). Once the request in which the upgrade has been negotiated is complete, said upgrade takes place.

Any subsequent requests on the same TCP connection won't be eligible for upgrade to WebSocket. This kind of rule ought to live outside the HTTP/1.x implementation as it has more to do with WebSocket than HTTP.


-- 
Tim Bannister – isoma@c8h10n4o2.org.uk


Re: Upgrades

Posted by Stefan Eissing <st...@greenbytes.de>.
> Am 10.12.2015 um 02:07 schrieb William A Rowe Jr <wr...@rowe-clan.net>:
> 
> There is a case to be made for the h2c to also be an 'early' upgrade decision,
> AIUI (correct me if I'm wrong Stefan) the mod_http2 module sees a request,
> grabs ahold of the network in the main request thread, and then 're-processes'
> the request, repeating all of the request processing hooks for the initial request
> on the secondary h2c 'worker' thread.  By interrupting very early, during the
> post_read_request phase, these steps will no longer be duplicated.

Yes, correct. Good point for making the upgrade earlier for protocols like h2c.

Re: Upgrades

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Wed, Dec 9, 2015 at 6:16 PM, Tim Bannister <is...@c8h10n4o2.org.uk>
wrote:

> On 9 Dec 2015, at 23:19, William A Rowe Jr <wr...@rowe-clan.net> wrote:
>
> > Because the request body is inbound already at some state of completion
> > or incomplete transmission, it is competing with the TLS handshake, which
> > is a bidirectional engagement with the same socket between the user agent
> > and server.  Unlike h2c and websocket, where Roy suggests we leave the
> > http/1 input filter in place and inject the http/2 output filter for the
> duration
> > of the initial Upgrade: request, we must pass TLS traffic in both
> directions
> > at once during Upgrade: TLS.
> …
> > Please remember that a request handler is based on a method and location,
> > while Upgrade is not the request itself, but a proposal to switch
> protocols.
> > In the case of TLS and h2c, that request is satisfied over the
> corresponding
> > HTTP/1 or HTTP/2 output filter, but I'm not clear whether websocket has
> > any equivalence in terms of a content handler phase.
>
> In a sense, all upgrades happen after of an existing request (& response).
> So how about this high level behaviour model:
> httpd keeps note, for each connection, of what upgrades are (1) feasible
> and (2) agreed upon.
> At end of any given request, either zero or one of the feasible upgrades
> will have been agreed between web server and client. That's when the
> upgrade should happen if it has been negotiated.
>

I think that is the design we are arriving at, that each module is queried
early
if an upgrade should be advertised, and given the chance to begin the
upgrade,
and then immediately before the content handler (after auth) these steps
are
repeated, giving the protocol modules a chance to offer an upgrade or back
out of an intended offer.  The offers must be assembled before the content
handler causes the http/1 protocol filter to push out the response headers.

In the TLS case, it must happen very early for TLS
handshake/certificates/SNI
inspection for auth purposes, and prior to beginning the response.  No
upgrade
can happen after a response (except within the next request) because the
upgrade is a product of the 101-switching protocols.

There is a case to be made for the h2c to also be an 'early' upgrade
decision,
AIUI (correct me if I'm wrong Stefan) the mod_http2 module sees a request,
grabs ahold of the network in the main request thread, and then
're-processes'
the request, repeating all of the request processing hooks for the initial
request
on the secondary h2c 'worker' thread.  By interrupting very early, during
the
post_read_request phase, these steps will no longer be duplicated.

The main thread can still leave the http/1 input filter in place to provide
the
initial request body to that initial worker thread, but won't see
additional http/2
requests until that request body is consumed, completing the 101-switching
protocols contract.

The reason not to leave the initial http/1 request in the primary thread
until
it has been satisfied is that the connection would block on both the initial
request body and the initial response, which would be a huge penalty for
an initial request that performed some back-end processing and might
have database or other back-end contention.

Eg, for a new, inbound port 80 connection: an upgrade to TLS or h2c would
> be feasible. During the first request it may transpire that an upgrade to
> WebSocket is feasible too (authz having been satisfied). Once the request
> in which the upgrade has been negotiated is complete, said upgrade takes
> place.
>

For every request within a connection, such an upgrade remains feasible.


> Any subsequent requests on the same TCP connection won't be eligible for
> upgrade to WebSocket. This kind of rule ought to live outside the HTTP/1.x
> implementation as it has more to do with WebSocket than HTTP.
>

I'm wondering the same thing, why not on the third or twentieth request?
It simply can't be downgraded back to HTTP/1, if I understand the spec
correctly.

Re: Upgrades

Posted by Jacob Champion <ch...@gmail.com>.
On 12/09/2015 04:16 PM, Tim Bannister wrote:
> Any subsequent requests on the same TCP connection won't be eligible for upgrade to WebSocket.

Why not?

--Jacob