google / cronet-transport-for-okhttp

This package allows OkHttp and Retrofit users to use Cronet as their transport layer, benefiting from features like QUIC/HTTP3 support or connection migration.
Apache License 2.0
452 stars 34 forks source link

Requests are resolved through HTTP2 #21

Closed araujo-luis closed 1 year ago

araujo-luis commented 1 year ago

I'm trying to implement HTTP/3 with QUIC support in my Android app using OkHttp and the Cronet transport. However, all requests are being made under HTTP/2. I have used different devices with different versions. I've tried with Retrofit as well and same result.

The server I'm reaching out does support HTTP3 I've tested it on web and it works fine.

private val engine = CronetEngine.Builder(MainActivity.appContext).enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, 10 * 1024 * 1024)
    .build()

    private val callFactory = OkHttpClient.Builder()
        .addInterceptor(CronetInterceptor.newBuilder(engine).build())
    .build();

private fun getRequest(url: String): JSONObject? {
        val request: Request = Request.Builder()
            .url(url)
            .build()

        val response = callFactory.newCall(request).execute()
        return response.body?.string()?.let { JSONObject(it) }
    }

image

ag2s20150909 commented 1 year ago

https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/CronetEngine.Builder.html#addQuicHint(java.lang.String,%20int,%20int)

araujo-luis commented 1 year ago

https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/CronetEngine.Builder.html#addQuicHint(java.lang.String,%20int,%20int)

Yes, I tried that. I realized my OkHttp config was missing QUIC protocol, by default is not enabled. https://github.com/google/cronet-transport-for-okhttp/pull/23

ag2s20150909 commented 1 year ago

but OkHttp config has no effect on Cronet.

araujo-luis commented 1 year ago

but OkHttp config has no effect on Cronet.

It does.

  * QUIC is not natively supported by OkHttp, but provided to allow a theoretical interceptor that
  * provides support.

https://github.com/square/okhttp/blob/337b1b1b19a702916798096766b80e4b3700db01/okhttp/src/commonMain/kotlin/okhttp3/Protocol.kt#L77-L85

Danstahrg commented 1 year ago

The TL;DR of how the http2/3 negotiation works is covered here: https://github.com/GoogleChromeLabs/cronet-sample/blob/master/android/app/src/main/java/com/google/samples/cronet_sample/CronetApplication.java#L77. If you enable the on-disk cache this should only affect the very first few requests to a server, subsequent connections will respect the alt-svc signal and use QUIC.

As for protocols configuration in OkHttp (https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/-builder/protocols/), this library bypasses the config and setting it has no effect.

Yes, I tried that. I realized my OkHttp config was missing QUIC protocol, by default is not enabled.

Which Cronet version are you using? This suggests an old one, as the default was changed in mid-2020: https://crrev.com/c/2168553

araujo-luis commented 1 year ago

The TL;DR of how the http2/3 negotiation works is covered here: https://github.com/GoogleChromeLabs/cronet-sample/blob/master/android/app/src/main/java/com/google/samples/cronet_sample/CronetApplication.java#L77. If you enable the on-disk cache this should only affect the very first few requests to a server, subsequent connections will respect the alt-svc signal and use QUIC.

As for protocols configuration in OkHttp (https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/-builder/protocols/), this library bypasses the config and setting it has no effect.

Yes, I tried that. I realized my OkHttp config was missing QUIC protocol, by default is not enabled.

Which Cronet version are you using? This suggests an old one, as the default was changed in mid-2020: https://crrev.com/c/2168553

Thanks for your help!

    implementation 'com.google.net.cronet:cronet-okhttp:0.1.0'
    implementation 'com.google.android.gms:play-services-cronet:18.0.1'

Seems like you are right, I just removed the protocols I've defined on OkHttpBuilder, and requests are being resolved through QUIC. Not sure what configuration I had yesterday. My guess is that the first requests were resolved with HTTP2 as you pointed out (the one I was debugging).

                // Cronet tries to use both protocols and it's nondeterministic which
                // one will be used for the first few requests. As soon as Cronet is aware that
                // a server supports QUIC, it will always attempt to use it first