Skip to content

[0.83] Add support for custom header in devsupport#55722

Merged
cortinico merged 25 commits into0.83-stablefrom
nc/devsupport-083
Mar 4, 2026
Merged

[0.83] Add support for custom header in devsupport#55722
cortinico merged 25 commits into0.83-stablefrom
nc/devsupport-083

Conversation

@cortinico
Copy link
Contributor

Summary:

This is a series of commits that add custom header capability to devsupport (Android & iOS) for 0.83.

Changelog:

[INTERNAL] -

Test Plan:

CI

@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 Feb 24, 2026
@github-actions
Copy link

Warning

JavaScript API change detected

This PR commits an update to ReactNativeApi.d.ts, indicating a change to React Native's public JavaScript API.

  • Please include a clear changelog message.
  • This change will be subject to additional review.

This change was flagged as: BREAKING

@cortinico cortinico marked this pull request as draft February 24, 2026 16:15
@github-actions
Copy link

Job Summary for Gradle

Test All :: run_fantom_tests
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
react-native-github :private:react-native-fantom:buildFantomTester 9.0.0 Build Scan not published

@github-actions
Copy link

Job Summary for Gradle

Test All :: run_fantom_tests
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
react-native-github :private:react-native-fantom:buildFantomTester 9.0.0 Build Scan not published

@github-actions
Copy link

Job Summary for Gradle

Test All :: run_fantom_tests
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
react-native-github :private:react-native-fantom:buildFantomTester 9.0.0 Build Scan not published

Summary:
Pull Request resolved: #55575

The devsupport package creates multiple OkHttpClient instances across different files, each with its own connection pool and thread pool. This is wasteful and introduces bugs (thread-safety race in InspectorNetworkHelper, per-tap allocation in RedBoxContentView).

This diff introduces DevSupportHttpClient, an internal object singleton with two shared clients derived from the same connection pool:
- httpClient: with connect=5s, write=disabled, read=disabled (for HTTP requests)
- websocketClient: derived via newBuilder() with connect=10s, write=10s, read=disabled (for WebSocket/inspector use)

Subsequent diffs in this stack migrate each consumer to use these shared clients.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D93480249

fbshipit-source-id: b489f5946aa0c0a5318f0fb600dec31f373b8c09
Summary:
Pull Request resolved: #55576

Replace the inline OkHttpClient.Builder() in DevServerHelper with DevSupportHttpClient.httpClient. This shares the connection pool and thread pool with all other devsupport HTTP consumers. Remove the now-unused HTTP_CONNECT_TIMEOUT_MS constant and TimeUnit import.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D93480251

fbshipit-source-id: b783c2b7a499d20fc12a9fca664651e99b00579d
#55577)

Summary:
Pull Request resolved: #55577

PackagerStatusCheck had two constructors: a no-arg one that created its own OkHttpClient, and one that accepted an external client. The no-arg constructor is used by callers in fbandroid/ (FbDevBottomSheetViewController, LocalJsPackagerManager, FbPackagerStatusCheck, FbDevModeNuxController). Instead of removing it, delegate it to `DevSupportHttpClient.httpClient` so that all callers share the same connection pool without needing code changes.

Also removes the now-unused `HTTP_CONNECT_TIMEOUT_MS` constant since the timeout configuration is centralized in DevSupportHttpClient.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi

Differential Revision: D93480248

fbshipit-source-id: 07b3a6c01cec19a5de1604c560229622974e500e
Summary:
Pull Request resolved: #55578

RedBoxContentView.OpenStackFrameTask was creating a new OkHttpClient() (with a fresh connection pool and thread pool) every time a user tapped a stack frame in the red box. Replace with the shared DevSupportHttpClient.httpClient singleton.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D93480250

fbshipit-source-id: 882c218e709681e5f5fb22b4b35710d23f349c8e
Summary:
Pull Request resolved: #55579

