Skip to content

WebSocketModule uses OkHttpClientProvider#55885

Closed
cortinico wants to merge 3 commits intofacebook:mainfrom
cortinico:export-D95059116
Closed

WebSocketModule uses OkHttpClientProvider#55885
cortinico wants to merge 3 commits intofacebook:mainfrom
cortinico:export-D95059116

Conversation

@cortinico
Copy link
Copy Markdown
Contributor

Summary:
Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Differential Revision: D95059116

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 3, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented Mar 3, 2026

@cortinico has exported this pull request. If you are a Meta employee, you can view the originating Diff in D95059116.

cortinico added a commit to cortinico/react-native that referenced this pull request Mar 4, 2026
Summary:

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
cortinico added a commit to cortinico/react-native that referenced this pull request Mar 4, 2026
Summary:

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
cortinico added a commit to cortinico/react-native that referenced this pull request Mar 4, 2026
Summary:
Pull Request resolved: facebook#55885

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
@cortinico cortinico force-pushed the export-D95059116 branch 2 times, most recently from 47911aa to 4c85df7 Compare March 4, 2026 10:34
cortinico added a commit to cortinico/react-native that referenced this pull request Mar 4, 2026
Summary:

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
cortinico added a commit to cortinico/react-native that referenced this pull request Mar 4, 2026
Summary:
Pull Request resolved: facebook#55885

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
cortinico added a commit to cortinico/react-native that referenced this pull request Mar 4, 2026
Summary:

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
cortinico added a commit to cortinico/react-native that referenced this pull request Mar 4, 2026
Summary:

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
cortinico added a commit to cortinico/react-native that referenced this pull request Mar 4, 2026
Summary:

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
cortinico added a commit to cortinico/react-native that referenced this pull request Mar 4, 2026
Summary:
Pull Request resolved: facebook#55885

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
Summary:

All 7 callers of DevSupportHttpClient are within ReactAndroid, so
there is no need to expose it as a public API. Make the class and all
its members internal.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D95059038
Summary:

The addRequestHeader/removeRequestHeader methods don't need to live inside devsupport.

Instead we can use the `setOkHttpClientFactory` to provide this same logic.

Changelog: [Internal]

Reviewed By: javache, cipolleschi

Differential Revision: D95059080
Summary:

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116
@meta-codesync meta-codesync Bot closed this in 8487b6d Mar 4, 2026
@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label Mar 4, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented Mar 4, 2026

This pull request has been merged in 8487b6d.

zoontek pushed a commit to zoontek/react-native that referenced this pull request Mar 9, 2026
Summary:
Pull Request resolved: facebook#55885

Instead of creating a brand-new OkHttpClient.Builder() per WebSocket
connection, derive from OkHttpClientProvider.getOkHttpClient() so
that all connections share the same connection pool and dispatcher.

Also remove the dispatcher shutdown call, since the dispatcher is now
shared with the global OkHttpClient and shutting it down would kill
all connections.

Changelog: [Internal]

Reviewed By: cipolleschi, javache

Differential Revision: D95059116

fbshipit-source-id: c8052c11f26a07961bcc8e4428508abeb391541d
meta-codesync Bot pushed a commit that referenced this pull request Apr 23, 2026
…#56579)

Summary:
#55885 changed WebSocketModule to derive its OkHttpClient from OkHttpClientProvider.getOkHttpClient().newBuilder() in order to share the connection pool and dispatcher. The shared client carries ReactCookieJarContainer, so OkHttp's BridgeInterceptor now calls Request.Builder.header("Cookie", ...) on every outgoing request — case-insensitively replacing any Cookie / cookie header the caller passed via the WebSocket constructor's `headers` option.

This silently drops caller-supplied Cookie auth on the upgrade request. Apps that rely on `new WebSocket(url, null, { headers: { cookie: ... } })` for authentication (a documented public API on Android/iOS) lose their session header on Android 0.83+, while iOS continues to work because the iOS WebSocket transport doesn't go through this interceptor pipeline.

Fix: explicitly set CookieJar.NO_COOKIES on the WebSocket-derived client. ForwardingCookieHandler cookies are still added manually via getCookie(), so cookies set via WebView's CookieManager keep flowing through. The connection pool and dispatcher sharing introduced by #55885 is preserved.

## Changelog:

[ANDROID] [FIXED] - WebSocketModule no longer strips a `Cookie` header passed via the WebSocket constructor's `headers` option

## Tested with:

Server logs the Cookie header it receives on the upgrade request:

```js
const ws = new WebSocket('wss://example.com/ws', null, {
  headers: { cookie: 'session=abc' },
});
```

| Build | Server sees |
| --- | --- |
| 0.81.6 Android | `Cookie: session=abc` |
| 0.83.6 Android (before this PR) | `Cookie: <whatever the cookie jar has, NOT session=abc>` |
| 0.83.6 Android (with this PR) | `Cookie: session=abc` |
| iOS, all versions | `Cookie: session=abc` |

Verified locally on RN 0.83.6 + a production app whose WebSocket auth broke on the 0.83.6 upgrade — a real-time streaming feed silently downgraded logged-in users to anonymous access. Applying the same change via `WebSocketModule.setCustomClientBuilder` from the host app's MainApplication.onCreate (functionally identical to this patch) restored authenticated streaming. Verified `fetch()` and other HTTP requests still get the cookie jar's cookies correctly — only the WebSocket OkHttpClient is affected by this change.

Pull Request resolved: #56579

Reviewed By: cortinico

Differential Revision: D102166959

Pulled By: javache

fbshipit-source-id: 72cbf66acf8ced17f6f104492de67bb6f92157ce
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants