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

Upgrade to okhttp3 #6119

Open
tao1 opened this issue Sep 3, 2019 · 16 comments
Open

Upgrade to okhttp3 #6119

tao1 opened this issue Sep 3, 2019 · 16 comments
Milestone

Comments

@tao1
Copy link

tao1 commented Sep 3, 2019

Please answer these questions before submitting your issue.

What version of gRPC are you using?

1.23

What did you expect to see?

okhttp3 is more than 3 years old now (released in 2016-01-13). Please upgrade grpc-okhttp to use okhttp3.
Indeed a lot of android apps now use okhttp3 to make http requests. But if an android app also uses grpc, it must still embed okhttp 2.5.0 library.

Kind regards,

Laurent

@ran-su
Copy link
Member

ran-su commented Sep 4, 2019

Currently, we do not have a plan for that.

@gildor
Copy link

gildor commented Sep 8, 2019

@ran-su Are there any particular reason for this? It's not a problem if you use grpc in your app, but actually most of the applications just have this dependency because of Firebase, it's not only polluting autocomplete but also adds unnecessary code to the classpath and increase the size of the app, which even more important for SDKs. Maybe make sense to introduce a new artifact grpc-okhttp3 so it would be possible to select more appropriate version of http library

One more possible advantage would be if we could share Okhttp client between grpc and our own code, so also can share Dispatcher and underlying thread pool

@ran-su
Copy link
Member

ran-su commented Sep 9, 2019

The okhttp need to be modified to suit our needs. We did that for okhttp2.5. Currently, we do not have plan for upgrade to okhttp3. I will bring your requests to the team meetings.

@ejona86
Copy link
Member

ejona86 commented Sep 10, 2019

Our usage of okhttp 2 adds negligibly to the size of the app after proguard. The Android helloworld example retains 67 methods from okhttp. This is because grpc has a fork/reimplementation of the HTTP/2 code, so very little of the dependency is used. In some ways we use Okio more than OkHttp.

The few methods retained are for HTTP CONNECT proxy support:

import com.squareup.okhttp.Credentials;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.Request;

Those could be migrated to okhttp 3, but at that point grpc would technically depend on both okhttp 2 and okhttp 3. However, Proguard could strip all of okhttp 2.

The OkHttpChannelBuilder API allows you to specify a com.squareup.okhttp.ConnectionSpec , which is part of the OkHttp 2 API. If we support OkHttp 3, we'd probably add another method to also support the OkHttp 3 equivalent. This is because we don't use either directly; we end up copying the details to an internal format. If you don't use the method, then Proguard strips the usages.

One more possible advantage would be if we could share Okhttp client between grpc and our own code

That has never been possible, even with okhttp 2.

Maybe make sense to introduce a new artifact grpc-okhttp3 so it would be possible to select more appropriate version of http library

No, that is quite an undertaking to make a fork and maintain both.

@malachid
Copy link

