Skip to content

Commit

Permalink
Fix 302 ImageLoader caching problem on iOS
Browse files Browse the repository at this point in the history
Summary:
+ Fixes #5616
+ Bug RNPlay Demo: https://rnplay.org/apps/Eg2goQ

Test demo loads a Tumblr avatar image using a URL that 301 to a CDN. Try to edit and save the file to trigger image reloads.

The 302 image request succeeds the first time:

<img width="318" alt="screen shot 2016-04-27 at 9 37 03 am" src="https://cloud.githubusercontent.com/assets/50120/14860038/b2c04e8a-0c5b-11e6-9edf-78309048368b.png">

But it fails for subsequent loads. You should see:

<img width="307" alt="screen shot 2016-04-27 at 9 37 22 am" src="https://cloud.githubusercontent.com/assets/50120/14860048/b756e170-0c5b-11e6-9031-8f3cca8f2994.png">

+ The first image is a 302, only succeeds to load the first time.
+ The second image in the column adds a nonce as request parameter to render caching ineffective (but still a 302), and the problem doesn't occur.
+ The last image is the canonical url location (200).

Although NSURLSession hand
Closes #7262

Differential Revision: D3231702

Pulled By: javache

fb-gh-sync-id: 364fcf9819188c63310768411d49e6431b2a01d3
fbshipit-source-id: 364fcf9819188c63310768411d49e6431b2a01d3
  • Loading branch information
hayeah authored and Facebook Github Bot 4 committed Apr 27, 2016
1 parent 8891f22 commit 192ab66
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion Libraries/Image/RCTImageLoader.m
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,24 @@ - (RCTImageLoaderCancellationBlock)loadImageOrDataWithTag:(NSString *)imageTag
// Check for cached response before reloading
// TODO: move URL cache out of RCTImageLoader into its own module
NSCachedURLResponse *cachedResponse = [_URLCache cachedResponseForRequest:request];
if (cachedResponse) {

while (cachedResponse) {
if ([cachedResponse.response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)cachedResponse.response;
if (httpResponse.statusCode == 301 || httpResponse.statusCode == 302) {
NSString *location = httpResponse.allHeaderFields[@"Location"];
if (location == nil) {
completionHandler(RCTErrorWithMessage(@"Image redirect without location"), nil);
return;
}

NSURL *redirectURL = [NSURL URLWithString: location];
request = [NSURLRequest requestWithURL: redirectURL];
cachedResponse = [_URLCache cachedResponseForRequest:request];
continue;
}
}

processResponse(cachedResponse.response, cachedResponse.data, nil);
return;
}
Expand Down

1 comment on commit 192ab66

@Stevemoretz
Copy link

Choose a reason for hiding this comment

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

What about android?

Please sign in to comment.