okhttp icon indicating copy to clipboard operation
okhttp copied to clipboard

HTTP/3 support

Open mariotaku opened this issue 10 years ago • 42 comments

does okhttp have any plan on QUIC support?

mariotaku avatar Jun 10 '14 01:06 mariotaku

Yup. Though it isn't a high priority yet!

swankjesse avatar Jun 10 '14 01:06 swankjesse

thanks :D

mariotaku avatar Jun 10 '14 01:06 mariotaku

Any update on QUIC support in okhttp? Google just announced that half of Chrome's traffic to Google servers now uses this. The benefits to mobile traffic is terms of reduced round trips is even more profound.

brunobowden avatar Apr 20 '15 19:04 brunobowden

Yup! We're still waiting on some sort of stable QUIC spec.

swankjesse avatar Apr 20 '15 19:04 swankjesse

I'm planning to implement the QUIC support in okhttp source code. Does anyone could help me plotting the main stack responsible for transport connection? I would appreciate any kind of help. Thanks in advance.

bgcr avatar Jun 05 '15 20:06 bgcr

@bgcr please do your work in a fork! We don't have time or interest to have QUIC in trunk at this time.

swankjesse avatar Jun 05 '15 20:06 swankjesse

https://www.ietf.org/proceedings/96/slides/slides-96-quic-5.pdf

swankjesse avatar Jul 20 '16 13:07 swankjesse

@bgcr how's your effort in QUIC support? BTW, I still haven't seen a stable QUIC spec.

duanbo1983 avatar Nov 28 '16 22:11 duanbo1983

I can see "QUIC is not natively supported by OkHttp, but provided to allow a theoretical interceptor that provides support." in OkHttp 3.11.0 API how can I use interceptor?

JY482 avatar Aug 20 '18 06:08 JY482

@JY482 you would need to implement that interceptor yourself. I know from discussions of two companies discussing implementing it, but it unclear if/when they will publicly release their implementations.

yschimke avatar Aug 20 '18 13:08 yschimke

Hey everyone, just checking if there's been any movement here?

derekargueta avatar Oct 13 '18 20:10 derekargueta

I would interested in the maintainers thoughts on this issue, I had a quick look around and there are a few things that could be blocking this:

  • Quic runs on UDP. Currently, the notion of a Socket (which UDP does not use) is pretty pervasive across the codebase.
  • Most importantly RealCall/RealConnection/StreamAllocation/ConnectionPool are pretty coupled to each other, and then to http1/http2 parts and then to Socket interface.
  • All the important interceptors (CallServerInterceptor, ConnectInterceptor) all cast Chain->RealInterceptorChain. This might not be so important though.

From a quick look it feels like extracting a notion of a Transport and making it so that RealCall/RealConnection/StreamAllocation/CollectionPool don't think so much in terms of sockets but simply streams, or even better just HttpCodec, as that is ultimately what the higher interfaces require.

I'll keep digging, but my preliminary thoughts are that things will not slot in without a few adjustments, but please correct my thinking if I got something wrong. To validate my work so far, I have managed to wire up rust implementation of quic (https://github.com/djc/quinn) to https://github.com/undertow-io/undertow successfully (reusing their http1 handlers), will hopefully publish the code at some point.

jkozlowski avatar Dec 28 '18 07:12 jkozlowski

@jkozlowski I think in OkHttp 3, it would likely be most feasible as the last application interceptor i.e. before the BridgeInterceptor when it has already made connections etc. It would be ugly but allow you to use an existing app with a feature switch to test a wholesale replacement of connection management.

Not sure of specific plans here, it's possible that a couple of large companies have this sort of setup running but not in a form they would open source. I heard some thoughts but nothing concrete, so I don't know.

yschimke avatar Dec 28 '18 08:12 yschimke

Yeah, that would be a shame, since the connection management has some nice features. Your suggestion would also be probably not so nice since RealCall doesn't really let you swap those low level interceptors out, it would still need to be a fork. I guess that's why you're saying nobody has it in a form they could open-source (i.e. they forked).

I can see that you've added the Protocol#Quic, was that to enable this sort of workaround?

jkozlowski avatar Dec 28 '18 08:12 jkozlowski

Discussed here https://github.com/square/okhttp/issues/3683

yschimke avatar Dec 28 '18 11:12 yschimke

Thanks! I think the refactoring I described could work out, I might try to hack something together. I wonder if the maintainers would be open to a contribution like that?

