I really search the web, and I can not find the reason why web browsers do not support h2c (http/2 with no TLS). Any idea, appreciated.
A little bit clarification
http/2 with https uses ALPN (this is called h2).
http/2 with http does not need ALPN(this is called h2c), but almost no web browser support it. Why is so?
I feel that for many resources, there is no need for confidentiality though authenticity is always good (the digital signature of the http body is not widely supported though there are some private implementations). Given confidentiality is not needed, then h2c is really a good thing to have.
Technically
There are several technical reasons why HTTP/2 is much better and easier to handle over HTTPS:
Doing HTTP/2 negotiation in TLS with ALPN is much easier and doesn't lose round-trips like Upgrade: in plain HTTP does. And it doesn't suffer from the upgrade problem on POST that you get with plain-text HTTP/2.
N% of the web doesn't support unsolicited Upgrade: h2cheaders in requests and instead respond with 400 errors.
Doing something else than HTTP/1.1 over TCP port 80 breaks in Y% of the cases since the world is full of middle-boxes that "help" out and replace/add things in-stream for such connections. If that then isn't HTTP/1.1, things break (this is also why brotli for example also requires HTTPS).
Ideologically
There's a push for more HTTPS on the web that is shared by and worked on in part by some of the larger web browser developer teams. That makes it considered a bonus if features are implemented HTTPS-only as they then work as yet another motivation for sites and services to move over to HTTPS. Thus, some teams never tried very hard (if at all) to make HTTP/2 work without TLS.
Practically
At least one browser vendor expressed its intention early on to implement and provide HTTP/2 for users done over plain-text HTTP (h2c). They ended up never doing this because of technical obstacles as mentioned above.
Related
Is there a reason why HTTP2 is required when websocket is already available?
Nathan Aw (Singapore)
Why do we need HTTP/2 when we have WebSockets? Well why did we need WebSockets when we have TCP? Or even IP? Protocols are basically agreed standards that can be implemented by independent parties.
WebSockets are good for two way communication but are mostly unstructured on top of that and application specific. HTTP is (mostly) a series of one-way requests to the server (ask for a resource, receive an answer) — though HTTP/2 enhances that slightly with HTTP/2 push and the binary framing layer could in theory be used more for proper two way push. So the full two way nature of WebSockets — the very thing they are good at — is not really needed for most HTTP use cases.
Looking at HTTP, it has various extras that WebSockets does not have. Including defined methods, headers and compression. This allows a well-defined understanding between various HTTP implementations to facilitate communications for its use case including features like multiplexing, caching, compression, redirects, error handling... etc. If you had to reinvent all of those on top of WebSockets (which is a very raw protocol), you’d end up with an HTTP/2 like protocol.
Could HTTP/2 have used WebSockets to act as it’s underlying transport layer? Possibly, but that’s an unnecessary extra level of abstraction (IP->TCP->WS->HTTP2->HTTP), not to mention that websockets are often established over HTTP initially. HTTP is big enough to have its own transport protocol so in fact they’ve gone the other way and specified WebSockets over HTTP/2.
Finally, it should also be noted that HTTP/2 does not make Web Sockets obselete either. They are different and with different advantages and disadvantages.
The new HTTP/2 protocol comes with some promising features. Some of them:
Multiplexing - a single TCP connection can be used to make multiple HTTP/2 requests and receive multiple responses (to a single origin)
HTTP/2 Server Push - sending server responses to the client without receiving requests, i.e. initiated by the server
Bidirectional connection - HTTP/2 spec - Streams and Multiplexing:
A "stream" is an independent, bidirectional sequence of frames
exchanged between the client and server within an HTTP/2 connection.
The motivation behind HTTP/2 is explained here HTTP/2 FAQ:
HTTP/1.1 has served the Web well for more than fifteen years, but its
age is starting to show.
and
The goal of the Working Group is that typical uses of HTTP/1.x can use HTTP/2 and see some benefit.
So HTTP/2 is nice and comes to replace HTTP/1.x. Unfortunately, HTTP/2 does not support WebSockets. In this question Does HTTP/2 make websockets obsolete? it is made clear that the HTTP/2 Server Push is not an alternative, neither are Server-Sent Events.
Now to the question: What do we use if we want WebSockts functionality over HTTP/2?
Current forms of HTTP/2 Protocol Negotiation:
HTTP/2 connections start in one of three ways:
In an encrypted connection (TLS/SSL) using ALPN (Application Layer Protocol Negotiation). Most browsers require TLS/SSL for HTTP/2 and use this method for HTTP/2 connection establishment.
In clear text, using the HTTP/1.1 Upgrade header (same as Websockets). Most browsers require TLS/SSL for HTTP/2, so this is limited in it's support.
In clear text, using a special string at the beginning of an HTTP/1.1 connection (which could allow HTTP/2 servers in clear text to disable HTTP/1.1 support). Limited client support.
Negotiating the Websocket Protocol, present tense:
Negotiating Websocket connections, at the moment, requires HTTP/1.1 support and makes use of the HTTP/1.1 Upgrade header.
This is often performed by the same application server that listens to the HTTP/1.1 and HTTP/2 connections. Web applications that support concurrency (whether evented or thread based) are usually protocol agnostic (as long as HTTP semantics are preserved) and work well enough on both protocols.
This allows HTTP data to be used during connection establishment (and perhaps effect the Websocket connection state/authentication procedure).
Once the Websocket connection is established, it's totally independent from the HTTP semantics / layer.
Negotiating the Websocket Protocol in an HTTP/2 world:
In an HTTP/2 (only) world, which might be a while into the future, there could be a number of possible approaches to Websocket protocol negotiation: an ALPN based approach and an HTTP/2 "tunnel" (or "stream") approach.
The ALPN approach preserves protocol independence at the expense of the pre-upgrade (HTTP) stage, while the "stream" approach provides the HTTP pre-"upgrade" (or Connect) stage at the expense of high coupling and complexity.
The ALPN Approach:
One possible future approach will simply add the Websocket protocol to the ALPN negotiation table.
At the moment, ALPN is used to select (or default to) the "http/1.1" protocol and the Upgrade request is handled by the HTTP/1.1 server. Which means that Websocket still provides us with the HTTP header data during protocol negotiation (while using it's own TCP/IP connection)
In the future, ALPN might simply add "wss" as an available choice.
Using this approach, the Websocket (which is currently established using the HTTP/1.1 Upgrade header, both in encrypted and clear text forms) could easily be negotiated using the ALPN extension to the TLS/SSL layer.
This will keep the Websocket protocol independent from the HTTP/2 protocol and allow it's use even when HTTP isn't supported.
However, this will come with the downside that cookies and other HTTP headers might be no longer available as part of the protocol negotiation. Another difference (both good and bad) is that this approach will require a separate TCP/IP connection.
The HTTP/2 "tunnel" / "stream" approach
Another possible future approach, which is reflected in this proposed draft, will dispose of the HTTP/1.1 variation of the Websocket protocol in favor of an HTTP/2 "stream" approach.
HTTP/2 "streams" are the way HTTP/2 implements multiplexing and allows multiple requests to be handled concurrently. Each request receives a stream number ID and any data pertaining to this request (headers, responses etc') is identified using the same numerical stream ID.
Under this approach, "Websocket" data will be contain within the HTTP/2 wrapper and the stream ID will be used to identify the "Websocket" stream.
Although this might provide some benefits (HTTP headers and cookies could be provided as part of the Websocket negotiation), it's not without its downfalls.
Higher complexity and tighter protocol coupling are just two examples, both of which are very serious downfalls.
Conclusion:
At the time of this writing, HTTP/1.1 Upgrade semantics are required for Websocket connections, both when using clear text (ws) and encrypted (wss) connections.
The future is, as of yet, undecided and it will probably take a long time before the current Upgrade process (using HTTP/1.1) is phased out
Well your timing is rather apt!
A new version of the internet standards draft was literally just published:
Bootstrapping WebSockets with HTTP/2
Additional information here:
https://github.com/mcmanus/draft-h2ws/blob/master/README.md
And you can follow the discussion in it here:
https://lists.w3.org/Archives/Public/ietf-http-wg/2017OctDec/0032.html
Until this is approved, and then implemented by browsers and servers, I would say that Daniel Haxx’s post that you included in your question represents a very good summary of the current status.
One of your links actually has one answer: you can just use SSE.
Semantically, you can achieve the same things with either websockets or (SSE + POST ). The view that the two technologies address different use cases is, roughly speaking, bikeshedding around "this syntax works better for this".
There are ongoing efforts to port something similar to websockets to HTTP/2, but unless those technologies make possible new uses cases or efficiencies, I see no point.
From watching HTTPS everywhere on YouTube
they suggest that HTTPS and SPDY combined will be quicker than just serving web pages/assets over HTTP but then since reading SPDY is Dead. Long Live HTTP/2 and what with with HTTP2 support being a way off I am in two minds as to whether to move a large site I'm working on to HTTPS entirely as ultimately it will be slower since doing perf comparison tests (the DOM content loaded took twice the time to load). I also just read somewhere that browsers are dropping support for SPDY.
What is the state of SPDY and should I just wait until HTTP2 until I advocate moving everything to HTTPS everywhere? Should I accept the performance hit?
SPDY is definitely dying, now that HTTP/2 is an official specification.
Firefox and Chrome already support HTTP/2, and servers start to deploy it instead of SPDY - Google, Twitter, etc. Internet Explorer support will arrive soon with IE 11.
HTTP/2 is definitely gaining momentum, and the future will be on HTTP/2 and TLS.
You should not wait for HTTP/2, because it's already here.
About the performance hit, the usual recommendation is to benchmark, but there is evidence that HTTP/2 over TLS is much better than HTTP/1.1 over TLS, and possibly comparable - if not better - than cleartext HTTP/1.1, depending on the case.
Reasons behind this are a number of optimizations performed by HTTP/2 such as multiplexing, header compression and resource push, that are simply not possible with HTTP/1.1.
See for example the demo video (disclaimer, I am a Jetty committer) we gave in 2012 (about Jetty and SPDY at that time, but HTTP/2 behaves the same), or the Go language HTTP/2 demo, or the Akamai HTTP/2 demo.
With Jetty, for example, you can deploy Java webapps on HTTP/2, but also complete PHP websites on HTTP/2. Our own website, https://webtide.com, is WordPress served by Jetty on HTTP/2.
You can move to TLS and HTTP/2 now.
Most browsers do support HTTP/2 and so do some servers.
Akamai for example offers a HTTP/2 testpage (https://http2.akamai.com/). When I visit this page in chrome and go to chrome://net-internals/#spdy the page is listed with the protocol h2-14 (HTTP/2 draft 14). But when I open the console on the akamai page and type window.chrome.loadTimes() the property wasFetchedViaSpdy is true. Why is this? The Akamai-page is HTTP/2, not SPDY, roght?
Another thing I dont get is this tutorial (https://www.gatherdigital.co.uk/blog/how-to-setup-http-2-support/527). It says:
"How to setup HTTP/2 support (nginx, apache, plesk) [...]
Well, not quite HTTP/2, it's still mod_spdy."
What is this HTTP/2 "over" SPDY thing? The reason for my question is i want to do some meassurement on which pages make use of which protocol.
Long story short: SPDY is dead, long live HTTP/2!
Asking whether "HTTP/2 is possible without SPDY" implies that HTTP/2 somehow depends on SPDY. That isn't the case. Instead, HTTP/2 and SPDY are so similar that many implementations are hacking their existing SPDY support to be HTTP/2. There's also a lot of people who think HTTP/2 is SPDY, or get sloppy with their terminology. They're different protocols.
SPDY is a non-standard (but open) extension to HTTP/1.1 by Google designed to speed up web site loading and interaction and eliminate a lot of the hacks people do to reduce the number of connections. HTTP/2 started with SPDY and ran from there to create a new, standard protocol incompatible with both HTTP/1.1 and SPDY.
Many people treat SPDY and HTTP/2 as the same things, they're not. There have been significant changes in the standardization process between HTTP/2 and SPDY so that SPDY and HTTP/2 are not compatible. But they're really close, so many HTTP/2 implementations are just hacked SPDY implementations.
Many web servers and clients implemented SPDY even though it wasn't a standard. The performance gains were just too good to pass up.
Now that HTTP/2 is official, SPDY has been officially deprecated in favor of HTTP/2 and will be withdrawn as a standard in 2016. Web clients and servers are working to switch over. While the clients have adopted HTTP/2 very fast, server support seems to be lagging.
As of this writing, HTTP/2 has only been a standard for six weeks. Give it some more time. References to SPDY will be hanging around in HTTP/2 implementations, but that will be rapidly cleaned up. Firefox 36.0.4's Network console properly reports the protocol version as HTTP/2.
As for finding out whether HTTP/2 is used, look at the HTTP response object, it should have the protocol used.
This might sound really naive but I would really find a descriptive answer helpful.
So, my question is this:
I can use Firebug to look at AJAX requests made from any website I visit. So, am I right in saying that I wouldn't be able to examine the same communication between the client and the server if the website choses to use Websockets? In other words, does this make it more secure?
No. Not at all. Just because the browser does not (yet) have a tool to show WebSocket traffic, doesn't make it any more secure. You can always run a packet sniffer to monitor the traffic, for example.
No, because there will be other ways beside the browser-build in tools to read your traffic.
Have a try: Install and run Wireshark and you will be able to see all packets you send and receive via Websockets.
Depends on the application. If you are fully Ajax without reloading the document for data then I would think websockets would provide a better authentication for data requests then a cookie session in regards to connection hijack. Given that you are using SSL of course.
Never rely on secrecy of algorithm cause it only gives you false sense of security. Wiki: Security by obscurity
Remember that browser is a program on my computer and I am the one who have a full control over what is send to you, not my browser.
I guess it's only matter of time (up to few months IMO) when developer tools such as Firebug will provide some fancy tool for browsing data send/received by WebSockets.
WebSockets has both an unencrypted (ws://) and encrypted mode (wss://). This is analogous to HTTP and HTTPS. WebSockets protocol payload is simply UTF-8 encoded. From a network sniffing perspective there is no advantage to using WebSockets (use wss and HTTPS for everything at all sensitive). From the browser perspective there is no benefit to using WebSockets for security. Anything running in the browser can be examined (and modified) by a sufficiently knowledgeable user. The tools for examining HTTP/AJAX requests just happen to be better right now.