Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
More efficient and correct H1C-to-H2C upgrade
Motivation: The current HTTP/1-to-2 upgrade has the following slightly inter-related issues: 1. When a user specifies an explicit session protocol (H1C/H1/H2C/H2) instead of HTTP/HTTPS, the session creation must fail when the negotiated protocol does not match exactly. For example, when a user specified H2C, a rejected upgrade request should fail session creation. 2. When connecting to a host whose name is registered in /etc/hosts, the 'Host' header of the HEAD upgrade request is not set to the host name but the host address. 3. When a user specifies HTTP/HTTPS as session protocol and the remote host does not support H2C/H2, the client currently keeps sending the HEAD upgrade request. We could cache the list of the hosts with no HTTP/2 support, so we do not send upgrade requests unnecessarily. 4. Some servers send 'Connection: close' header when rejecting a upgrade request, resulting disconnection. When this happens and a user specified HTTP as session protocol, the client should retry the connection attempt silently, so that a user does not notice the upgrade failure, because it's not really a failure. Modifications: - (2) Fork DefaultHostsFileEntryResolver and HostsFileParser so that they do not omit the host name in the resolved InetAddress, where the host name is picked up from by Armeria - (1) Add SessionProtocolNegotiationException - Mark the session creation as failure when protocol upgrade fails or the protocol is different from what user expected - See HttpConfigurator and HttpSessionChannelFactory - (3) Add SessionProtocolNegotiationCache - Update the cache when protocol upgrade is rejected by remote host in HttpConfigurator - (4) HttpSessionChannelFactory now retries the connection attempt when HttpConfigurator finds the upgrade response contains 'Connection: close' header. - Add the test cases for (1, 3, 4) to ThriftOverHttpClientTServletIntegrationTest - Miscellaneous: - When HTTP codec fails to decode a response, use the cause of the decoder failure as the invocation result, which is much more informative. - Add another variant of Exceptions.logIfUnexpected() - Add Exceptions.clearTrace() to remove the stack trace of an exception easily - Fix a bug where HttpServerHandler sends content in a response to a HEAD request. A response content of a HEAD request must be empty. Result: - Invocation now fails when the negotiated protocol does not match the desired protocol. - The 'Host' header in a upgrade request now contains host name even if the host address was resolved via the /etc/hosts file - HTTP/1-to-2 upgrade request is sent only when necessary. - Http/1-to-2 upgrade deals better with 'Connection: close' headers.
- Loading branch information