1

我正在使用 OkHttpClient 3.14.9。我需要使用 TLSv1.3 和 http2 协议建立连接。问题是服务器不支持 ALPN(OkHttpClient 使用这个扩展与服务器建立使用哪个版本的 http 协议)。

在服务器端 http1.1 被禁用,只有 http2 被启用。客户端没有成功建立连接。当服务器启用 http1.1 时,我的客户端通过 http1.1 连接到服务器。

据我了解,这意味着客户端和服务器之间没有关于http版本的协商:客户端正在尝试通过ALPN进行协商->服务器不“理解”客户端->客户端认为服务器不支持http2并尝试连接http1.1

那么,如果不是 ALPN,OkHttpClient 是否有其他方法可以通过 http2 建立 TLS 连接?(重要的是连接是 TLS,因为没有 TLSProtocol.H2_PRIOR_KNOWLEDGE效果很好)

4

1 回答 1

1

像下面这样的东西应该/可以在 JDK9 上工作。但它很难测试,因为它实际上是一个损坏的服务器。

  val sslSocketFactory = context.socketFactory
  val wrapped = object : DelegatingSSLSocketFactory(sslSocketFactory) {
    override fun configureSocket(sslSocket: SSLSocket): SSLSocket {
      return object : DelegatingSSLSocket(sslSocket) {
        override fun getApplicationProtocol(): String {
          return "h2"
        }
      }
    }
  }

  val client = OkHttpClient.Builder()
    .sslSocketFactory(wrapped, trustManager)
    .build()

  val response = client.newCall(Request.Builder().url("https://api.twitter.com/").build()).execute()
  println(response.protocol)

您可以在此处获取委托套接字工厂https://github.com/square/okhttp/blob/c1a6dec505a62af07e4c117e777302bd136e107f/okhttp-testing-support/src/main/kotlin/okhttp3/DelegatingSSLSocketFactory.kt

但在不同的 JVM 或不同的 Android 版本上,这可能会有所不同。

这就是我们为不同套接字类型(如 Android10SocketAdapter.kt、ConscryptSocketAdapter.kt 等)提供适配器的原因。

https://github.com/square/okhttp/blob/3ad1912f783e108b3d0ad2c4a5b1b89b827e4db9/okhttp/src/jvmMain/kotlin/okhttp3/internal/platform/android/SocketAdapter.kt#L35

于 2022-01-26T19:34:26.127 回答