InspectorNetworkHelper used a lateinit var with an isInitialized check to lazily create an OkHttpClient. This pattern is not thread-safe — concurrent calls to loadNetworkResource could race on the initialization. Replace with the shared DevSupportHttpClient.websocketClient singleton, which is initialized at class load time and is inherently safe.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D93480252

fbshipit-source-id: fefb144b3b26670954a77aa27c9b7f637290f21b
Summary:
Pull Request resolved: #55580

Replace the OkHttpClient.Builder() in CxxInspectorPackagerConnection.DelegateImpl with DevSupportHttpClient.websocketClient. This shares the connection pool and thread pool with all other devsupport WebSocket consumers. Remove the now-unused TimeUnit and OkHttpClient imports.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D93480223

fbshipit-source-id: ff3d742ccb4f484f4906496b1a081377a1b3fa8d
Summary:
Pull Request resolved: #55581

Replace the inline OkHttpClient.Builder() in ReconnectingWebSocket with DevSupportHttpClient.websocketClient. This shares the connection pool and thread pool with all other devsupport WebSocket consumers.

DevSupportHttpClient is changed from internal to public to be accessible from the packagerconnection module, and the packagerconnection BUCK target gains a dependency on the inspector target.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D93481092

fbshipit-source-id: b0d6a14e59310e2f975ce92d6bab68f6f6a231da
Summary:
Pull Request resolved: #55582

Add addRequestHeader/removeRequestHeader methods to DevSupportHttpClient. These allow callers to register custom HTTP headers that will be included in all requests made through both the httpClient and websocketClient.

Implemented via a shared OkHttp Interceptor that reads from a ConcurrentHashMap, so headers can be safely added/removed from any thread.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D93481539

fbshipit-source-id: e8d6bc4c9d21c65a0f4d95065eaadff776933c55
Summary:
Pull Request resolved: #55586

Add a thread-safe singleton that holds custom HTTP headers to be applied to all iOS devsupport network requests. This mirrors the Android `DevSupportHttpClient` from D93481539. Uses a GCD concurrent queue with barrier writes for reader-writer synchronization.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi

Differential Revision: D93490954

fbshipit-source-id: addb2f11025a046eedd0e296a7c398eef7211dc4
Summary:
Pull Request resolved: #55607

Inject custom devsupport headers into bundle download requests. This ensures that multipart bundle fetches include any headers registered via `RCTDevSupportHttpHeaders`.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi

Differential Revision: D93596721

fbshipit-source-id: 358b0de351677b843a70204caa101531941789b0
Summary:
Pull Request resolved: #55608

Inject custom devsupport headers into the packager status check request. Changes NSURLRequest to NSMutableURLRequest to allow header mutation before the request is sent.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi

Differential Revision: D93596717

fbshipit-source-id: 94ab3df95317cb3697d26d18b6a27750bfcf4bff
Summary:
Pull Request resolved: #55609

Inject custom devsupport headers into the open-debugger POST request. This ensures the debugger launch request includes any registered custom headers.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi

Differential Revision: D93596719

fbshipit-source-id: d4ed0a67b586b8b4e6bbd1817b7cfdf0bd75065f
Summary:
Pull Request resolved: #55610

Inject custom devsupport headers into inspector resource loading requests. This ensures that inspector network fetches include any registered custom headers.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi

Differential Revision: D93596720

fbshipit-source-id: bda4690a2d9c78729c874977357358a432e46046
Summary:
Pull Request resolved: #55611

Inject custom devsupport headers into the HMR WebSocket connection. Changes from `initWithURL:` to `initWithURLRequest:` so headers can be set on the HTTP upgrade handshake.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi

Differential Revision: D93596718

fbshipit-source-id: ab028d0e03e11f0efde000d19943693439236dbc
Summary:
Pull Request resolved: #55612

Inject custom devsupport headers into the inspector CDP WebSocket connection. Changes from `initWithURL:` to `initWithURLRequest:` so headers can be set on the HTTP upgrade handshake.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi

Differential Revision: D93596715

