Skip to content

Commit cc44e96

Browse files
huntiemeta-codesync[bot]
authored andcommitted
Re-implement request body previews on Android (#55456)
Summary: Pull Request resolved: #55456 **Context** Follow-up to D89373824, which addressed a runtime Android crash with `FormData` uploads (#54881) but introduced a "[Preview unavailable]" fallback for the `ProgressRequestBody` case. **This diff** Reintroduce request body previews under this case. Protects agains the original crash by: - Checking `body.isOneShot()` to prevent disallowed double-reads of stream bodies. - [Pre-existing] Preserves `BuildConfig.DEBUG` guard added in D89377163. Changelog: [Android][Added] - React Native DevTools: Restore request payload previews on Android Reviewed By: vzaidman Differential Revision: D89381124 fbshipit-source-id: ae6ce006285b4bcd7bbb09bb4413d119f18a8630
1 parent 0d40f2a commit cc44e96

3 files changed

Lines changed: 38 additions & 11 deletions

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkEventUtil.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@ import com.facebook.react.bridge.ReactApplicationContext
1616
import com.facebook.react.bridge.WritableMap
1717
import com.facebook.react.bridge.buildReadableArray
1818
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
19+
import java.io.IOException
1920
import java.net.SocketTimeoutException
2021
import okhttp3.Headers
22+
import okhttp3.RequestBody
23+
import okio.Buffer
2124

2225
/**
2326
* Utility class for reporting network lifecycle events to JavaScript and InspectorNetworkReporter.
2427
*/
2528
internal object NetworkEventUtil {
29+
private const val MAX_BODY_PREVIEW_SIZE = 512 * 1024 // 512KB
30+
2631
@JvmStatic
2732
fun onCreateRequest(
2833
devToolsRequestId: String,
@@ -243,4 +248,33 @@ internal object NetworkEventUtil {
243248
}
244249
return responseHeaders
245250
}
251+
252+
@JvmStatic
253+
fun getRequestBodyPreview(requestBody: RequestBody?): String? {
254+
if (requestBody == null) {
255+
return null
256+
}
257+
258+
// Unwrap ProgressRequestBody
259+
val body = (requestBody as? ProgressRequestBody)?.innerBody() ?: requestBody
260+
261+
if (body.isOneShot()) {
262+
// Fallback - body cannot be read twice
263+
return "[Preview unavailable]"
264+
}
265+
266+
return try {
267+
val buffer = Buffer()
268+
body.writeTo(buffer)
269+
270+
val size = buffer.size()
271+
if (size <= MAX_BODY_PREVIEW_SIZE) {
272+
buffer.readUtf8()
273+
} else {
274+
buffer.readUtf8(MAX_BODY_PREVIEW_SIZE.toLong()) + "... (truncated, ${size} bytes total)"
275+
}
276+
} catch (e: IOException) {
277+
"[Preview unavailable]"
278+
}
279+
}
246280
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -610,12 +610,8 @@ public class NetworkingModule(
610610
request.url().toString(),
611611
request.method(),
612612
NetworkEventUtil.okHttpHeadersToMap(request.headers()),
613-
if (ReactBuildConfig.DEBUG) {
614-
// Debug build: Include request body for preview in DevTools
615-
(request.body() as? ProgressRequestBody)?.getBodyPreview() ?: request.body()?.toString()
616-
} else {
617-
null
618-
},
613+
if (ReactBuildConfig.DEBUG) NetworkEventUtil.getRequestBodyPreview(request.body())
614+
else null,
619615
request.body()?.contentLength() ?: 0,
620616
)
621617

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/network/ProgressRequestBody.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ internal class ProgressRequestBody(
5050
sinkWrapper.flush()
5151
}
5252

53+
fun innerBody(): RequestBody = requestBody
54+
5355
private fun outputStreamSink(sink: BufferedSink): Sink {
5456
return Okio.sink(
5557
object : FilterOutputStream(sink.outputStream()) {
@@ -78,9 +80,4 @@ internal class ProgressRequestBody(
7880
}
7981
)
8082
}
81-
82-
fun getBodyPreview(): String {
83-
// TODO: Safely implement request body previews
84-
return "[Preview unavailable]"
85-
}
8683
}

0 commit comments

Comments
 (0)