From 367fc7ad5254c5dd2c8ef38248766173525cc77c Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Tue, 4 Jul 2023 13:38:51 +0100 Subject: [PATCH] [0.69] Use `Content-Location` header in bundle response as JS source URL (#37501) (#38179) resolved: https://github.com/facebook/react-native/pull/37501 fix for https://github.com/facebook/react-native/issues/36794. --- React/Base/RCTJavaScriptLoader.mm | 12 +++++++++++- React/CxxBridge/RCTCxxBridge.mm | 13 +++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/React/Base/RCTJavaScriptLoader.mm b/React/Base/RCTJavaScriptLoader.mm index 133851a1d7f49d..b789d949a9ce23 100755 --- a/React/Base/RCTJavaScriptLoader.mm +++ b/React/Base/RCTJavaScriptLoader.mm @@ -312,7 +312,17 @@ static void attemptAsynchronousLoadOfBundleAtURL( return; } - RCTSource *source = RCTSourceCreate(scriptURL, data, data.length); + // Prefer `Content-Location` as the canonical source URL, if given, or fall back to scriptURL. + NSURL *sourceURL = scriptURL; + NSString *contentLocationHeader = headers[@"Content-Location"]; + if (contentLocationHeader) { + NSURL *contentLocationURL = [NSURL URLWithString:contentLocationHeader relativeToURL:scriptURL]; + if (contentLocationURL) { + sourceURL = contentLocationURL; + } + } + + RCTSource *source = RCTSourceCreate(sourceURL, data, data.length); parseHeaders(headers, source); onComplete(nil, source); } diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index cad9d74f02b38f..7785cd25086c96 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -473,6 +473,7 @@ - (void)start // Load the source asynchronously, then store it for later execution. dispatch_group_enter(prepareBridge); __block NSData *sourceCode; + __block NSURL *sourceURL = self.bundleURL; #if (RCT_DEV | RCT_ENABLE_LOADING_VIEW) && __has_include() { @@ -488,6 +489,9 @@ - (void)start } sourceCode = source.data; + if (source.url) { + sourceURL = source.url; + } dispatch_group_leave(prepareBridge); } onProgress:^(RCTLoadingProgress *progressData) { @@ -502,7 +506,7 @@ - (void)start dispatch_group_notify(prepareBridge, dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{ RCTCxxBridge *strongSelf = weakSelf; if (sourceCode && strongSelf.loading) { - [strongSelf executeSourceCode:sourceCode sync:NO]; + [strongSelf executeSourceCode:sourceCode withSourceURL:sourceURL sync:NO]; } }); RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); @@ -1048,7 +1052,7 @@ - (void)registerModuleForFrameUpdates:(id)module withModuleData [_displayLink registerModuleForFrameUpdates:module withModuleData:moduleData]; } -- (void)executeSourceCode:(NSData *)sourceCode sync:(BOOL)sync +- (void)executeSourceCode:(NSData *)sourceCode withSourceURL:(NSURL *)url sync:(BOOL)sync { // This will get called from whatever thread was actually executing JS. dispatch_block_t completion = ^{ @@ -1073,12 +1077,13 @@ - (void)executeSourceCode:(NSData *)sourceCode sync:(BOOL)sync }; if (sync) { - [self executeApplicationScriptSync:sourceCode url:self.bundleURL]; + [self executeApplicationScriptSync:sourceCode url:url]; completion(); } else { - [self enqueueApplicationScript:sourceCode url:self.bundleURL onComplete:completion]; + [self enqueueApplicationScript:sourceCode url:url onComplete:completion]; } + // Use the original request URL here - HMRClient uses this to derive the /hot URL and entry point. [self.devSettings setupHMRClientWithBundleURL:self.bundleURL]; }