-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix 302 ImageLoader caching problem on iOS #7262
Conversation
By analyzing the blame information on this pull request, we identified @nicklockwood and @ide to be potential reviewers. |
if (cachedResponse) { | ||
processResponse(cachedResponse.response, cachedResponse.data, nil); | ||
return; | ||
while(true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while (true)
is a big code smell. I'd prefer it if we repeated the NSCachedURLResponse *cachedResponse = [_URLCache cachedResponseForRequest:request];
line instead and use that as the loop condition.
Thanks for fixing this! The solution looks good but I'd restructure the loop a bit so it's easier to maintain. |
edab48d
to
37af780
Compare
@hayeah updated the pull request. |
@javache I rewrote the loop per your advice. In Golang for {
cond := ...
if cond {
return err;
}
if cond2 {
break
}
} In this case there is just one loop condition, so probably better to be explicit in the loop structure. Thanks for the tip! |
@@ -371,11 +371,23 @@ - (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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style nit: while (cachedResponse) {
37af780
to
0204ee4
Compare
@hayeah updated the pull request. |
if (cachedResponse) { | ||
|
||
while (cachedResponse) { | ||
if ([cachedResponse.response isKindOfClass: [NSHTTPURLResponse class]]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last style nits, I promise :)
There shouldn't be a space between the :
and the argument, so isKindOfClass:[NSHTTPURLResponse class]
0204ee4
to
710653f
Compare
@hayeah updated the pull request. |
710653f
to
ed2dcfb
Compare
@hayeah updated the pull request. |
@javache If Location is nil, would now call the completion handler with error. |
@facebook-github-bot shipit |
Thanks for importing. If you are an FB employee go to Phabricator to review. |
192ab66
Summary: + Fixes facebook#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 facebook#7262 Differential Revision: D3231702 Pulled By: javache fb-gh-sync-id: 364fcf9819188c63310768411d49e6431b2a01d3 fbshipit-source-id: 364fcf9819188c63310768411d49e6431b2a01d3
Summary: + Fixes facebook#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 facebook#7262 Differential Revision: D3231702 Pulled By: javache fb-gh-sync-id: 364fcf9819188c63310768411d49e6431b2a01d3 fbshipit-source-id: 364fcf9819188c63310768411d49e6431b2a01d3
Summary: + Fixes facebook#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 facebook#7262 Differential Revision: D3231702 Pulled By: javache fb-gh-sync-id: 364fcf9819188c63310768411d49e6431b2a01d3 fbshipit-source-id: 364fcf9819188c63310768411d49e6431b2a01d3
Hi @hayeah, do you know if this PR was merged? Or why was closed? |
@diogoca I believe that this was merged a long time ago. |
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.
Problem Description
The 302 image request succeeds the first time:
But it fails for subsequent loads. You should see:
- 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). # Analysis
Although NSURLSession handles redirect and caching properly, the
RCTImageLoader
checks the cache directly to see if an image url has cached response. Like so:See:
react-native/Libraries/Image/RCTImageLoader.m
Line 373 in 9547a98
This is a problem because
cachedResponseForRequest
does not handle redirect. The returned response is a 302, which causes ImageLoading failure later on.This PR changes this chunk of code to follow the redirect.