@Override
            public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
                if (!(evt instanceof SslHandshakeCompletionEvent)) {
                    ctx.fireUserEventTriggered(evt);
                    return;
                }

                final SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;
                handshakeFailed = !handshakeEvent.isSuccess();
                if (handshakeFailed) {
                    // The connection will be closed automatically by SslHandler.
                    return;
                }

                if (!sslHandler.handshakeFuture().isDone()) {
                    // Ignore successful handshake events for other SslHandlers in the pipeline.
                    // This can happen when a client connects with ssl to an encrypted proxy server,
                    // and then to an encrypted backend. Without this check, clients may incorrectly
                    // conclude protocol negotiation and start a new session.
                    return;
                }

                final SessionProtocol protocol;
                if (isHttp2Protocol(sslHandler)) {
                    if (httpPreference == HttpPreference.HTTP1_REQUIRED) {
                        finishWithNegotiationFailure(ctx, H1, H2, "unexpected protocol negotiation result");
                        return;
                    }

                    addBeforeSessionHandler(p, newHttp2ConnectionHandler(ch, H2));
                    protocol = H2;
                } else if (clientFactory.useHttp2WithoutAlpn() && attemptUpgrade()) {
                    configureUpgradeCodec(ch, h -> addBeforeSessionHandler(p, h));
                    p.remove(this);
                    return;
                } else {
                    if (httpPreference != HttpPreference.HTTP1_REQUIRED) {
                        SessionProtocolNegotiationCache.setUnsupported(remoteAddress(ctx), H2);
                    }

                    if (httpPreference == HttpPreference.HTTP2_REQUIRED) {
                        finishWithNegotiationFailure(ctx, H2, H1, "unexpected protocol negotiation result");
                        return;
                    }

                    addBeforeSessionHandler(p, newHttp1Codec(
                            clientFactory.http1MaxInitialLineLength(),
                            clientFactory.http1MaxHeaderSize(),
                            clientFactory.http1MaxChunkSize()));
                    protocol = H1;
                }
                finishSuccessfully(p, protocol);
                p.remove(this);
            }
See <a href="https://http2.github.io/http2-spec/#discover-https">HTTP/2 specification</a>.
core/src/main/java/com/linecorp/armeria/client/HttpClientPipelineConfigurator.java