Skip to content

Commit e0d34b2

Browse files
cortinicometa-codesync[bot]
authored andcommitted
Fix visibility of DevSupportHttpClient by extracting DevSupportRequestHeaders (#55739)
Summary: Pull Request resolved: #55739 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 Reviewed By: cipolleschi Differential Revision: D94354168 fbshipit-source-id: 72aa65b615fe4ef43feaab10ffea7526589a76fd
1 parent 0ce2790 commit e0d34b2

3 files changed

Lines changed: 58 additions & 18 deletions

File tree

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,6 +2184,13 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp
21842184
public abstract fun onResume ()V
21852185
}
21862186

2187+
public final class com/facebook/react/devsupport/interfaces/DevSupportRequestHeaders {
2188+
public static final field INSTANCE Lcom/facebook/react/devsupport/interfaces/DevSupportRequestHeaders;
2189+
public static final fun addRequestHeader (Ljava/lang/String;Ljava/lang/String;)V
2190+
public static final fun allHeaders ()Ljava/util/Map;
2191+
public static final fun removeRequestHeader (Ljava/lang/String;)V
2192+
}
2193+
21872194
public abstract interface class com/facebook/react/devsupport/interfaces/ErrorCustomizer {
21882195
public abstract fun customizeErrorInfo (Landroid/util/Pair;)Landroid/util/Pair;
21892196
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/DevSupportHttpClient.kt

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,29 @@
99

1010
package com.facebook.react.devsupport.inspector
1111

12-
import java.util.concurrent.ConcurrentHashMap
12+
import com.facebook.react.devsupport.interfaces.DevSupportRequestHeaders
1313
import java.util.concurrent.TimeUnit
1414
import okhttp3.Interceptor
1515
import okhttp3.OkHttpClient
1616

1717
/**
1818
* Shared [OkHttpClient] instances for devsupport networking. Uses a single connection pool and
19-
* dispatcher across all dev support HTTP and WebSocket usage.
19+
* dispatcher across all dev support HTTP and WebSocket usage. Injects custom request headers
20+
* registered via [DevSupportRequestHeaders] into every outgoing request.
2021
*/
2122
internal object DevSupportHttpClient {
22-
private val customHeaders = ConcurrentHashMap<String, String>()
23-
2423
private val headerInterceptor = Interceptor { chain ->
25-
val builder = chain.request().newBuilder()
26-
for ((name, value) in customHeaders) {
27-
builder.header(name, value)
24+
val originalRequest = chain.request()
25+
val headers = DevSupportRequestHeaders.allHeaders()
26+
if (headers.isEmpty()) {
27+
chain.proceed(originalRequest)
28+
} else {
29+
val builder = originalRequest.newBuilder()
30+
for ((name, value) in headers) {
31+
builder.header(name, value)
32+
}
33+
chain.proceed(builder.build())
2834
}
29-
chain.proceed(builder.build())
3035
}
3136

3237
/** Client for HTTP requests: connect=5s, write=disabled, read=disabled. */
@@ -45,14 +50,4 @@ internal object DevSupportHttpClient {
4550
.connectTimeout(10, TimeUnit.SECONDS)
4651
.writeTimeout(10, TimeUnit.SECONDS)
4752
.build()
48-
49-
/** Add a custom header to be included in all requests made through both clients. */
50-
fun addRequestHeader(name: String, value: String) {
51-
customHeaders[name] = value
52-
}
53-
54-
/** Remove a previously added custom header. */
55-
fun removeRequestHeader(name: String) {
56-
customHeaders.remove(name)
57-
}
5853
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.devsupport.interfaces
9+
10+
import java.util.concurrent.ConcurrentHashMap
11+
12+
/**
13+
* Thread-safe singleton for registering custom HTTP headers that will be applied to all React
14+
* Native dev-support network traffic (bundle fetches, packager status checks, inspector
15+
* connections, HMR WebSocket upgrades).
16+
*
17+
* Headers are stored globally and survive across React Host re-creations, so they can be set before
18+
* the first app load.
19+
*/
20+
public object DevSupportRequestHeaders {
21+
22+
private val headers = ConcurrentHashMap<String, String>()
23+
24+
/** Adds (or replaces) a custom request header. */
25+
@JvmStatic
26+
public fun addRequestHeader(name: String, value: String) {
27+
headers[name] = value
28+
}
29+
30+
/** Removes a previously added custom request header. */
31+
@JvmStatic
32+
public fun removeRequestHeader(name: String) {
33+
headers.remove(name)
34+
}
35+
36+
/** Returns a snapshot of all currently registered headers. */
37+
@JvmStatic public fun allHeaders(): Map<String, String> = HashMap(headers)
38+
}

0 commit comments

Comments
 (0)