On Thu, Jul 28, 2016 at 2:33 AM, William A Rowe Jr <[email protected]> wrote:
> On Jul 27, 2016 6:53 PM, "Yann Ylavic" <[email protected]> wrote:
>>
>> On Wed, Jul 27, 2016 at 8:27 PM, William A Rowe Jr <[email protected]>
>> wrote:
>> >
>> > On Wed, Jul 27, 2016 at 11:09 AM, Yann Ylavic <[email protected]>
>> > wrote:
>> >>
>> >> Hi,
>> >>
>> >> since Upgrade is an HTTP/1 feature, I don't find it too twisted...
>> >>
>> >> The primary goal would be to let the backend decide whether an Upgrade
>> >> is to be done, or otherwise continue with HTTP (still parsing the
>> >> response, filtering, caching, ...).
>> >
>> >
>> > Nope... a thousand times nope...
>> >
>> > The protocol, along with a host of headers, are a hop-by-hop entities.
>> > They are not part of that discussion.
>>
>> Hmm, what's the point?
>> Can't proxies forward protocols? Don't we forward WebSocket already?
>> Do hop by hop headers prevent HTTP forwarding?
>>
>> We are talking about proxying Upgraded protocols here (once upgraded),
>> acting as a transparent/reverse proxy, when configured to, and as
>> negotiated by the client and backend.
>> Don't we do that for HTTP and other protocols already?
>
> Nope. Point-to-point is addressed by CONNECT, everything else is hop-by-hop.
Well, as usual, the proxy acts as the next hop for the client, and the
next hop for the proxy is the backend (or another proxy)?
What prevents a proxy from doing hop by hop on both sides?
For example, a proxy can play 100-continue on the client side but not
on the backend side, or play distinct 100-continue on both the client
and backend sides, or forward the "Expect: 100-continue" to the
backend (w/o reading the client's body) and the backend's "100
Continue" response before forwarding the request body and then the
final response, its choice/implementation.
Hop by hop does not mean that the protocol/feature has to stop at the
first hop, it says that it is self-contained for communicating from
one hop to next one, and that a client can't expect it to be forwarded
above the next hop (but if it works transparently, how could it
know?).
That's already what mod_proxy_wstunnel does for WebSocket, I simply
propose a more generic way (allow *any* HTTP Upgrade to be tunneled by
mod_proxy_http, at the backend's initiative, with conformant hop by
hop between the client<=>proxy and proxy<=>backend).
Below a concrete example (for the example) of what would work (better)
than today:
CLIENT PROXY BACKEND
GET / HTTP/1.1
Host: proxy
==>
GET / HTTP/1.1
Host: backend
==>
HTTP/1.1 XXX OK
[Some auth mechanism]
<==
HTTP/1.1 XXX OK
[Some auth mechanism]
<==
[Auth] <=> [HTTP] <=> [Auth]
HTTP/1.1 302 Found
Location: https://backend/ws/
Set-Cookie: auth=token
Upgrade: WebSocket
Connection: upgrade
<==
HTTP/1.1 302 Found
Location: https://proxy/ws/
Set-Cookie: auth=token
Upgrade: WebSocket
Connection: upgrade
<==
GET /ws/ HTTP/1.1
Host: proxy
Upgrade: WebSocket
Connection: upgrade
Cookie: auth=token
==>
GET /ws/ HTTP/1.1
Host: backend
Upgrade: WebSocket
Connection: upgrade
Cookie: auth=token
==>
HTTP/1.1 101 Switching
Upgrade: WebSocket
Connection: upgrade
<==
HTTP/1.1 101 Switching
Upgrade: WebSocket
Connection: upgrade
<==
[WebSocket] <=> [TCP] <=> [WebSocket]
But if the client tries the below (without the Cookie), we still have
the hand on HTTP with my proposed patch, whereas with
mod_proxy_wstunnel today we'd be tunneling normal HTTP traffic:
GET /ws/ HTTP/1.1
Host: proxy
Upgrade: WebSocket
Connection: upgrade
==>
GET /ws/ HTTP/1.1
Host: backend
Upgrade: WebSocket
Connection: upgrade
==>
HTTP/1.1 302 Found
Location: https://backend/
[Go do auth there first]
<==
HTTP/1.1 302 Found
Location: https://proxy/
[Go do auth there first]
<==
[Roger, I'll do that]