mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Support CDP response previews for chunked data (#52331)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52331 Updates the iOS inputs to `NetworkReporter` to support incremental string data HTTP responses (`Transfer-Encoding: chunked`). This means that incremental responses, such as Metro bundle requests, can be displayed as previews in React Native DevTools. Changelog: [Internal] Reviewed By: hoxyq Differential Revision: D77457109 fbshipit-source-id: 00a622dbac97c38e07c67b5ee3661c8d586f6fe1
This commit is contained in:
committed by
Facebook GitHub Bot
parent
94c97db4da
commit
68342a4d12
@@ -52,9 +52,27 @@
|
||||
*/
|
||||
+ (void)reportResponseEnd:(NSNumber *)requestId encodedDataLength:(int)encodedDataLength;
|
||||
|
||||
/**
|
||||
* Report when a network request has failed.
|
||||
*
|
||||
* - Corresponds to `Network.loadingFailed` in CDP.
|
||||
*/
|
||||
+ (void)reportRequestFailed:(NSNumber *)requestId;
|
||||
|
||||
/**
|
||||
* Store response body preview. This is an optional reporting method, and is a
|
||||
* no-op if CDP debugging is disabled.
|
||||
*/
|
||||
+ (void)maybeStoreResponseBody:(NSNumber *)requestId data:(NSData *)data base64Encoded:(bool)base64Encoded;
|
||||
|
||||
/**
|
||||
* Incrementally store a response body preview, when a string response is
|
||||
* received in chunks. Buffered contents will be flushed to `NetworkReporter`
|
||||
* with `reportResponseEnd`.
|
||||
*
|
||||
* As with `maybeStoreResponseBody`, calling this method is optional and a
|
||||
* no-op if CDP debugging is disabled.
|
||||
*/
|
||||
+ (void)maybeStoreResponseBodyIncremental:(NSNumber *)requestId data:(NSString *)data;
|
||||
|
||||
@end
|
||||
|
||||
@@ -45,6 +45,13 @@ std::string convertRequestBodyToStringTruncated(NSURLRequest *request)
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
|
||||
|
||||
// Dictionary to buffer incremental response bodies (CDP debugging active only)
|
||||
static const NSMutableDictionary<NSNumber *, NSMutableString *> *responseBuffers = nil;
|
||||
|
||||
#endif
|
||||
|
||||
@implementation RCTInspectorNetworkReporter {
|
||||
}
|
||||
|
||||
@@ -86,6 +93,31 @@ std::string convertRequestBodyToStringTruncated(NSURLRequest *request)
|
||||
+ (void)reportResponseEnd:(NSNumber *)requestId encodedDataLength:(int)encodedDataLength
|
||||
{
|
||||
NetworkReporter::getInstance().reportResponseEnd(requestId.stringValue.UTF8String, encodedDataLength);
|
||||
|
||||
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
|
||||
// Debug build: Check for buffered response body and flush to NetworkReporter
|
||||
if (responseBuffers != nullptr) {
|
||||
NSMutableString *buffer = responseBuffers[requestId];
|
||||
if (buffer != nullptr) {
|
||||
if (buffer.length > 0) {
|
||||
NetworkReporter::getInstance().storeResponseBody(
|
||||
requestId.stringValue.UTF8String, RCTStringViewFromNSString(buffer), false);
|
||||
}
|
||||
[responseBuffers removeObjectForKey:requestId];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO(T218584924): Implement and report to NetworkReporter
|
||||
+ (void)reportRequestFailed:(NSNumber *)requestId
|
||||
{
|
||||
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
|
||||
// Debug build: Clear buffer for request
|
||||
if (responseBuffers != nullptr) {
|
||||
[responseBuffers removeObjectForKey:requestId];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (void)maybeStoreResponseBody:(NSNumber *)requestId data:(id)data base64Encoded:(bool)base64Encoded
|
||||
@@ -115,4 +147,29 @@ std::string convertRequestBodyToStringTruncated(NSURLRequest *request)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (void)maybeStoreResponseBodyIncremental:(NSNumber *)requestId data:(NSString *)data
|
||||
{
|
||||
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
|
||||
// Debug build: Buffer incremental response body contents
|
||||
auto &networkReporter = NetworkReporter::getInstance();
|
||||
if (!networkReporter.isDebuggingEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (responseBuffers == nullptr) {
|
||||
responseBuffers = [NSMutableDictionary dictionary];
|
||||
}
|
||||
|
||||
// Get or create buffer for this requestId
|
||||
NSMutableString *buffer = responseBuffers[requestId];
|
||||
if (buffer == nullptr) {
|
||||
buffer = [NSMutableString string];
|
||||
responseBuffers[requestId] = buffer;
|
||||
}
|
||||
|
||||
[buffer appendString:data];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -627,9 +627,9 @@ RCT_EXPORT_MODULE()
|
||||
incrementalDataBlock = ^(NSData *data, int64_t progress, int64_t total) {
|
||||
NSUInteger initialCarryLength = incrementalDataCarry.length;
|
||||
|
||||
NSString *responseString = [RCTNetworking decodeTextData:data
|
||||
fromResponse:task.response
|
||||
withCarryData:incrementalDataCarry];
|
||||
id responseString = [RCTNetworking decodeTextData:data
|
||||
fromResponse:task.response
|
||||
withCarryData:incrementalDataCarry];
|
||||
if (!responseString) {
|
||||
RCTLogWarn(@"Received data was not a string, or was not a recognised encoding.");
|
||||
return;
|
||||
@@ -643,6 +643,9 @@ RCT_EXPORT_MODULE()
|
||||
@(total)
|
||||
];
|
||||
|
||||
if (facebook::react::ReactNativeFeatureFlags::enableNetworkEventReporting()) {
|
||||
[RCTInspectorNetworkReporter maybeStoreResponseBodyIncremental:task.requestID data:responseString];
|
||||
}
|
||||
[weakSelf sendEventWithName:@"didReceiveNetworkIncrementalData" body:responseJSON];
|
||||
};
|
||||
} else {
|
||||
@@ -668,7 +671,11 @@ RCT_EXPORT_MODULE()
|
||||
@[ task.requestID, RCTNullIfNil(error.localizedDescription), error.code == kCFURLErrorTimedOut ? @YES : @NO ];
|
||||
|
||||
if (facebook::react::ReactNativeFeatureFlags::enableNetworkEventReporting()) {
|
||||
[RCTInspectorNetworkReporter reportResponseEnd:task.requestID encodedDataLength:data.length];
|
||||
if (error != nullptr) {
|
||||
[RCTInspectorNetworkReporter reportRequestFailed:task.requestID];
|
||||
} else {
|
||||
[RCTInspectorNetworkReporter reportResponseEnd:task.requestID encodedDataLength:data.length];
|
||||
}
|
||||
}
|
||||
[strongSelf sendEventWithName:@"didCompleteNetworkResponse" body:responseJSON];
|
||||
[strongSelf->_tasksByRequestID removeObjectForKey:task.requestID];
|
||||
|
||||
Reference in New Issue
Block a user