I'm trying to understand what is the difference between HTTPS and http/2?
If I'm going to build a Node.js/express app, what should I use?
Can I use HTTPS with http/2?
Maybe if I use HTTPS, I don't need http/2 because it's the same, or HTTPS use http/2 under the hood?
I'm confused.
Someone is linked to me "difference between HTTP 1.1 and HTTP 2.0 [closed]", but I understand the difference between HTTP and HTTP2. I'm asking about HTTPS and HTTP/2
HTTP - A protocol used by clients (e.g. web browsers) to request resources from servers (e.g. web servers).
HTTPS - A way of encrypting HTTP. It basically wraps HTTP messages up in an encrypted format using SSL/TLS. The web is moving towards HTTPS more and more and web browsers are starting to put more and more warnings when a website is served over unencrypted HTTP. Unless you have a very good reason not to, use HTTPS on any websites you create now.
Digging into HTTP more we have:
HTTP/1.1 - this was the prevalent format of HTTP until recently. It is a text-based protocol and has some inefficiencies in it - especially when requesting lots of resources like a typical web page. HTTP/1.1 messages can be unencrypted (where web site addresses start http://) or encrypted with HTTPS (where web site address start with https://). The client uses the start of the URL to decide which protocol to use, usually defaulting to http:// if not provided.
HTTP/2 - a new version of HTTP released in 2015 which addresses some of the performance issues by moving away from a text based protocol to a binary protocol where each byte is clearly defined. This is easier to parse for clients and servers, leaves less room for errors and also allows multiplexing. HTTP/2, like HTTP/1.1, is available over unencrypted (http://) and encrypted (https://) channels but web browsers only support it over HTTPS, where it is decided whether to use HTTP/1.1 or HTTP/2 as part of the HTTPS negotiation at the start of the connection.
HTTP/2 is used by about a third of all websites at the time of writing (up to 50% of websites as of Jan 2020, and 67% of website requests). However not all clients support HTTP/2 so you should support HTTP/1.1 over HTTPS and HTTP/2 over HTTPS where possible (I believe node automatically does this for you when using the http module). I do not believe HTTP/1.1 will be retired any time soon. You should also consider supporting HTTP/1.1 over unencrypted HTTP and then redirect to HTTPS version (which will then use HTTP/1.1 or HTTP/2 as appropriate). A web server like Apache or Nginx in front of Node makes this easy.
HTTP/3 - the next version of HTTP, currently under development. It is expected to be finalised in 2020 though it will likely be late 2020 or even 2021 before you see this widely available in web servers and languages like node. It will be built on top of a UDP-based transport called QUIC (rather than the TCP-based protocol that HTTP/1.1 and HTTP/2 are based on top of). It will include part of HTTPS in the protocol so HTTP/3 will only be available over HTTPS.
In short you should use HTTP/1.1 over HTTPS, should consider HTTP/2 as well if easy to implement (not always possible as not quite ubiquitous yet - but getting there) and in future you might be using HTTP/3.
I suggest you get a firm understanding of all of these technologies (except maybe HTTP/3 just yet) if you want to do web development. It will stand you in good stead.
Related
For example I have a node server which uses the built-in module "http" (which is http1.1 version I assume). So will it be able to serve any XHR request from browser with http2 protocol?
Yes. Browsers negotiate HTTP/2 as part of the HTTPS setup (since browsers only support HTTP/2 over HTTPS). If HTTP/2 is not supported by both sides it will just use HTTP/1.1
Thanks one of the great things about HTTP/2 and why it’s made such headway - the ability to (almost!) seamlessly roll it out to the web without breaking existing sites/servers/browsers.
When I start my API server on local it serves http/1.1 but I found that when it's deployed on VPS and set up with Cloudflare, the browser shows the protocol is http/3. So between the clients and Cloudflare is http/3 and Cloudflare and VPS is http/1.1 is this correct? That means http/3 is served only by DNS, my server is still plain http/1.1 and I need to migrate it to http/2 to be truly supported http/2. (I'm using node so it'll be a switch from http to http2 module)
When your web application / web API is behind Cloudflare, Cloudflare acts as a reverse proxy. This means that there are two "legs" of the connection:
From the end user's client (browser / mobile phone etc...) to Cloudflare
From Cloudflare to your origin server (in your case a VPS)
From a user point of view, they see leg (1) so it is quite easy to enable HTTP/2 or HTTP/3 (see documentation) even if your origin server does not support them. This is what you see in the browser when testing, depending on your configuration in the Cloudflare Dashboard.
For leg (2), only HTTP/1.1 is currently supported (as noted also in this Support KB). You can still optimize the setup of that leg by using features such as Argo Smart Routing or Argo Tunnel,
Update Jun 2022: HTTP/2 to the origin server is now supported and can be enabled in the dashboard. See here for more details.
I have a question about SSL. As I know, when we use browser to request from https server, it will make an SSL handshake first then all data will be encryption in the connection. But if I make a request without browser (like request module in nodejs, postman...), will it be an SSL handshake and data encryption on the connection?
Anyone know please explain to me, thank you.
First, stop saying SSL. Its successor is TLS, and it will have 20 years next January.
TLS is a protocol sitting on top of TCP typically (other variants can also use UDP), and provides on top of TCP features some new features about endpoints authentication and transport confidentiality and integrity.
In a way, you can understand it as being sandwiched between TCP and the higher level application protocol, like HTTP.
Saying otherwise you can use many others protocols on top of TLS: you have all email related ones (SMTP, IMAP, POP, etc.), you can have FTP on top of it (while probably not a good idea nowadays), XMPP for realtime communications, etc.
In short, any protocol using TCP could use TLS with some adaptation.
So HTTP is one case among others. HTTP is between an HTTP client and an HTTP server, or webserver for short.
A browser is an HTTP client. One among many ones. When you use curl or wget you are also an HTTP client. So if any HTTP client access an http:// link it will first do the TLS handshake, after the TCP connection and before starting to do anything really related to the HTTP protocol.
You have specialized libraries dealing with TLS so that not all program need to recode everything about this again, since it is also complicated.
Wondering how to setup a persistent connection between client and server in Node.js.
The persistent connection should be able to send requests back and forth from both sides. It seems like it needs to have a mechanism for delineating each request, such as \r\n if requests are JSON, but not sure what best-practices are here if it's already been done before. Wondering how web-sockets handle this.
Mozilla says Keep-Alive shouldn't be used in production, so wondering if that still holds with HTTP2.
With EventSource you can receive server events, but wondering if there is a way to add client events to send to the server.
In the end, I would like to have a simple setup for two-way communication like WebSockets, but am not sure of best practices in HTTP2 and if it should just be done with WebSockets. I would prefer to try to do this without websockets.
https://daniel.haxx.se/blog/2016/06/15/no-websockets-over-http2/
With all due respect, I believe you're under the mistaken assumption that the HTTP/2 connection is page specific.
In actuality, HTTP/2 connection are often browser wide connections. It's not possible for an HTTP/2 push to know which page/tab will use the data (possibly more than one).
Also, see the discussion here that includes a myriad number of reasons as to why HTTP/2 couldn't (or shouldn't) be used as a Websocket alternative.
On the other hand, if HTTP/2 is "promised" and Websockets are unavailable, than polling might be an option.
Polling with HTTP/2 will be significantly more resource friendly than polling with HTTP/1.1, even though it would still be far more expensive than Websocket push (or poll) due to the extra header and authentication data (it will also decrease security, but that's probably something nobody really cares about all that much).
P.S.
Websockets over HTTP/2
This is a non-issue unless HTTP/1.1 is retired (in fact, IMHO, this is intentional and good).
It's true that HTTP/2 connections can't be "upgraded" (changed) to Websocket connections, nor can they tunnel Websocket data, but that means absolutely nothing.
New Websocket connections use the existing HTTP/1.1 upgrade handshake and that's it.
Any HTTP/2 server that supports Websockets will support the handshake.
Keep-Alive
Mozilla warns against the non-standard Keep-Alive header. However, the Connection: keep-alive standard for HTTP/1.1 (which is also the default for HTTP/1.1 clients) is definitely recommended.
SSE (Server Sent Events)
SSE pre-date Websockets and they didn't get much traction in the community, while Websockets were adopted with a vengeance.
wondering if there is a way to add client events to send to the server
Simple - send an HTTP request. The reply can be asynchronously received with SSE.
I like Websockets better. As far as server-side goes, I find them easier to manage and code.
My gut feeling is that a SPDY-capable browser will treat it as though it were a SPDY response. However, the most I can find is a reassurance that an H2 response will degrade gracefully to HTTP1.1. I'm considering serving assets in an H2 oriented manner (multiple requests, no domain sharding, etc.), but I do need to support some non-H2 browsers (e.g. Android 4.1's browser). Will I be OK if all the clients are at least SPDY compliant?
Bonus question: are there any complications involved with mixing protocols? We're on a web framework that doesn't support H2, but I'm considering serving most of our assets from a CDN. Assume TLS.
Browsers that are SPDY or HTTP/2 enabled use a TLS extension (either the older NPN or the new ALPN) to negotiate the protocol they speak over TLS.
The client sends the list of protocols that it is capable to speak in order of preference (e.g. h2,spdy/3.1,http/1.1), and the server picks one protocol among those in that list that it also supports (and that match security required constraints).
For example, if you have an older browser that does not support h2, it will send spdy/3.1,http/1.1, and the server will never pick h2 (even if it supports it).
If the server does not support SPDY, the only option left is http/1.1, and this is what constitutes the "graceful degradation" to HTTP/1.1.
There is never the possibility that if the client requested to speak SPDY (and not HTTP/2), the server replies with HTTP/2, unless gross implementation errors on the server.
SPDY is being phased out in favor of HTTP/2. For example, recent Chrome versions don't support SPDY anymore.
There are no complications when you you make requests to different domains, and the servers speak different protocols: this is handled transparently by the browsers.
If your server can speak SPDY and HTTP/1.1, and the CDN can speak HTTP/2 and HTTP/1.1, then you have to use a browser that supports all 3 protocols to leverage the SPDY and HTTP/2 benefits.
The browser can negotiate SPDY with your server, and negotiate HTTP/2 with the CDN, and the page composed of resources from both origins.
However, browsers will soon drop (or have already dropped) SPDY, so with recent browsers you may end up speaking HTTP/1.1 with your server and HTTP/2 with the CDN, thereby losing the SPDY|HTTP/2 benefits for resources on your server.