Use the correct way to specify cancel if the response status code is invalid.
Showing
1 changed file
with
15 additions
and
27 deletions
@@ -182,7 +182,7 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary; | @@ -182,7 +182,7 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary; | ||
182 | [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:weakSelf]; | 182 | [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:weakSelf]; |
183 | }); | 183 | }); |
184 | } else { | 184 | } else { |
185 | - [self callCompletionBlocksWithError:[NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Connection can't be initialized"}]]; | 185 | + [self callCompletionBlocksWithError:[NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Task can't be initialized"}]]; |
186 | } | 186 | } |
187 | 187 | ||
188 | #if SD_UIKIT | 188 | #if SD_UIKIT |
@@ -215,7 +215,7 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary; | @@ -215,7 +215,7 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary; | ||
215 | [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:weakSelf]; | 215 | [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:weakSelf]; |
216 | }); | 216 | }); |
217 | 217 | ||
218 | - // As we cancelled the connection, its callback won't be called and thus won't | 218 | + // As we cancelled the task, its callback won't be called and thus won't |
219 | // maintain the isFinished and isExecuting flags. | 219 | // maintain the isFinished and isExecuting flags. |
220 | if (self.isExecuting) self.executing = NO; | 220 | if (self.isExecuting) self.executing = NO; |
221 | if (!self.isFinished) self.finished = YES; | 221 | if (!self.isFinished) self.finished = YES; |
@@ -278,48 +278,36 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary; | @@ -278,48 +278,36 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary; | ||
278 | dataTask:(NSURLSessionDataTask *)dataTask | 278 | dataTask:(NSURLSessionDataTask *)dataTask |
279 | didReceiveResponse:(NSURLResponse *)response | 279 | didReceiveResponse:(NSURLResponse *)response |
280 | completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { | 280 | completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { |
281 | - | ||
282 | - //'304 Not Modified' is an exceptional one | ||
283 | - if (![response respondsToSelector:@selector(statusCode)] || (((NSHTTPURLResponse *)response).statusCode < 400 && ((NSHTTPURLResponse *)response).statusCode != 304)) { | 281 | + NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow; |
284 | NSInteger expected = (NSInteger)response.expectedContentLength; | 282 | NSInteger expected = (NSInteger)response.expectedContentLength; |
285 | expected = expected > 0 ? expected : 0; | 283 | expected = expected > 0 ? expected : 0; |
286 | self.expectedSize = expected; | 284 | self.expectedSize = expected; |
285 | + self.response = response; | ||
286 | + | ||
287 | + //'304 Not Modified' is an exceptional one. It should be treated as cancelled. | ||
288 | + if (![response respondsToSelector:@selector(statusCode)] || (((NSHTTPURLResponse *)response).statusCode < 400 && ((NSHTTPURLResponse *)response).statusCode != 304)) { | ||
287 | for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) { | 289 | for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) { |
288 | progressBlock(0, expected, self.request.URL); | 290 | progressBlock(0, expected, self.request.URL); |
289 | } | 291 | } |
290 | - | ||
291 | - self.imageData = [[NSMutableData alloc] initWithCapacity:expected]; | ||
292 | - self.response = response; | ||
293 | - __weak typeof(self) weakSelf = self; | ||
294 | - dispatch_async(dispatch_get_main_queue(), ^{ | ||
295 | - [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadReceiveResponseNotification object:weakSelf]; | ||
296 | - }); | ||
297 | } else { | 292 | } else { |
298 | - NSUInteger code = ((NSHTTPURLResponse *)response).statusCode; | ||
299 | - | ||
300 | - //This is the case when server returns '304 Not Modified'. It means that remote image is not changed. | ||
301 | - //In case of 304 we need just cancel the operation and return cached image from the cache. | ||
302 | - if (code == 304) { | ||
303 | - [self cancelInternal]; | ||
304 | - } else { | ||
305 | - [self.dataTask cancel]; | 293 | + // Status code invalid and marked as cancelled. Do not call `[self.dataTask cancel]` which may mass up URLSession life cycle |
294 | + disposition = NSURLSessionResponseCancel; | ||
306 | } | 295 | } |
296 | + | ||
307 | __weak typeof(self) weakSelf = self; | 297 | __weak typeof(self) weakSelf = self; |
308 | dispatch_async(dispatch_get_main_queue(), ^{ | 298 | dispatch_async(dispatch_get_main_queue(), ^{ |
309 | - [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:weakSelf]; | 299 | + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadReceiveResponseNotification object:weakSelf]; |
310 | }); | 300 | }); |
311 | 301 | ||
312 | - [self callCompletionBlocksWithError:[NSError errorWithDomain:NSURLErrorDomain code:((NSHTTPURLResponse *)response).statusCode userInfo:nil]]; | ||
313 | - | ||
314 | - [self done]; | ||
315 | - } | ||
316 | - | ||
317 | if (completionHandler) { | 302 | if (completionHandler) { |
318 | - completionHandler(NSURLSessionResponseAllow); | 303 | + completionHandler(disposition); |
319 | } | 304 | } |
320 | } | 305 | } |
321 | 306 | ||
322 | - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { | 307 | - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { |
308 | + if (!self.imageData) { | ||
309 | + self.imageData = [[NSMutableData alloc] initWithCapacity:self.expectedSize]; | ||
310 | + } | ||
323 | [self.imageData appendData:data]; | 311 | [self.imageData appendData:data]; |
324 | 312 | ||
325 | if ((self.options & SDWebImageDownloaderProgressiveDownload) && self.expectedSize > 0) { | 313 | if ((self.options & SDWebImageDownloaderProgressiveDownload) && self.expectedSize > 0) { |
-
Please register or login to post a comment