The security implications of using a really old outdated version without the bugfixes and security patches is the biggest downside to using the io.grpc version for me. Looking at the release notes for OkHttp 4 and OkHttp 3, I am surprised that anyone would be willing to still use okhttp 2.7.5 in production. Especially when we already have OkHttp 3 or 4 in our apps. This issue has come up over and over (#1628 #2549 #2999 #5103 #6119 etc).

It seems like the best option would be to have a proper dependency on an updated version rather than trying to get everyone to use an out-of-date copy. If it doesn't have some support io.grpc needs; why is a PR not being passed onto OkHttp?

@ejona86
Copy link
Member

ejona86 commented Oct 14, 2019

The security implications of using a really old outdated version

Except there aren't many security implications. We are maintaining the "internal" code from OkHttp, but the OkHttp code that we are using is providing some primitives. We have our own full implementation of HTTP/2 on top and manage our own TLS, etc.

As I already mentioned, ProGuard will strip out most of the com.squareup.okhttp namespace.

It seems like the best option would be to have a proper dependency on an updated version rather than trying to get everyone to use an out-of-date copy.

The problem is it is a lot of work for little gain. I do think it should happen, but we can't find enough technical reason it should happen soon, above other work.

Part of the problem is that the "OkHttp" name for the transport is a bit of a misnomer. We are using OkHttp, but it isn't a "normal" usage by any means; most people don't realize how little of OkHttp we are using.

(It would be nice to use OkHttp more directly. But there are some fundamental API differences that have strong impact to overhead, like blocking vs async API.)

@Kernald
Copy link

Kernald commented Mar 22, 2021

The APK size isn't the only issue - this dependency on OkHttp 2 also pulls a really old version of Okio (1.x vs 2.x), which in turns causes issues with OkHttp3 - see square/okhttp#5378 for example. Overriding the dependency to use Okio 2.x fixes the issue, except that grpc-java then doesn't build anymore (I have no idea if there are more errors, but

return buffer.readByte() & 0x000000FF;
throws an exception in Okio 2, which isn't handled here).

This is becoming a real problem, not limited to the APK size or security concerns.

@ejona86
Copy link
Member

ejona86 commented Mar 22, 2021

@Kernald, that seems to be a different issue than this one. Please open a separate issue for tracking Okio compatibility issues.

@Kernald
Copy link

Kernald commented Mar 22, 2021

@ejona86 Done in #8004 - it's essentially similar I suspect, as OkHttp3 4.x depends on Okio 2.x (I stumbled on this by trying to depend on OkHttp3, not Okio directly).

@tkaitchuck
Copy link

@ejona86 Is this blocking #7431 ?

@ejona86
Copy link
Member

ejona86 commented Aug 17, 2021

@tkaitchuck, not as much as it may seem. It only impacts the ability to tell gRPC to use TLS v1.3 via a ConnectionSpec on the builder.

@anuraaga
Copy link
Contributor

anuraaga commented Sep 29, 2021

@ejona86 We package gRPC into a javaagent so care about binary size, but currently don't use proguard. We don't expose the knobs that rely on the okhttp types to our end users. I'm curious what you think about excluding the dependency, as I tried open-telemetry/opentelemetry-java#3678 This thread makes me believe that okhttp types won't be used on the hot path and this approach should basically be OK and would be called out in release notes otherwise. Excluding it is hacky, so I don't think it's a great approach or deserves endorsement - but would appreciate hearing if there are any current, obvious pitfalls or in-progress plans that would cause pitfalls.

Also curious if there is any appetite for deprecating the existing methods and add ones that accept a gRPC-defined type. That way the non-deprecated API would have no public surface exposing okhttp.

@ejona86
Copy link
Member

ejona86 commented Sep 29, 2021

We package gRPC into a javaagent so care about binary size, but currently don't use proguard.

@anuraaga, which means to me you don't care about binary size very much. Minification tools can dramatically reduce binary size. If you strongly cared, it'd seem you'd be using one.

I'm curious what you think about excluding the dependency

You can't currently safely exclude the okhttp dependency because we do use small parts of their API in our implementation. For example:

import com.squareup.okhttp.Credentials;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.internal.http.StatusLine;

Those specific usages are for client-side proxy usage, so excluding okhttp on your machine may seem to work, but it may break on another machine.

I'm actually going to be trying to "clean" some of those up in Q4 so that grpc-okhttp could become an optional dependency. At that point we could add okhttp3 as another optional dependency and put this stuff behind us. Users that use methods with okhttp types would then need to depend on the version of okhttp they wanted.

@anuraaga
Copy link
Contributor

If you strongly cared, it'd seem you'd be using one.

I'd say the world is too nuanced for such generalizations in OSS :P Proguard being mostly automatic in Android builds but not simple outside of that doesn't preclude keeping size down by reducing actual dependent artifacts.

Thanks for the pointers and the tip on potential cleanup in Q4, that'll be quite nice.

@valeriyo
Copy link

valeriyo commented Jul 29, 2022

most people don't realize how little of OkHttp we are using

Sounds fishy. If that's the case, just copy the "little" stuff that you're using and get rid of the dependency.

@ejona86
Copy link
Member

ejona86 commented Aug 1, 2022

Sounds fishy. If that's the case, just copy the "little" stuff that you're using and get rid of the dependency.

It is on the API surface and, as I said, there was no technical reason it should be a priority. However, since #8971 (v1.46.0) we don't depend on okhttp 2; you depend on okhttp 2 yourself if you need to use the API that uses okhttp 2.

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

No branches or pull requests

10 participants