Skip to content

Commit 24b51db

Browse files
psjostrommeta-codesync[bot]
authored andcommitted
fix(android): WebSocketModule stripping caller-supplied Cookie header (facebook#56579)
Summary: facebook#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 facebook#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: facebook#56579 Reviewed By: cortinico Differential Revision: D102166959 Pulled By: javache fbshipit-source-id: 72cbf66acf8ced17f6f104492de67bb6f92157ce
1 parent 9d18367 commit 24b51db

1 file changed

Lines changed: 3 additions & 0 deletions

File tree

  • packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/websocket

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/WebSocketModule.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import java.net.URISyntaxException
2929
import java.util.HashMap
3030
import java.util.concurrent.ConcurrentHashMap
3131
import java.util.concurrent.TimeUnit
32+
import okhttp3.CookieJar
3233
import okhttp3.OkHttpClient
3334
import okhttp3.Request
3435
import okhttp3.Response
@@ -83,6 +84,8 @@ public class WebSocketModule(context: ReactApplicationContext) :
8384
val okHttpBuilder =
8485
OkHttpClientProvider.getOkHttpClient()
8586
.newBuilder()
87+
// Don't let BridgeInterceptor overwrite a caller-supplied Cookie header.
88+
.cookieJar(CookieJar.NO_COOKIES)
8689
.connectTimeout(10, TimeUnit.SECONDS)
8790
.writeTimeout(10, TimeUnit.SECONDS)
8891
.readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read

0 commit comments

Comments
 (0)