This is only partially true. http/1.1 has well defined semantics for persistent connections. The server can send the header "Connection: Close" to indicate to the client it is closing the idle connection. All http/1.1 clients should respect that since it's in the RFC.
The problem is many servers don't send this header when closing idle connections. nginx is a notorious example. But well behaving servers should be sending that header if they intend to close the connection after a request.
Hmm, that's good catch - thanks. HTTP 1.0 didn't explicitly specify anything around persistent connections, so in practice you can add Keep-Alive header and hope that the server will respect it. By comparison, HTTP 1.1 defaults to persistent always and requires a "Connection: close" header to indicate otherwise.
It's perfectly normal (and allowed) for servers to send back a version string of "HTTP/1.1" even if the client sent the request as "HTTP/1.0". As long as they don't do anything in their response that assumes that the client has 1.1 features, all is fine. This basically just means:
* Don't use chunked encoding in the response. (Technically a 1.0 client could specifically indicate support for that by sending a "TE: chunked" header, but since chunked encoding arrived at the same time as 1.1 I think most servers just assume that HTTP/1.0 clients never support it)
* Don't assume that the client supports keep-alive connections. However, prior to HTTP/1.0 clients often did indicate that they could do keep-alive by sending "Connection: keep-alive". The only real difference in 1.1 is that now the client must support it unless they specifically indicate that they don't by sending "Connection: close". In the absence of a "Connection:" header, a 1.1 client supports keep-alive and a 1.0 does not.
HTTP1.1 only closes the connection if one party sets Keepalive: Close. It was HTTP1.0 that was one-shot. There was also pipelining support added but apparently nobody bothered to support it.
The one thing that HTTP/2 gives me that I find useful is a clear indication when the server closed an idle connection, so that clients can tell if their request was likely seen or not when the connection is closed.
19.7.1 Compatibility with HTTP/1.0 Persistent Connections
Some clients and servers may wish to be compatible with some previous
implementations of persistent connections in HTTP/1.0 clients and
servers. Persistent connections in HTTP/1.0 must be explicitly
negotiated as they are not the default behavior. HTTP/1.0
experimental implementations of persistent connections are faulty,
and the new facilities in HTTP/1.1 are designed to rectify these
problems. The problem was that some existing 1.0 clients may be
sending Keep-Alive to a proxy server that doesn't understand
Connection, which would then erroneously forward it to the next
inbound server, which would establish the Keep-Alive connection and
result in a hung HTTP/1.0 proxy waiting for the close on the
response. The result is that HTTP/1.0 clients must be prevented from
using Keep-Alive when talking to proxies.
This is pretty much unrelated to the discussion earlier on (which was about the interaction of different flow control mechansisms). But nevertheless one answer that tries to clear up some misunderstandings:
You can reuse connections with every HTTP version up from HTTP/1.1. The main difference between HTTP/1.1 and HTTP/2 and /3 is that you can't make concurrent requests on a single connection with HTTP/1.1, but you can with /2 and /3.
For how long a connection will stay open after a request will be determined by keepalive settings on the client and server side. All HTTP versions up from 1.1 allow you not to use a connection for 30s and then make another request.
Agree with the point, but remember normal HTTP/1.1 /2 keep alive should close that connection in 15-30 seconds for all modern browsers. It will give rise to a DOS vulnerability as you point out.
“However, the problems with HTTP2 are not because of HTTP2 itself, but because of the heavier costs of provisioning and maintaining healthy infrastructure that can afford to keep stateful long TCP/IP sessions by themselves.”
That's already been the case with HTTP 1 keep-alives and even more so with web sockets and unlike in the late 90s it's just not an issue for the vast majority of services.
That said, HTTP/2 also has no requirement that you keep a connection open after you're done with the request – the specification clearly states that either end can cleanly close the connection at any point. A browser might choose to implement something similar to the traditional keep-alive timer but there's no reason why you can't make a single request or close the connection immediately after a fetching a single round of resources. The only difference is that this process is both faster and more reliable than it was with HTTP 1 keep-alives & pipelining.
Are you sure about that? That seems to violate the http/1.1 RFC. I think the node.js docs are talking about http/1.0 there. http/1.1 uses the "Connection" header to indicate whether to persist the connection.
Well, they also appear to be stacking the deck a bit, by configuring HTTP/1.1 in ways that no sane person would (i.e., force-closing the connection after each resource -- HTTP/1.1 already supports re-using the existing connection for further requests, but they're explicitly disallowing that to make HTTP/2 seem better).
There's nothing stopping you from having one connection per request with HTTP/2. You could build your software to simply have the same behavior as HTTP/1.1 with keep-alive
The problem is many servers don't send this header when closing idle connections. nginx is a notorious example. But well behaving servers should be sending that header if they intend to close the connection after a request.
reply