Re: WebSocket2

> Kari and other participants, which way do you think would be better:
> 
> RFC of Websocket2  updates RFC 7540 (HTTP/2)
> OR
> RFC of Websocket2 registers new method.
> 
> Using it this way you proposed would it require adding
> SETTINGS_WEBSOCKET_CAPABLE
> as well?
> 
> I think the SETTINGS_WEBSOCKET_CAPABLE can be included in the RFC and if
> a middle box does not implement support for it, as long as it forwards
> everything correctly
> AND the response contains the sec-ws2-error header, there should not be
> problems?

• Assuming
  
  ":scheme"    = "wss"  (or  "ws"  on forward proxy scenario )
  ":authority" = "foo.example"
  ":method"    = "CONNECT"
  ":path"      = "/bar"

  ( This may need: RFC of Websocket2  updates RFC 7540 (HTTP/2) )

  ‣ benefit

    ∘ If http/2 component does not support Websocket2, this produces
      http/2 error code PROTOCOL_ERROR  (because ":scheme" and
      ":path" are not allowed).

    ∘ ":method" = "CONNECT" have already semantic
      which implies that DATA frames are not
      collected for request or response body
      and DATA frame traffic is bidirectional.

  ‣ disadvantage

    ∘ There is danger that PROTOCOL_ERROR error 
      is sent with GOAWAY. This means closing
      of connection (expensive).

      If PROTOCOL_ERROR error is sent with
      RST_STREAM, then this is good.

      ∷  SETTINGS_WEBSOCKET_CAPABLE  from http/2
  server to http/2 client avoids
  possible PROTOCOL_ERROR

    ∘ ":scheme" and ":path" may be ignored. 
      { Ignoring violates MUST clause on RFC 7540. }
      ( Forward proxy may try open tcp connection
        to ":authority". )

• Assuming

  ":scheme"    = "wss"  (or  "ws"  on forward proxy scenario )
  ":authority" = "foo.example"
  ":method"    = "WS2"
  ":path"      = "/bar"

  ( This may need: RFC of Websocket2 registers new method )

  ‣ benefit

    ∘ if http/2 (or http/1.1 behind reverse proxy) server 
      does not support that method it can give
      http status code 405 (Method Not Allowed)

      Also http status 501 (Not Implemented) is possible.

    ∘ If http/2 reverse proxy does not buffer DATA,
      it may work without Websocket2 support

    ∘ response header (was it sec-ws2-error? or sec-ws2-ack?)
      may indicate that origin server understand
      ":scheme" and ":path".

  ‣ disadvantage

    ∘ If http/2 component does not support Websocket2,
      it may try buffer assumed http request body
      (all request DATA frames) and response body
      (all response DATA frames). Because some 
      responses can be cached, it make sense to buffer
      them all (to some upper limit of data).

    ∘ ":scheme" may be ignored (or dropped when
      converted to HTTP/1.1 request).

      ∷  SETTINGS_WEBSOCKET_CAPABLE  from http/2
         server to http/2 client help quarantee
  that DATA frames are not buffered
         excessively and promises that
         ":scheme" is not ignored.

    ∘ If response header (was it sec-ws2-error? or 
      sec-ws2-ack?) is not received, 
      http/2 client may need RST_STREAM 
      opened stream.

If middle box does not support Websocket2,
then it can be assumed that it does not
send SETTINGS_WEBSOCKET_CAPABLE to http/2
client.

It may be possible to send

  ":scheme"    = "wss"  (or  "ws"  on forward proxy scenario )
  ":authority" = "foo.example"
  ":method"    = "WS2"
  ":path"      = "/bar"

to http/2 origin server and then look if
SETTINGS_WEBSOCKET_CAPABLE = 1 is set
by http/2 server. If SETTINGS_WEBSOCKET_CAPABLE
is not set (not received via SETTINGS)
then http/2 client may need RST_STREAM 
opened stream.

That RST_STREAM happens when http/2 server
is finished handshake.  May be expensive.

It is also possible that http/2 server
is set SETTINGS_WEBSOCKET_CAPABLE = 1 on
initial SETTINGS frame. 

> Standardized protocol or not is irrelevant.  I was simply considering the
> options
> and what would work.  QUIC uses different negotiation and transport frames
> then HTTP/2
> does (also QUIC does not have HTTP/2 SETTINGS frames). I was proposing
> ideas at
> tackling the problem to make WebSocket2 work across different transport
> layers.

Obviously you then need omit SETTINGS_WEBSOCKET_CAPABLE
when QUIC is used. I do not know if buffering of DATA
frames is concern on here.

> >> I contemplated SETTINGS as:
> >>
> >> ∙ SETTINGS frame with SETTINGS_WEBSOCKET_CAPABLE = 1
> >>   from HTTP/2 server ⇒  HTTP/1 client direction
> >>
> >>   ∘ Promises that HTTP/2 server checks ":scheme"
> >>     (and specially "wss" and "ws")
> >>
> >>   ∘ Acknowledges that DATA frames for
> >>     ":scheme" = "wss" and "ws" are handled
> >>     as bidirectional traffic (similar than
> >>     ":method" = "CONNECT").
> >>
> >>     In other words these DATA drames do
> >>     NOT form HTTP request body from client
> >>     and DATA drames do not form
> >>     HTTP response body from server
> >>     (on cases ":scheme" = "wss" and "ws").
> >>
> >>   ∘ SETTINGS_WEBSOCKET_CAPABLE = 1 does
> >>     not promise that HTTP/2 server
> >>     accepts ":scheme" = "wss" or "ws".
> >>
> >
> > Yutaka's proposal tried to represent the same guarantee by using the
> > combination of the client to server direction SETTINGS and the response
> > status code.
> >
> > I chatted with Yutaka offline. He don't remember the background fully, but
> > we guess we chose to let the client send SETTINGS because we want to start
> > sending WebSocket handshake before waiting for response from the server to
> > reduce the initial latency. Such an attempt may result in failure, but
> > worth doing for some latency sensitive applications.
> >
> > There're two approaches to realize this:
> > (a) let the server send SETTINGS and let the client send handshake
> > speculatively without waiting for the SETTINGS
> > (b) let the client send SETTINGS and then send handshake speculatively,
> > and let the server determine the response status code based on whether or
> > not it has received SETTINGS as specified in Yutaka's I-D.
> >
> > (a) still gives the client path check result before receiving the
> > WebSocket handshake response, but it's not good that the server cannot know
> > whether the path was good or not before accepting the WebSocket handshake.
> >
> > One more thing to note is that we were investigating whether we could
> > relax the requirement of the WebSocket API that messages cannot be sent
> > before receiving handshake response, when h2 is used. The server needs to
> > process these speculative messages without determining whether the the path
> > was good for WS/h2 if we adopt (a).
> >
> > One small benefit of (b) is that there wouldn't be any
> > SETTINGS_WEBSOCKET_CAPABLE traffic if the client doesn't want to use WS.
> >
> > Now I think combining (a) and (b) is the best given the concern that the
> > server may forget to investigate the SETTINGS correctly but still reply to
> > a WebSocket handshake with non 501 status code.
> >

/ Kari Hurtta

Received on Friday, 7 October 2016 16:40:53 UTC