Make ASIReloadIfDifferentCachePolicy turn requests into conditional GETs
Stop wasting time insensitive matching response headers, CFNetwork will normalise the case for us anyway
Showing
2 changed files
with
22 additions
and
17 deletions
| @@ -17,7 +17,6 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | @@ -17,7 +17,6 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | ||
| 17 | 17 | ||
| 18 | @interface ASIDownloadCache () | 18 | @interface ASIDownloadCache () |
| 19 | + (NSString *)keyForRequest:(ASIHTTPRequest *)request; | 19 | + (NSString *)keyForRequest:(ASIHTTPRequest *)request; |
| 20 | -+ (NSString *)responseHeader:(NSString *)header fromHeaders:(NSDictionary *)headers; | ||
| 21 | @end | 20 | @end |
| 22 | 21 | ||
| 23 | @implementation ASIDownloadCache | 22 | @implementation ASIDownloadCache |
| @@ -185,9 +184,9 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | @@ -185,9 +184,9 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | ||
| 185 | return NO; | 184 | return NO; |
| 186 | } | 185 | } |
| 187 | // If the Etag or Last-Modified date are different from the one we have, fetch the document again | 186 | // If the Etag or Last-Modified date are different from the one we have, fetch the document again |
| 188 | - NSArray *headersToCompare = [NSArray arrayWithObjects:@"etag",@"last-modified",nil]; | 187 | + NSArray *headersToCompare = [NSArray arrayWithObjects:@"Etag",@"Last-Modified",nil]; |
| 189 | for (NSString *header in headersToCompare) { | 188 | for (NSString *header in headersToCompare) { |
| 190 | - if (![[[self class] responseHeader:header fromHeaders:[request responseHeaders]] isEqualToString:[[self class] responseHeader:header fromHeaders:cachedHeaders]]) { | 189 | + if (![[[request responseHeaders] objectForKey:header] isEqualToString:[cachedHeaders objectForKey:header]]) { |
| 191 | return NO; | 190 | return NO; |
| 192 | } | 191 | } |
| 193 | } | 192 | } |
| @@ -195,14 +194,14 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | @@ -195,14 +194,14 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | ||
| 195 | return YES; | 194 | return YES; |
| 196 | } | 195 | } |
| 197 | // Look for an Expires header to see if the content is out of data | 196 | // Look for an Expires header to see if the content is out of data |
| 198 | - NSString *expires = [[self class] responseHeader:@"expires" fromHeaders:cachedHeaders]; | 197 | + NSString *expires = [cachedHeaders objectForKey:@"Expires"]; |
| 199 | if (expires) { | 198 | if (expires) { |
| 200 | if ([[ASIHTTPRequest dateFromRFC1123String:expires] timeIntervalSinceNow] < 0) { | 199 | if ([[ASIHTTPRequest dateFromRFC1123String:expires] timeIntervalSinceNow] < 0) { |
| 201 | return NO; | 200 | return NO; |
| 202 | } | 201 | } |
| 203 | } | 202 | } |
| 204 | // Look for a max-age header | 203 | // Look for a max-age header |
| 205 | - NSString *cacheControl = [[[self class] responseHeader:@"cache-control" fromHeaders:cachedHeaders] lowercaseString]; | 204 | + NSString *cacheControl = [[cachedHeaders objectForKey:@"Cache-Control"] lowercaseString]; |
| 206 | if (cacheControl) { | 205 | if (cacheControl) { |
| 207 | NSScanner *scanner = [NSScanner scannerWithString:cacheControl]; | 206 | NSScanner *scanner = [NSScanner scannerWithString:cacheControl]; |
| 208 | if ([scanner scanString:@"max-age" intoString:NULL]) { | 207 | if ([scanner scanString:@"max-age" intoString:NULL]) { |
| @@ -277,13 +276,13 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | @@ -277,13 +276,13 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | ||
| 277 | 276 | ||
| 278 | + (BOOL)serverAllowsResponseCachingForRequest:(ASIHTTPRequest *)request | 277 | + (BOOL)serverAllowsResponseCachingForRequest:(ASIHTTPRequest *)request |
| 279 | { | 278 | { |
| 280 | - NSString *cacheControl = [[[self class] responseHeader:@"cache-control" fromHeaders:[request responseHeaders]] lowercaseString]; | 279 | + NSString *cacheControl = [[[request responseHeaders] objectForKey:@"Cache-Control"] lowercaseString]; |
| 281 | if (cacheControl) { | 280 | if (cacheControl) { |
| 282 | if ([cacheControl isEqualToString:@"no-cache"] || [cacheControl isEqualToString:@"no-store"]) { | 281 | if ([cacheControl isEqualToString:@"no-cache"] || [cacheControl isEqualToString:@"no-store"]) { |
| 283 | return NO; | 282 | return NO; |
| 284 | } | 283 | } |
| 285 | } | 284 | } |
| 286 | - NSString *pragma = [[[self class] responseHeader:@"pragma" fromHeaders:[request responseHeaders]] lowercaseString]; | 285 | + NSString *pragma = [[[request responseHeaders] objectForKey:@"Pragma"] lowercaseString]; |
| 287 | if (pragma) { | 286 | if (pragma) { |
| 288 | if ([pragma isEqualToString:@"no-cache"]) { | 287 | if ([pragma isEqualToString:@"no-cache"]) { |
| 289 | return NO; | 288 | return NO; |
| @@ -301,15 +300,6 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | @@ -301,15 +300,6 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | ||
| 301 | return [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],result[8], result[9], result[10], result[11],result[12], result[13], result[14], result[15]]; | 300 | return [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],result[8], result[9], result[10], result[11],result[12], result[13], result[14], result[15]]; |
| 302 | } | 301 | } |
| 303 | 302 | ||
| 304 | -+ (NSString *)responseHeader:(NSString *)header fromHeaders:(NSDictionary *)headers | ||
| 305 | -{ | ||
| 306 | - for (NSString *responseHeader in headers) { | ||
| 307 | - if ([[responseHeader lowercaseString] isEqualToString:header]) { | ||
| 308 | - return [headers objectForKey:responseHeader]; | ||
| 309 | - } | ||
| 310 | - } | ||
| 311 | - return nil; | ||
| 312 | -} | ||
| 313 | 303 | ||
| 314 | @synthesize storagePath; | 304 | @synthesize storagePath; |
| 315 | @synthesize defaultCachePolicy; | 305 | @synthesize defaultCachePolicy; |
| @@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | // Automatically set on build | 25 | // Automatically set on build |
| 26 | -NSString *ASIHTTPRequestVersion = @"v1.6.2-13 2010-05-03"; | 26 | +NSString *ASIHTTPRequestVersion = @"v1.6.2-14 2010-05-03"; |
| 27 | 27 | ||
| 28 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; | 28 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; |
| 29 | 29 | ||
| @@ -812,6 +812,21 @@ static id <ASICacheDelegate> defaultCache = nil; | @@ -812,6 +812,21 @@ static id <ASICacheDelegate> defaultCache = nil; | ||
| 812 | [[self cancelledLock] unlock]; | 812 | [[self cancelledLock] unlock]; |
| 813 | return; | 813 | return; |
| 814 | } | 814 | } |
| 815 | + } else if ([self cachePolicy] == ASIReloadIfDifferentCachePolicy) { | ||
| 816 | + | ||
| 817 | + // Force a conditional GET if we have a cached version of this content already | ||
| 818 | + NSDictionary *cachedHeaders = [[self downloadCache] cachedHeadersForRequest:self]; | ||
| 819 | + if (cachedHeaders) { | ||
| 820 | + NSString *etag = [cachedHeaders objectForKey:@"Etag"]; | ||
| 821 | + if (etag) { | ||
| 822 | + [[self requestHeaders] setObject:etag forKey:@"If-None-Match"]; | ||
| 823 | + } else { | ||
| 824 | + NSString *lastModified = [cachedHeaders objectForKey:@"Last-Modified"]; | ||
| 825 | + if (lastModified) { | ||
| 826 | + [[self requestHeaders] setObject:lastModified forKey:@"If-Modified-Since"]; | ||
| 827 | + } | ||
| 828 | + } | ||
| 829 | + } | ||
| 815 | } | 830 | } |
| 816 | } | 831 | } |
| 817 | 832 |
-
Please register or login to post a comment