square / okhttp

Square’s meticulous HTTP client for the JVM, Android, and GraalVM.
https://square.github.io/okhttp/
Apache License 2.0
45.48k stars 9.12k forks source link

HTTP/3 support #907

Closed mariotaku closed 1 year ago

mariotaku commented 10 years ago

does okhttp have any plan on QUIC support?

swankjesse commented 10 years ago

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

mariotaku commented 10 years ago

thanks :D

brunobowden commented 9 years ago

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 commented 9 years ago

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

bgcr commented 9 years ago

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 commented 9 years ago

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

swankjesse commented 7 years ago

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

duanbo1983 commented 7 years ago

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

JY482 commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

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

jkozlowski commented 5 years ago

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:

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 commented 5 years ago

@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 commented 5 years ago

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 commented 5 years ago

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

jkozlowski commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

That's what I was thinking too.

jkozlowski commented 5 years ago

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

swankjesse commented 5 years ago

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

jkozlowski commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

Uber blog post discussing their Quic work behind the OkHttpClient facade

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

yschimke commented 5 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 3 years ago

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

swankjesse commented 3 years ago

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 commented 3 years ago

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

https://github.com/envoyproxy/envoy-mobile/issues/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 commented 3 years ago

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 commented 2 years ago

Any progress on this?

yschimke commented 2 years ago

@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 commented 2 years ago

I want to see okquic born,any plan?

anjalsaneen commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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

yschimke commented 1 year ago

Closing in favour of the existing Cronet transport.

matejdro commented 1 year ago

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 commented 1 year ago

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 https://github.com/square/okhttp/issues/907#issuecomment-782903877)

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 commented 1 year ago

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 commented 3 months ago

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