okhttp
okhttp copied to clipboard
HTTP/3 support
Yup. Though it isn't a high priority yet!
thanks :D
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.
Yup! We're still waiting on some sort of stable QUIC spec.
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 please do your work in a fork! We don't have time or interest to have QUIC in trunk at this time.
https://www.ietf.org/proceedings/96/slides/slides-96-quic-5.pdf
@bgcr how's your effort in QUIC support? BTW, I still haven't seen a stable QUIC spec.
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 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.
Hey everyone, just checking if there's been any movement here?
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 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.
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?
Discussed here https://github.com/square/okhttp/issues/3683
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?
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.
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.
We make no API compatibility promises for our internal packages. So those changes aren’t precluded.
That's what I was thinking too.
Address holds the SocketFactory that is used in the lower layers, and that's in the public API.
That's fine. The address needs the SocketFactory for TCP connections.
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 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.
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.
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.
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.
Uber blog post discussing their Quic work behind the OkHttpClient facade
https://eng.uber.com/employing-quic-protocol/
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
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
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!