code: @Override
      public final void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
          if (evt == Http2ConnectionPrefaceAndSettingsFrameWrittenEvent.INSTANCE) {
              // The user event implies that we are on the client.
              tryExpandConnectionFlowControlWindow(connection());
          } else if (evt instanceof UpgradeEvent) {
              UpgradeEvent upgrade = (UpgradeEvent) evt;
              try {
                  onUpgradeEvent(ctx, upgrade.retain());
                  Http2Stream stream = connection().stream(HTTP_UPGRADE_STREAM_ID);
                  if (stream.getProperty(streamKey) == null) {
                      // TODO: improve handler/stream lifecycle so that stream isn't active before handler added.
                      // The stream was already made active, but ctx may have been null so it wasn't initialized.
                      // https://github.com/netty/netty/issues/4942
                      onStreamActive0(stream);
                  }
                  upgrade.upgradeRequest().headers().setInt(
                          HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text(), HTTP_UPGRADE_STREAM_ID);
                  stream.setProperty(upgradeKey, true);
                  InboundHttpToHttp2Adapter.handle(
                          ctx, connection(), decoder().frameListener(), upgrade.upgradeRequest().retain());
              } finally {
                  upgrade.release();
              }
              return;
          }
          super.userEventTriggered(ctx, evt);
      }
docs: Handles the cleartext HTTP upgrade event. If an upgrade occurred, sends a simple response via
  HTTP/2 on stream 1 (the stream specifically reserved for cleartext HTTP upgrade).