Is HTTP/2 without SPDY possible yet? - spdy

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.

Related

Is there a reason why HTTP2 is required when websocket is already available?

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.

Why do web browsers not support h2c (HTTP/2 without TLS)?

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.

What is the WebSockets alternative in the HTTP/2 world?

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.

What is the best and current way to move to HTTPS on a large website?

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.

SPDY as replacement for Websockets?

First off - I understand SPDY and Websockets aren't the same thing, and that you can run Websockets over SPDY like you can with HTTP, etc.
However - I am wondering if SPDY would be a viable replacement for websockets if I am trying to provide a REST (like) API that also supports server push (bi-directional calls over the same connection).
My current prototype uses websockets (node+socket.io), and works fine. However, my issue with websockets is I am having to dream up my own JSON protocol for routing requests both to and from the server. I'd much rather use REST-style URIs and Headers in requests, which fits better in a REST-based architecture. SPDY seems like it would support this better.
Also, because of the lack of headers, I'm concerned websockets won't fit well in our deployment network, and thinking SPDY would be a better fit again.
However, I've not seen many examples of bidirectional SPDY requests, apart from pushing files to the browser. I would like to push events and data to the browsers, such as:
Content-Type: application/json
{
"id": "ca823f3e233233",
"name": "Greg Brady"
}
but it's not clear to me how the browser/Javascript might "listen" and react to these, as I would with the WebSocket and socket.io APIs.
Let's start from the beginning: why would you want to run WebSockets over SPDY, as opposed to doing an HTTP upgrade? If you upgrade an HTTP connection to WS, then nothing else can use that TCP stream - the WS connection can be idle, but the connection is blocked nonetheless. With SPDY, you can mux multiple requests/responses, and a websocket connection (or even multiple) over the same underlying TCP stream. On a practical note, as of July 2012, WS over SPDY is still a work in progress, so you will have to wait to use SPDY for WebSockets - hopefully not too long though!
But let's assume the support is there... The reason why it's not clear how to listen for "SPDY Push" from JavaScript is because there is no way to do that! A pushed resource goes into your browsers cache - nothing more, nothing less. If you need to stream data to your javascript callbacks, then WebSockets, or Server-Sent Events (SSE) is the answer.
So, putting it all together:
HTTP adds a lot of overhead for individual small requests (headers, etc)
WebSockets gives you a low overhead channel, but requires you implement own routing
SPDY will significantly reduce the overhead and cost of small HTTP requests (win)
SSE is a good, simple alternative to pushing data to the client (which works today, over SPDY)
You could use SPDY+SSE to meet your goals, and all of that communication can run over the same TCP channel. SPDY requests to the server, SSE push from the server.
First some clarifications:
The base WebSocket protocol (IETF 6455) is not layered onto HTTP. The initial handshake for WebSocket connections is HTTP compatible, but once the handshake is completed, the protocol is a framed, bi-directional full-duplex connection with very low overhead (often just 2 bytes per frame of header).
The WebSocket over SPDY idea is a proposal that may or may not see the light of day. In this case, WebSocket is in fact being layered on SPDY. The initial connection/handshake may happen faster due to the nature of SPDY versus HTTP, however, the data frames will have more overhead because the WebSocket header fields are mapped into SPDY header fields.
SPDY aims to be a more efficient replacement for HTTP. WebSocket is an entirely different beast that enables very low-latency bi-directional/full-duplex messaging between the client and server.
If what you are interested in server-push with a simple API and you don't need super low-latency, then you might consider server-sent events which has an API that is simple and similar to the WebSocket API. Or you could look into one of the many good Comet libraries which enable server-push but will better support old browsers unlike any of the above solutions.
However, my issue with websockets is I am having to dream up my own
JSON protocol for routing requests both to and from the server.
I wrote a thin RPC layer over socket.io wrapping network calls in promises just for that reason. You can take a peek at it here.

Resources