jkozlowski avatar Dec 28 '18 12:12 jkozlowski

If it made non-trivial changes to public API then it would almost certainly be a OkHttp 4 feature. But a working PR would be the starting point either way. You should probably get more feedback from @swankjesse before spending too much time on it. He will know more about future plans.

yschimke avatar Dec 28 '18 13:12 yschimke

We make no API compatibility promises for our internal packages. So those changes aren’t precluded.

In Connection we may need to hack a few things to keep a consistent API, but I don't expect too much grief there either.

swankjesse avatar Dec 28 '18 14:12 swankjesse

We make no API compatibility promises for our internal packages. So those changes aren’t precluded.

That's what I was thinking too.

jkozlowski avatar Dec 28 '18 19:12 jkozlowski

Address holds the SocketFactory that is used in the lower layers, and that's in the public API.

jkozlowski avatar Dec 29 '18 06:12 jkozlowski

That's fine. The address needs the SocketFactory for TCP connections.

swankjesse avatar Dec 29 '18 16:12 swankjesse

Yeah, but Quic uses UDP, so no SocketFactories :) maybe the way to do this is indeed just let us have something that will make a decision on what set of interceptors to install in RealCall#getResponseWithInterceptorChain based on some criteria.

Question is: how do you switch protocols? Request doesn't have a protocol attached to it, I don't know if there is a way of encoding the protocol in the URL. But that is basically where it belongs, since with Http3 vs Http2 the is no upgrade ability and you're using a different transport (UDP vs TCP)

jkozlowski avatar Dec 29 '18 18:12 jkozlowski

@jkozlowski there is no currently defined separate protocol schema for H3 in the URL. H3 will continue to use the same urls as resources available over H2. The way to switch between H3 and H2 is to use Alt-SVC as an indicator for the transport. In addition there must be support for fallback from H3 to H2 as well since UDP might be blocked on networks. At FB we've done some work on this in mvfst, our implementation of QUIC an I presented some of that work including racing schemes at ACM conext https://conferences2.sigcomm.org/co-next/2018/slides/epiq-keynote.pdf. Hopefully this helps in the refactor.

siyengar avatar Dec 29 '18 18:12 siyengar

Ah yes, now I remember reading the RFC. Cool, the refactoring will basically need to cleanup a bunch of code that deals directly with Sockets and then we need a way to switch protocols if alt-svc advertised something new.

jkozlowski avatar Dec 29 '18 19:12 jkozlowski

I see you went with http1.1 over quic, that's what I attempted as well server side. Is that still the case? I was hoping to use this for internal backend services, so firewalls etc. are under my control, so racing and recovery is not so important. Nevertheless, your slides describe interesting approaches.

jkozlowski avatar Dec 29 '18 20:12 jkozlowski

We've already moved our internal deployments of QUIC to HTTP/3. For external traffic we used HTTP1.1 initially because the spec was very much in flux. It is now in much better shape and we're moving to HTTP/3 early next year.

siyengar avatar Dec 29 '18 23:12 siyengar

Uber blog post discussing their Quic work behind the OkHttpClient facade

https://eng.uber.com/employing-quic-protocol/

yschimke avatar May 28 '19 21:05 yschimke

I'm implementing a QuicInterceptor based on cronet just for testing. Currently it is ignoring headers and body, just throwing away the response content after consuming and using the status code. This isn't intended to be production code, I just want it to understand networks changes on Android.

But mentioning in case anyone wants to build a public QuicInterceptor off this once it's actually working. Currently it just tells you that https://facebook.com/robots.txt returns 200 and https://facebook.com/robots.txtXXX returns 404.

https://github.com/yschimke/OkHttpAndroidApp/blob/master/android/app/src/main/java/ee/schimke/okhttp/android/quic/QuicInterceptor.kt https://github.com/yschimke/OkHttpAndroidApp/blob/master/android/app/src/main/java/ee/schimke/okhttp/android/quic/QuicCallback.kt

yschimke avatar Jun 09 '19 18:06 yschimke

A probably more viable starting point for the interceptor https://github.com/akshetpandey/react-native-cronet/tree/master/android/src/main/java/com/akshetpandey/rncronet

yschimke avatar Nov 15 '19 16:11 yschimke

The side-by-side comparison on that site is intense. Without digging too deep I think it’s trying to tell us that maxRequestsPerHost=5 in Dispatcher is a bad default for apps that want to kick off 30 requests immediately!

swankjesse avatar Nov 17 '19 01:11 swankjesse