Do not send keep-alive or close in HTTP Upgrade requests#732
Do not send keep-alive or close in HTTP Upgrade requests#732rousskov wants to merge 4 commits intosquid-cache:masterfrom
Conversation
... because it breaks some Google Voice services, not present in RFC 7230 Upgrade example and popular client requests, and is redundant in Upgrade requests (because they are HTTP/1.1). TODO: This also disables sending Connection:close in Upgrade requests, resulting in a misleading false value of flags.keepalive.
... but honor the original no-keepalive decision so that we do not violate server_persistent_connections=off and internal restrictions.
|
The primary/first part (branch commit 5dd22d6) has been tested and appears to resolve the problem when Squid was sending a Connection:keep-alive header and receiving an The second part (branch commit ac2df70) handles the case when Squid was sending a Connection:close header; that change has not been tested. AFAICT from manual tests, Google Voice service does not like either header in the Upgrade request. |
Please do not. server_persistent_connections=off is an explicit admin policy choice to override HTTP/1.1 default persistence. We MUST send "Connection:close" on HTTP/1.1 and later messages to enforce that admins policy. They can remove the setting to let Squid perform the default working behaviour. Long-term we should switch these persistence config settings from onoff to YesNoNone so we can explicitly send keep-alive/close when admin explicitly require one or other behaviour. While still doing best-effort behaviour like this PR has in the None case. In regards to testing; has the existence of Connection with other values been checked to see if it is the hop-by-hop or persistence which breaks? |
Which this PR honors IMO -- Squid does not reuse HTTP connections if server_persistent_connections is off.
Why? AFAICT, when server_persistent_connections is
Let's assume the admin had a good/valid reason to disable persistent connections with servers. They cannot just go back to the default behavior. Why do we have to prevent that same admin from supporting HTTP Upgrade (with admin-selected servers or for admin-specified protocols)? This PR gives the admin the choice. N.B. Persistence does not matter (is not applicable) if the Upgrade is successful (we are no longer speaking HTTP at that point). It only matters for rare cases where the server refuses to upgrade. In those cases, Squid will close the connection after handling the (negative) server response to the Upgrade request if server_persistent_connections was set to
I am not sure I understand the "to see..." part of the question. FWIW, in my tests, the current Google Voice service implementation appears to look at the last Connection header field item received. If that item is not "upgrade", the service considers the HTTP request invalid, responding with HTTP 400 "Bad Request" message. The previous items are irrelevant. The service implementation changes in response to bug reports, and I would not be surprised if it starts tolerating other Connection items order, but given what we now know about this and other Upgrade-related agents (both clients and servers), it is unwise to send anything other than "Connection: upgrade" to them. Too many will break. |
|
Sorry, I mistook the comment as applicable to response messages where there is a MUST requirement. On re-review I see it is for requests which leave the Connection:close sending as optional. I am approving for merge as-implemented. Your response answers my question about testing. That clearly indicates a buggy Voice service. If you can please document your tests and report to the relevant Google dev if you can find them and/or the HTTPbis WG so the spec authors can be aware of this case for the latest spec update. |
A presence of a Connection:keep-alive or Connection:close header in an Upgrade request sent by Squid breaks some Google Voice services. FWIW, these headers are not present in RFC 7230 Upgrade example, and popular client requests do not send them. * In most cases, Squid was sending Connection:keep-alive which is redundant in Upgrade requests (because they are HTTP/1.1). * In rare cases (e.g., server_persistent_connections=off), Squid was sending Connection:close. Since we cannot send that header and remain compatible with popular Upgrade-dependent services, we now do not send it but treat the connection as non-persistent if the server does not upgrade and expects us to continue reusing the connection.
Done. The tests I used are basic curl requests with |
A presence of a Connection:keep-alive or Connection:close header in an Upgrade request sent by Squid breaks some Google Voice services. FWIW, these headers are not present in RFC 7230 Upgrade example, and popular client requests do not send them. * In most cases, Squid was sending Connection:keep-alive which is redundant in Upgrade requests (because they are HTTP/1.1). * In rare cases (e.g., server_persistent_connections=off), Squid was sending Connection:close. Since we cannot send that header and remain compatible with popular Upgrade-dependent services, we now do not send it but treat the connection as non-persistent if the server does not upgrade and expects us to continue reusing the connection.
A presence of a Connection:keep-alive or Connection:close header in an Upgrade request sent by Squid breaks some Google Voice services. FWIW, these headers are not present in RFC 7230 Upgrade example, and popular client requests do not send them. * In most cases, Squid was sending Connection:keep-alive which is redundant in Upgrade requests (because they are HTTP/1.1). * In rare cases (e.g., server_persistent_connections=off), Squid was sending Connection:close. Since we cannot send that header and remain compatible with popular Upgrade-dependent services, we now do not send it but treat the connection as non-persistent if the server does not upgrade and expects us to continue reusing the connection.
…#732) A presence of a Connection:keep-alive or Connection:close header in an Upgrade request sent by Squid breaks some Google Voice services. FWIW, these headers are not present in RFC 7230 Upgrade example, and popular client requests do not send them. * In most cases, Squid was sending Connection:keep-alive which is redundant in Upgrade requests (because they are HTTP/1.1). * In rare cases (e.g., server_persistent_connections=off), Squid was sending Connection:close. Since we cannot send that header and remain compatible with popular Upgrade-dependent services, we now do not send it but treat the connection as non-persistent if the server does not upgrade and expects us to continue reusing the connection.
A presence of a Connection:keep-alive or Connection:close header in an Upgrade request sent by Squid breaks some Google Voice services. FWIW, these headers are not present in RFC 7230 Upgrade example, and popular client requests do not send them. * In most cases, Squid was sending Connection:keep-alive which is redundant in Upgrade requests (because they are HTTP/1.1). * In rare cases (e.g., server_persistent_connections=off), Squid was sending Connection:close. Since we cannot send that header and remain compatible with popular Upgrade-dependent services, we now do not send it but treat the connection as non-persistent if the server does not upgrade and expects us to continue reusing the connection.
A presence of a Connection:keep-alive or Connection:close header in an
Upgrade request sent by Squid breaks some Google Voice services. FWIW,
these headers are not present in RFC 7230 Upgrade example, and popular
client requests do not send them.
In most cases, Squid was sending Connection:keep-alive which is
redundant in Upgrade requests (because they are HTTP/1.1).
In rare cases (e.g., server_persistent_connections=off), Squid was
sending Connection:close. Since we cannot send that header and remain
compatible with popular Upgrade-dependent services, we now do not send
it but treat the connection as non-persistent if the server does not
upgrade and expects us to continue reusing the connection.