Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP/3 support #907

Closed
mariotaku opened this issue Jun 10, 2014 · 47 comments
Closed

HTTP/3 support #907

mariotaku opened this issue Jun 10, 2014 · 47 comments
Labels
enhancement Feature not a bug
Milestone

Comments

@mariotaku
Copy link

does okhttp have any plan on QUIC support?

@swankjesse
Copy link
Member

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

@mariotaku
Copy link
Author

thanks :D

@swankjesse swankjesse added this to the Icebox milestone Jun 12, 2014
@brunobowden
Copy link

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.

@swankjesse
Copy link
Member

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

@bgcr
Copy link

bgcr commented Jun 5, 2015

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.

@swankjesse
Copy link
Member

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

@swankjesse
Copy link
Member

@duanbo1983
Copy link

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

@JY482
Copy link

JY482 commented Aug 20, 2018

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?

@yschimke
Copy link
Collaborator

yschimke commented Aug 20, 2018

@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.

@derekargueta
Copy link

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

@jkozlowski
Copy link

jkozlowski commented Dec 28, 2018

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.

@yschimke
Copy link
Collaborator

@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.

@jkozlowski
Copy link

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?

@yschimke
Copy link
Collaborator

Discussed here #3683

@jkozlowski
Copy link

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?

@yschimke
Copy link
Collaborator

yschimke commented Dec 28, 2018

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.

@swankjesse
Copy link
Member

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.

@jkozlowski
Copy link

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

That's what I was thinking too.

@jkozlowski
Copy link

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

@swankjesse
Copy link
Member

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

@jkozlowski
Copy link

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)

@siyengar
Copy link

@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.

@jkozlowski
Copy link

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
Copy link

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.

@siyengar
Copy link

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.

@yschimke
Copy link
Collaborator

Uber blog post discussing their Quic work behind the OkHttpClient facade

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

@yschimke
Copy link
Collaborator

yschimke commented Jun 9, 2019

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

@swankjesse swankjesse changed the title QUIC support HTTP/3 support Oct 26, 2019
@yschimke
Copy link
Collaborator

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

@swankjesse
Copy link
Member

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!

@yschimke
Copy link
Collaborator

I think particularly with HTTP/2 being so prevalent, sending more requests just allows the front end webserver at BigTechCo to start producing the images, and then client gets results back as fast as a single socket can transfer them. Your requests will be load balanced internally on the server anyway, so it's mostly IO and head of line blocking for them.

So +1 to bumping now, this sort of thing is worth revising as the middle of the bell curve becomes more capable Android phones etc.

For desktops - number of connections (sockets?) http://www.browserscope.org/?category=network&v=top

How about 10?

@FireMasterK
Copy link

Any progress on this? It's almost been two years since the last update 😅

@swankjesse
Copy link
Member

swankjesse commented Feb 21, 2021

I could write a basic implementation of HTTP/1 in about a week.

I could write a basic implementation of HTTP/2 in about a month.

I fear HTTP/3 is larger still; maybe 6 months of work? Not having TCP as a baseline means there’s a lot more to do in timeouts, retransmissions, recovering from out-of-order delivery, and other things we’ve been able to take advantage of to date. The upside is also less clear! It might be slower than HTTP/2, especially early on as integrations with UDP and TLSv1.3 are optimized.

What’s your use case? It may be worth trying to hook up cronet or mvfst as a backend to OkHttp to see if you observe benefits in practice.

@yschimke
Copy link
Collaborator

yschimke commented Feb 21, 2021

+1 Starting with https://github.com/akshetpandey/react-native-cronet/tree/master/android/src/main/java/com/akshetpandey/rncronet and working out how to get as close to 1:1 for events and show the benefits could have huge impact. This isn't blocked at the moment.

http://envoy-mobile.github.io/ also looks really promising long term, but at a guess it's probably 6+ months away from being ready for mainstream use. If you had a team working on your network stack and builds, you could get it working nicely now like the cronet solution above.

envoyproxy/envoy-mobile#637

I found it hard with build issues and specific NDKs required, I couldn't use either aar files I built myself or from their snapshot repo on my test devices (Android 11).

https://oss.sonatype.org/index.html#view-repositories;releases~browsestorage~/io/envoyproxy/envoymobile/envoy/0.3.1.11112020/envoy-0.3.1.11112020.aar

@FireMasterK
Copy link

My use case here is a Java 11 jvm application, afaict cronet doesn't support the jvm, but rather only android apps. I'm not sure about mvfst, from what I can tell, it needs jni bindings to use

Let me know what would suit a jvm

@ag2s20150909
Copy link

Any progress on this?

@yschimke
Copy link
Collaborator

@ag2s20150909 If you want this, your best best is to use one of the application interceptor approaches above with Cronet or if you are happy with bleeding edge, envoy mobile. This isn't something that anyone is currently publicly working on implementing directly in OkHttp.

@yangwuan55
Copy link

I want to see okquic born,any plan?

@anjalsaneen
Copy link

anjalsaneen commented Dec 6, 2021

The IETF published QUIC as RFC 9000 on May 21, supported by RFC 9001, RFC 9002, and RFC 8999

This is big. Now even more websites, applications, and networking libraries will start offering QUIC for general use. In the very near future, new protocols like QUIC will be essential to unlocking innovative internet applications. According to W3Tech 23% of websites support support. It was 4% at the start of 2021.

@yschimke
Copy link
Collaborator

yschimke commented Dec 7, 2021

The only plan is there is no plan. OkHttp Call.Factory and Interceptor both give you a place to swap out a different underlying connection. There is noone that I know of offering to write a Kotlin implementation of Quic, so reusing EnvoyMobile is probably the path to success.

As a starting point this is an older exploration. https://github.com/square/okhttp/pull/6800/files

@GEverding
Copy link

I've been using this library for cronet to replace the underlying network library of okhttp and I've had fewer weird bugs and get support for http/3. https://github.com/VKCOM/KNet

Uses the same concept that Snap and Uber user to combine Retrofit and okhttp.

@yschimke
Copy link
Collaborator

yschimke commented May 7, 2022

Another option now https://github.com/google/cronet-transport-for-okhttp/blob/master/README.md

@yschimke
Copy link
Collaborator

Closing in favour of the existing Cronet transport.

@matejdro
Copy link

matejdro commented May 25, 2023

Does that mean that OkHttp will get stuck at HTTP 2 and that we should eventually move to Cronet completely?

As far as I can see, Cronet is completely separate HTTP library and above options just bypass all of the OkHttp networking code, disabling most of its features (caching, retries, authentication, network interceptors). They only use OkHttp as a frontend for compatibility reasons (to allow existing Retrofit and interceptor code to work, I guess).

Plus, Cronet seems to only be available on Android, it's not a pure JVM library.

@yschimke
Copy link
Collaborator

note: Very personal take

If HTTP/3 is critical for you, then you should assume you'll be using an implementation based on something like Cronet or EnvoyMobile under the hood.

They only use OkHttp as a frontend for compatibility reasons

Correct, also why OkHttp 5 KMP story is as an API only. To allow libraries that use OkHttp on JVM, to have a way to bridge to other implementations. But not something the OkHttp project will implement.

Some of the design of OkHttp internals may assume HTTP/2, Sockets, Sync I/O, TLS anyway, if we had to break some of the public APIs to support HTTP/3 then it would diminish the value of that compatibility also.

There are a couple of major reasons why HTTP/3 in OkHttp is unlikely (echoing Jesse's comments in #907 (comment))

  • It would be a huge amount of work that isn't funded, the implementations like Cronet or EnvoyMobile have taken a substantial investment to build.
  • It's not clear that a Kotlin implementation of HTTP/3 would be able to compete with the performance of these native implementations that are highly optimised.

Outside a nicer API, a big part of the adoption of OkHttp on Android is likely as the optimised HTTP/2 stack missing on Android. Android U introduces android.net.http.HttpEngine, it seems like an ambitious project to attempt to implement a better more performant HTTP/3 engine that that.

@matejdro
Copy link

I don't really consider it critical, but it's a something that it's very nice to have (as servers start supporting it, users would get better performance for practically free).

Thanks for the explanation.

@limuyang2
Copy link

I've been using this library for cronet to replace the underlying network library of okhttp and I've had fewer weird bugs and get support for http/3. https://github.com/VKCOM/KNet我一直在 cronet 中使用这个库来替换 okhttp 的底层网络库,并且我遇到了更少的奇怪错误并获得了对 http/3 的支持。 https://github.com/VKCOM/KNet

Uses the same concept that Snap and Uber user to combine Retrofit and okhttp.使用与 Snap 和 Uber 用户相同的概念来结合 Retrofit 和 okhttp。

You can try this library:
okcronet
msnet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature not a bug
Projects
None yet
Development

No branches or pull requests