Here's a kotlin script that reproduces the problem:
import okhttp3.*
val client = OkHttpClient.Builder()
.protocols(listOf(Protocol.HTTP_1_1, Protocol.HTTP_2))
.build()
fun directConnect() {
val url = HttpUrl.parse("https://http2.akamai.com/")
val request = Request.Builder()
.url(url)
.build()
val response = client.newCall(request).execute()
println("Headers from direct connection")
response.headers().names().forEach { if (it.contains("proto")) {println(it + response.headers().values(it))} }
}
fun urlConnect() {
val url = java.net.URL("https://http2.akamai.com/")
val urlFactory = okhttp3.OkUrlFactory(client)
java.net.URL.setURLStreamHandlerFactory(urlFactory);
val connection = url.openConnection()
val headers = connection.getHeaderFields()
println("Headers from url connection")
headers.keys.forEach{ if (it != null && it.contains("proto")) {println(it + headers.get(it))} }
}
println(System.getProperty("java.home"))
directConnect()
println("--------------")
urlConnect()
Command to run the script:
kotlinc -cp okhttp-3.12.1.jar:okio-1.17.2.jar:okhttp-urlconnection-3.12.1.jar -script http2.kts
The output I see on Java 10 is:
Headers from direct connection
myproto[h2]
protocol_negotiation[h2]
--------------
Headers from url connection
myproto[]
protocol_negotiation[h1]
That is, directly using OkHTTP client results in http/2 neogitation, but using url-connection results in http1.x.
By quickly scanning the code, I was unable to determine if this is a fundamental limitation or just a bug.
Try calling setURLStreamHandlerFactory() before creating the URL in urlConnect().
Sweet, that worked!
Thanks @amirlivneh