Open benjchristensen opened 8 years ago
The extra level of framing is brought up in https://github.com/bidiweb/wish/issues/1. It many use cases the extra bytes per frame may not matter, though there are some use cases we are pursuing where even the HTTP/2 framing is considered heavy by some compared with MQTT, so it's a topic.
Also, it just feels unnecessary to have yet another level of framing if we can access HTTP/2 streams directly.
In fact, we are currently exploring extending HTTP/2 instead of layering on top of it so that we can eliminate layering altogether: https://github.com/ReactiveSocket/reactivesocket/issues/84#issuecomment-245448366
So, two questions:
1) Is there any possibility of pursuing a message oriented solution for HTTP/2 that extends the protocol rather than layers? 2) If not extend, can the underlying HTTP/2 streams be directly exposed via standardized APIs so that we only need 2 layers of framing (HTTP/2 + application messaging protocol)?
I imagine option 1 is more challenging to convince people of, but option 2 seems straight forward, it's just exposing what already exists in the HTTP/2 spec.
I opened https://github.com/bidiweb/wish/issues/5 to discuss standardizing the API to achieve option 2.
2) If not extend, can the underlying HTTP/2 streams be directly exposed via standardized APIs so that we only need 2 layers of framing (HTTP/2 + application messaging protocol)?
I think we can expose only some part of HTTP/2 framing via well-designed secure API to the web platform in order to prevent the feature from being abused like how we designed WebSockets. So, I think even (2) leads to designing some general purpose extension of HTTP2 to cover various use cases and it would be similar to WebSocket/HTTP2 discussion.
Even after eliminating the fragmentation feature from the WiSH proposal, having two layers would be critical for the MQTT use case?
What does the extra level of framing do to provide security that can't be done when exposing the HTTP streams directly?
I'm not experienced in security matters, so can you please explain the implications of security on these choices?
In fact, Node is proposing two APIs for HTTP/2: a low-level session API (access to the wire-level framing) and a high-level HTTP API. OTOH, I don't think Fetch will ever (or should) expose a low-level API.
Reusing the transport-level multiplex framing will cause streams with large messages to block other streams.
The three framing mentioned in #1 are really orthogonal to each other:
Mixing 1) and 2) is actually common and the the HOL blocking may not be a big concern if network is fast or message sizes are kept small by the application. By eliminating 1), CPU efficiency will be improved too due to better caching.
Also, I am guessing that, With a UDP based transport, the implicit cost of 1) is still there because of the max size of UDP packets.
@benjchristensen
Could you clarify "2) If not extend, can the underlying HTTP/2 streams be directly exposed via standardized APIs so that we only need 2 layers of framing (HTTP/2 + application messaging protocol)?"?
Is the goal to have a single framing or to eliminate the framing introduced by something like WiSH because the application has its own protocol/framing? If the latter, we certainly don't expect the application protocol to define any framing on top of WiSH.
What does the extra level of framing do to provide security that can't be done when exposing the HTTP streams directly?
When the WebSocket was designed bunch of security related concerns emerged including cross-protocol attack (pretend to be SMTP), cross-origin access (pretend to be cross-origin HTTP), etc. Allowing the web platform to access to lower layer tends to require more care of security concerns.
Given that HTTP2 is basically TLS only and there shouldn't be so many broken intermediaries and servers compared to HTTP/1.1/TCP world, I think issues we need to tackle would be a few. But just layering over HTTP/1.1/HTTP2 would be definitely easier I guess. That's what I wanted to say. I don't have any concrete estimate of actual work needed, yet. Let me investigate more.
Is the goal to have a single framing or to eliminate the framing introduced by something like WiSH because the application has its own protocol/framing? If the latter, we certainly don't expect the application protocol to define any framing on top of WiSH.
Any non-trivial application protocol is going to effectively end up with its own framing overhead, even if it doesn't need the "Frame length" portion when the transport (such as Wish or WS already has frames). ReactiveSocket makes the frame length optional so it can optimize for transport on protocols that already have frames. Everything else is still needed though as it has its own frame types to achieve its behavior.
More on this in https://github.com/bidiweb/wish/issues/5 so that we don't replicate that discussion here.
After a read-through of WiSH, it looks to me that if I had this for browsers I would use it. For mobile though where I can control my networking stack it’s less clear as a choice as it adds an extra framing layer that is not needed if I can directly access HTTP/2 byte streams like I do with Proxygen right now, or can extend HTTP/2. If I only had standard HTTP libraries though, and WiSH was available over them, I’d use it.