Open yutakahirano opened 3 years ago
@annevk @mikewest in case they are interested.
I'm not sure I understand the setup. I thought WebTransport would use ALPN. It seems to me that once ALPN is okay with a specific WebTransport identifier, everything after that is okay as it would be part of the protocol?
I'm not sure I understand the setup. I thought WebTransport would use ALPN. It seems to me that once ALPN is okay with a specific WebTransport identifier, everything after that is okay as it would be part of the protocol?
True, the client must not start establishing a WebTransport session before receiving SETTINGS_ENABLE_WEBTRANSPORT. With that settings, is it OK to send arbitrary headers (as long as the request makes sense in the context of WebTransport over HTTP/3)?
I think so. WebSocket and fetch()
have to care about existing servers and infrastructure and therefore come with a bunch of restrictions. WebTransport only has to care about such restrictions (e.g., ports, CSP) up until the point a connection has been established as after that it should be clear to the server it's something new.
We should make this clear in the WebTransport specification (e.g., in a considerations for server implementers section) and hopefully devrel will also cover this extensively.
I think from a privacy and security perspective this looks okay. We probably want to block request-body-header names too since although they wouldn't create security problems they'd be very confusing if set.
I assume extensions will be able to read and modify the headers?
I'm not sure what I feel about this from a design perspective. Is this something we're going to regret later?
My personal intuition on this:
Sec-*
and Origin
for the user agent, as we rely on Origin
header being supplied by ourselves. https://fetch.spec.whatwg.org/#forbidden-header-name is probably the easiest approach here.I guess this is about about session establishment as written down in https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3#section-3.3? So in theory that is post-ALPN so the server should know what is going on. However, I guess there is the concern servers might agree to the ALPN handshake but then handle the request in a normal endpoint (for authentication purposes and such), similar to what has been happening with WebSocket.
I suspect we would never include cookies or HTTP authentication in this CONNECT request, unlike WebSocket?
I'm not sure what ALPN specifically has to do here, since they both have ALPN of h3
.
The CONNECT requests are supposed to be fully uncredentialed, that is to say, no cookies, no HTTP auth, no TLS client certificates.
Sorry, I meant that the TLS handshake indicates it's a WebTransport connection and not a "normal" HTTP connection. I see that's covered through SETTINGS_ENABLE_WEBTRANSPORT as @yutakahirano already mentioned above.
Just to clarify, WebTransport support is an additive property; normal HTTP traffic can occur on WebTransport-supporting connections, though by default a WebTransport object will create a new connection.
Thanks! That does argue for being conservative with the handshake as servers will be incentivized to flip the WebTransport setting and are not at all incentivized to audit all their "legacy" paths at the same time.
Given the discussion above, do the followings make sense?
datagram-flow-id
), then the constructor throws.
I think to be on the safe side you probably want to match WebSocket or "no-cors". Other headers would only come after a CORS preflight normally, after all.
Ah sorry I overlooked the last comment.
Meeting:
Oh sorry I thought I hit the comment button.
My application needs to negotiate a video codec on connect. The client sends a list of supported codecs and the server responds with the chosen one. TLS does something similar.
There's how you could implement this:
You could marshal the supported codecs into the request path, but it's a pain. The server still needs to respond with the chosen codec and that's not possible.
I would definitely use custom request+response headers if they were available. Only supporting custom request headers would be a marginal improvement.
We don't need CORS pref-light (bad for performance) since we have settings
What settings is this referring to? If it's the settings set during ALPN I think that is negated (as also stated in prior comments) by the fact that this handshake ends up intermixed with normal HTTP traffic.
@kixelated
Thank you for your opinion!
@annevk What settings is this referring to? If it's the settings set during ALPN I think that is negated (as also stated in prior comments) by the fact that this handshake ends up intermixed with normal HTTP traffic.
I believe it's a new setting - we can define a new setting listing headers which the server accepts for the CONNECT request for webtransport over HTTP/3, for example (let's call it SETTINGS_WEBTRANSPORT_REQUEST_HEADERS for now). Just like SETTINGS_ENABLE_WEBTRANSPORT, if the server supports WebTransport over HTTP/3 and accepts custom headers for the CONNECT request, it should include SETTINGS_WEBTRANSPORT_REQUEST_HEADERS in the initial SETTINGS frame.
This is less flexible than CORS preflight but more efficient.
I see, that would be acceptable (to me, at least). I wonder though, could we generalize that to SETTINGS_BYPASS_CORS_PREFLIGHT or some such so we solve that thorny problem at the same time? See https://github.com/quicwg/base-drafts/issues/1993. Folks (I recall @mnot?) did raise similar concerns in that the person configuring TLS might not be aware of all the HTTP services on the server, but I think we'll always have that problem for any kind of centralized solution. I would hope that documentation would go a long way towards addressing that.
(I could also see trying this more limited thing out first and if it works going for the generalized solution later. Dunno how cheap these bits are.)
Flipping this bit in a SETTING (h2 or h3) has significant performance / race avoidance advantages, so I'm interested. Yes, there are deployments where server administration isn't done by the same people, but I think we can address that risk by:
It might also be interesting to define a companion well-known resource (or Origin Policy property, if that gets off the ground), which would allow control over the SETTING through a resource that's available to the server's content folks (provided that server implementations link the two).
I'm happy to write up a draft for the SETTING, but first it'd be great to hear what people like @mikewest think about this.
cc: @martinthomson
I'm not seeing any significant new information: yes, this sort of capability might be nice, but it also costs a fair bit to add. It can be added later.
Meeting:
It would be useful to pass a JWT token for authentication / authorization in the connect request. On the server-side, TLS connections are typically terminated by a load balancer, but it would be useful if an JWT token could be passed through to the server instance behind the load balancer.
the fetch api has "authentication entries" for this.
Authentication entries is explicitly not web developer controlled though.
What I meant was support for the corresponding to:
fetch(url, {
headers: {
'Authorization': `Bearer ${token}`,
},
})
this could perhaps be something like
const transport = new WebTransport(url, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
@annevk ^
Yeah, that's the same kind of use case people have for including headers in the WebSocket
handshake. As discussed many months ago upthread the conservative option would be requiring a CORS preflight for that, along with the necessary infrastructure. That doesn't seem like the kind of thing that should go into v1.
Meeting:
See the related bug entry about the lack of support for HTTP authentication in the WebSocket API.
How do we implement authentication with Web Transport? Do we need to store the session token in a non-HTTPOnly cookie or localStorage or something and send it (from the client) as the first message of a session?
Web developers may want to attach some information to the request, and encoding everything into the URL is tiresome.
The simplest form is something like this.
This may be dangerous if web developers can specify arbitrary headers. Some examples:
So, we need to forbid forbidden header names at least.
That may not be enough. For usual HTTP requests, if the request is cross-origin and has non-safelisted headers, CORS preflight is needed. WebSocket solves the problem by allowing web developers to control only one header (sec-websocket-protocols). We can do the same for WebTransport.
Thoughts?