-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
Inject configured OkHttpClient to networking module using MainPackageConfig #14068
Conversation
} | ||
|
||
private OkHttpClient createOkHttpClient( | ||
OkHttpClientProvider okHttpClientProvider, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can add the @Nullable
annotation just like List<NetworkInterceptorCreator>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes good idea - makes the API clearer to users.
} | ||
|
||
/** | ||
* @param context the ReactContext of the application | ||
* @param defaultUserAgent the User-Agent header that will be set for all requests where the | ||
* caller does not provide one explicitly | ||
* @param client the {@link OkHttpClient} to be used for networking | ||
* @param okHttpClientProvider the {@link OkHttpClient} provider to be used for networking |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could update the {@link } to point to the OkHttpClientProvider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, probably you should just call it provider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with both. Maybe httpClientProvider
.
} | ||
|
||
/** | ||
* @param context the ReactContext of the application |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use the {@link}
annotation for the java docs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit @param context the {@link ReactApplicationContext} of the application
|
||
public Builder setFrescoConfig(ImagePipelineConfig frescoConfig) { | ||
mFrescoConfig = frescoConfig; | ||
return this; | ||
} | ||
|
||
/** | ||
* Ability to inject configured OkHttpClient provider to react-native networking subsystem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about the {@link} annotation. I also dont think that the sentence This will be very useful
is needed.
@@ -77,6 +78,7 @@ | |||
@Test | |||
public void testGetWithoutHeaders() throws Exception { | |||
OkHttpClient httpClient = mock(OkHttpClient.class); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit remote
@@ -87,8 +89,10 @@ public Object answer(InvocationOnMock invocation) throws Throwable { | |||
OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class); | |||
when(clientBuilder.build()).thenReturn(httpClient); | |||
when(httpClient.newBuilder()).thenReturn(clientBuilder); | |||
OkHttpClientProvider clientProvider = mock(OkHttpClientProvider.class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment than before you can just call it provider
@thotegowda I added some minor comments. By the way, I am not an official reviewer but I am going to do something similar to what you are trying to achieve. |
@@ -154,7 +154,7 @@ private static ImagePipelineConfig getDefaultConfig(ReactContext context) { | |||
HashSet<RequestListener> requestListeners = new HashSet<>(); | |||
requestListeners.add(new SystraceRequestListener()); | |||
|
|||
OkHttpClient client = OkHttpClientProvider.createClient(); | |||
OkHttpClient client = new DefaultOkHttpProvider().get(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If fetching images should not be affected by the HTTP provider from MainPackageConfig
we should document the MainPackageConfig
only affects the fetch
API.
It's probably easier, however, to just use the HTTP client configured in MainPackageConfig
also here (for fetching images) to avoid confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't looked in to the details of how Fresco is using this client. But I guess, Fresco might need its own customised client configuration.
For now, I will add a comment in MainPackageConfig
. Will take a look at this later. Would be great if someone with Fresco context can share some light.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK sounds good, someone else can do that separately and we can keep this pull request simpler.
On Android 4.1-4.4 (API level 16 to 19) TLS 1.1 and 1.2 are | ||
available but not enabled by default. The following method | ||
enables it. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a stylistic thing but I could you make this into a Javadoc please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the method should be private - it's not used anywhere outside this class. I see it was public and just moved - so it was wrong previously but now is a good opportunity to make it private.
specs.add(ConnectionSpec.CLEARTEXT); | ||
|
||
client.connectionSpecs(specs); | ||
} catch (Exception exc) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Please name this variable e
- another opportunity to fix existing code a bit.
|
||
client.connectionSpecs(specs); | ||
} catch (Exception exc) { | ||
FLog.e("OkHttpClientProvider", "Error while enabling TLS 1.2", exc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be Flog.e(ReactConstants.TAG, "Error while enabling TLS 1.2", e);
so it's easy to see all React Native related messages in logcat.
Again I realise this is just moved code but good opportunity for minor fixes.
FLog.e("OkHttpClientProvider", "Error while enabling TLS 1.2", exc); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Empty line not really needed.
|
||
/** | ||
* Helper class that provides the same OkHttpClient instance that will be used for all networking | ||
* requests. | ||
* Interface that provides the OkHttpClient instance, that will be used for all networking requests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nit: No need for comma before "that".
|
||
/** | ||
* Configuration for {@link MainReactPackage} | ||
*/ | ||
public class MainPackageConfig { | ||
|
||
private ImagePipelineConfig mFrescoConfig; | ||
|
||
private final OkHttpClientProvider mOkHttpClientProvider; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO mHttpClientProvider
would be as clear as it's shorter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be @Nullable
.
assertEquals(config.getOkHttpClientProvider().getClass(), DefaultOkHttpProvider.class); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks for adding this! 💯
Thanks for doing this! I get the motivation for doing this and think the PR makes a lot of sense. Left some quite minor comments and once you address them we can merge. |
@mkonicek @amilcar-andrade Incorporated your feedback points. Please check. |
|
||
/** | ||
* @param context the ReactContext of the application | ||
* @param httpClientProvider {@link OkHttpClientProvider} to provide {@link OkHttpClient} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit extra space httpClientProvider {
@thotegowda cool. I think it looks good. But again I cannot merge or approve your PR. Thanks for doing this it will help a lot of us. |
Thanks for addressing the comments! I don't have push access anymore but I just messaged contributors asking to merge this. |
@thotegowda you should probably squash your commits and rebase against master. |
@amilcar-andrade - Done squashing commits. |
Sorry to comment here, but is there any way to customize okhttpclient currently without this PR? Just checked that OkHttpClientProvider has mechanics for this (like replaceOkHttpClient), but it seems that this injection isn't used internally in networking module |
@Knight704 I had used replaceOkHttpClient before. But then one of the recent commit broke it. check commit and discussion here |
@thotegowda, thanks, got it. So, if I understood correctly, now there is no way to do that, sad 👎 |
Okay, I came up to the workaround for this problem for now:
|
@hramos Hi, what is the status for this PR? |
No news to share. It's on someone's queue internally, waiting for review. As it happens, merging this would require making additional changes to other apps in our internal code repository, which introduces a high level of friction that may keep this PR from getting handled any time soon. |
@hramos I see. So there is no good way to use Stetho which requires intercepting OkHttp Header |
I'm really surprised this PR hasn't been merged in yet. Here is a gist of it. Hope it's helpful. Also @hramos, surely this is a relatively easy fix with almost no chance of breaking the existing tests/logic. Thoughts? |
@thotegowda I tried to find reviewers for this pull request and wanted to ping them to take another look. However, based on the blame information for the files in this pull request I couldn't find any reviewers. This sometimes happens when the files in the pull request are new or don't exist on master anymore. Is this pull request still relevant? If yes could you please rebase? In case you know who has context on this code feel free to mention them in a comment (one person is fine). Thanks for reading and hope you will continue contributing to the project. |
Any updates on this PR? I'd love to help if I can, but I'm not even sure what is this waiting for. |
Any updates on this @hramos ? If FB will not pull this in, can someone at least give an informal ship-it that confirms that the final code that will be merged will look like the current state of the PR. That way companies with brown-field apps that already compile RN in-house can manually make the same change and patch existing versions of RN between 0.43 and 0.52.
Also how long is this internal queue? It's been 4.5 months since that comment :S :( |
Summary: Prior to 0a71f48, users could customise the OkHttp client used by React Native on Android by calling replaceOkHttpClient in OkHttpClientProvider. This functionality has a variety of legitimate applications from changing connection timeouts or pool size to Stetho integration. The challenge is to add back support for replacing the client without causing a breaking change or reintroducing the problems olegbl sought to address in his original commit. Introducing a client factory archives these aims, it adds a new, backwards compatible interface and is called each time a client is requested rather than re-using the same instance (unless you explicitly want this behaviour, in which case you could replicate it using a static class property inside your custom factory). A number of PRs have been opened to add this functionality: #14675, #14068. I don't have a lot of Java experience so I'm open to better/more idiomatic ways to achieve this :) Create React Native application and set a custom factory in the constructor, e.g. `OkHttpClientProvider.setOkHttpClientFactory(new CustomNetworkModule());` Where a custom factory would look like: ``` class CustomNetworkModule implements OkHttpClientFactory { public OkHttpClient createNewNetworkModuleClient() { return new OkHttpClient.Builder().build(); } } ``` Remove the existing replace client method to prevent accident use and alert existing users that its functionality has changed: #16972 [Android] [Minor] [Networking] - | Provide interface for customising the OkHttp client used by React Native | Closes #17237 Differential Revision: D6837734 Pulled By: hramos fbshipit-source-id: 81e63df7716e6f9039ea12e99233f6336c6dd7ef
Any updates? Edit: If #17237 will be the preferred solution, we can actually close this now. I am ok with either pull-request, and the other one looks to be less invasive to me. |
Summary: Prior to 0a71f48, users could customise the OkHttp client used by React Native on Android by calling replaceOkHttpClient in OkHttpClientProvider. This functionality has a variety of legitimate applications from changing connection timeouts or pool size to Stetho integration. The challenge is to add back support for replacing the client without causing a breaking change or reintroducing the problems olegbl sought to address in his original commit. Introducing a client factory archives these aims, it adds a new, backwards compatible interface and is called each time a client is requested rather than re-using the same instance (unless you explicitly want this behaviour, in which case you could replicate it using a static class property inside your custom factory). A number of PRs have been opened to add this functionality: facebook#14675, facebook#14068. I don't have a lot of Java experience so I'm open to better/more idiomatic ways to achieve this :) Create React Native application and set a custom factory in the constructor, e.g. `OkHttpClientProvider.setOkHttpClientFactory(new CustomNetworkModule());` Where a custom factory would look like: ``` class CustomNetworkModule implements OkHttpClientFactory { public OkHttpClient createNewNetworkModuleClient() { return new OkHttpClient.Builder().build(); } } ``` Remove the existing replace client method to prevent accident use and alert existing users that its functionality has changed: facebook#16972 [Android] [Minor] [Networking] - | Provide interface for customising the OkHttp client used by React Native | Closes facebook#17237 Differential Revision: D6837734 Pulled By: hramos fbshipit-source-id: 81e63df7716e6f9039ea12e99233f6336c6dd7ef
Summary: Prior to 0a71f48, users could customise the OkHttp client used by React Native on Android by calling replaceOkHttpClient in OkHttpClientProvider. This functionality has a variety of legitimate applications from changing connection timeouts or pool size to Stetho integration. The challenge is to add back support for replacing the client without causing a breaking change or reintroducing the problems olegbl sought to address in his original commit. Introducing a client factory archives these aims, it adds a new, backwards compatible interface and is called each time a client is requested rather than re-using the same instance (unless you explicitly want this behaviour, in which case you could replicate it using a static class property inside your custom factory). A number of PRs have been opened to add this functionality: facebook#14675, facebook#14068. I don't have a lot of Java experience so I'm open to better/more idiomatic ways to achieve this :) Create React Native application and set a custom factory in the constructor, e.g. `OkHttpClientProvider.setOkHttpClientFactory(new CustomNetworkModule());` Where a custom factory would look like: ``` class CustomNetworkModule implements OkHttpClientFactory { public OkHttpClient createNewNetworkModuleClient() { return new OkHttpClient.Builder().build(); } } ``` Remove the existing replace client method to prevent accident use and alert existing users that its functionality has changed: facebook#16972 [Android] [Minor] [Networking] - | Provide interface for customising the OkHttp client used by React Native | Closes facebook#17237 Differential Revision: D6837734 Pulled By: hramos fbshipit-source-id: 81e63df7716e6f9039ea12e99233f6336c6dd7ef
Summary: This method was originally intended to replace the OkHttp client used by React Native's networking library. However it has effectively been a noop since 0a71f48#diff-177100ae5a977e4060b54cc2b34c79a7, when the Networking library was modified to create a new client rather than use the reference provided by OkHttpClientProvider. Leaving this code in place is dangerous. There is no indication to users upgrading React Native that the method is no longer replacing the OkHttpClient used by the Networking library. Any functionality reliant on overriding the client will silently break. This caused us some problems internally. There's been a PR out for some time that seeks to reintroduce this functionality: #14068 I've also put up a new PR that adds an interface for replacing the client without introducing breaking changes: #17237 Do our unit tests continue to pass? Should be safe as this method is not used anywhere inside React Native. [ANDROID] [BREAKING] [Networking] - removed replaceOkHttpClient method in OkHttpClientProvider. Pull Request resolved: #16972 Differential Revision: D13838805 Pulled By: cpojer fbshipit-source-id: 43606d1d141afb9b5dda4dd64e5ac5448771b45c
Summary: This method was originally intended to replace the OkHttp client used by React Native's networking library. However it has effectively been a noop since facebook@0a71f48#diff-177100ae5a977e4060b54cc2b34c79a7, when the Networking library was modified to create a new client rather than use the reference provided by OkHttpClientProvider. Leaving this code in place is dangerous. There is no indication to users upgrading React Native that the method is no longer replacing the OkHttpClient used by the Networking library. Any functionality reliant on overriding the client will silently break. This caused us some problems internally. There's been a PR out for some time that seeks to reintroduce this functionality: facebook#14068 I've also put up a new PR that adds an interface for replacing the client without introducing breaking changes: facebook#17237 Do our unit tests continue to pass? Should be safe as this method is not used anywhere inside React Native. [ANDROID] [BREAKING] [Networking] - removed replaceOkHttpClient method in OkHttpClientProvider. Pull Request resolved: facebook#16972 Differential Revision: D13838805 Pulled By: cpojer fbshipit-source-id: 43606d1d141afb9b5dda4dd64e5ac5448771b45c
Motivation
The main purpose of this PR is to enable brownfield applications to inject existing
OkHttpClient
instance to react-native networking sub system. Most native applications would have theirOkHttpClient
instance configured with headers, interceptors, logging, fallback handling, error handling, etc. It doesn't make much sense to duplicate all of this to usefetch
in javascript. Currently the only way you could use existingOkHttpClient
is by custom-bridge to native, but this will stops app from usingfetch
interface in JS.With this commit, App can pass
OkHttpClient
instance to networking module usingMainPackageConfig
, while creatingMainReactPackage
.Test Plan
Unit tests.