fbshipit-source-id: 12dc5c991027654fdd5559daafbc27144a0fdb6b
…tHeaders

Summary:
Extract header management from the `internal` `DevSupportHttpClient` into a new
public `DevSupportRequestHeaders` singleton in `devsupport.interfaces`. This
allows external consumers (e.g. Expo Dev Launcher) to register custom HTTP
headers that will be applied to all React Native dev-support network traffic
without depending on internal APIs.

`DevSupportHttpClient` now delegates to `DevSupportRequestHeaders.allHeaders()`
instead of maintaining its own `ConcurrentHashMap`.

A separate `request_headers` Buck target is introduced to avoid a dependency
cycle (`bridge` → `inspector` → `interfaces` → `bridge`).

Changelog: [Android][Added] - Public DevSupportRequestHeaders API for registering custom dev-support HTTP headers

Differential Revision: D94354168
Summary:
Revert the `DevSupportRequestHeaders` extraction from D94354168 and instead
make `DevSupportHttpClient` itself `public`. This gives external consumers
(e.g. Expo Dev Launcher) direct access to the shared OkHttpClient instances
and the `addRequestHeader`/`removeRequestHeader` methods without needing a
separate intermediary singleton.

Changes:
- Remove `DevSupportRequestHeaders` class and its `request_headers` Buck target
- Change `DevSupportHttpClient` from `internal` to `public`
- Restore `addRequestHeader`/`removeRequestHeader` methods in `DevSupportHttpClient`
- Revert `interfaces` Buck target to include all `interfaces/*.kt` files
- Revert inspector Buck target to remove the `request_headers` dependency

This looks breaking from the API prespective but `DevSupportRequestHeaders` was never shipped, so it's just an addittive change.

Changelog: [Android][Added] - Make DevSupportHttpClient public for custom dev-support HTTP header registration

Differential Revision: D94515394
Summary:
Pull Request resolved: #55790

React Native hardcodes http:// and ws:// schemes for all dev-support
URLs (inspector, message, status, bundle, debugger). When routing
through the proxy on port 443, this causes plain HTTP connections
to an HTTPS port, which fail.

Add httpScheme()/wsScheme() helpers to DevSupportHttpClient that
return https/wss when the host ends with :443, and update all URL
construction sites: DevServerHelper, JSPackagerClient, and
PackagerStatusCheck.

Changelog: [Internal]

Reviewed By: mdvacca, cipolleschi, vzaidman

Differential Revision: D94529835

fbshipit-source-id: f446939a82069c0466e26f107294ec4c6dd797d9
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.

While this would be considered breaking, I'm planning to pick this into 0.85 to make this change not breaking. This API has just been introduced in 0.85 and I'm fine having it not exposed.

Changelog: [Internal]

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]

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]

Differential Revision: D95059116
Summary:
Instead of creating an independent OkHttpClient, derive from
OkHttpClientProvider.getOkHttpClient() so that all dev support
connections share the same connection pool and dispatcher with
the rest of React Native networking.

Changelog: [Internal]

Differential Revision: D95058926
@cipolleschi
Copy link
Contributor

This pr is lacking changes on the JS side of things, though...

delegateQueue:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];
[request addValue:@"multipart/mixed" forHTTPHeaderField:@"Accept"];
[[RCTDevSupportHttpHeaders sharedInstance] applyHeadersToRequest:request];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will apply the headers to all the traffic, not just to the endpoints we need.

When a PR targets a -stable branch, github.ref_name is the PR branch
(not ending in -stable), so the version script was incorrectly running.
Added a check for github.base_ref to also skip the script when the PR
target branch is a stable branch.
@cortinico cortinico requested a review from cipolleschi March 4, 2026 16:51
@cortinico cortinico marked this pull request as ready for review March 4, 2026 17:22
@cortinico cortinico merged commit c8ab750 into 0.83-stable Mar 4, 2026
119 of 120 checks passed
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. p: Facebook Partner: Facebook Partner Pick Request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants