Ben Copsey

Parse expires / max-age headers

... ... @@ -109,6 +109,8 @@ static NSString *permanentCacheFolder = @"PermanentStore";
if ([request isResponseCompressed]) {
[responseHeaders removeObjectForKey:@"Content-Encoding"];
}
// We use this special key to help expire the request when we get a max-age header
[responseHeaders setObject:[NSDate date] forKey:@"X-ASIHTTPRequest-Fetch-date"];
[responseHeaders writeToFile:metadataPath atomically:NO];
if ([request responseData]) {
... ... @@ -182,12 +184,38 @@ static NSString *permanentCacheFolder = @"PermanentStore";
if (!dataPath) {
return NO;
}
// If the Etag or Last-Modified date are different from the one we have, fetch the document again
NSArray *headersToCompare = [NSArray arrayWithObjects:@"etag",@"last-modified",nil];
for (NSString *header in headersToCompare) {
if (![[[self class] responseHeader:header fromHeaders:[request responseHeaders]] isEqualToString:[[self class] responseHeader:header fromHeaders:cachedHeaders]]) {
return NO;
}
}
if (![self shouldRespectCacheControlHeaders]) {
return YES;
}
// Look for an Expires header to see if the content is out of data
NSString *expires = [[self class] responseHeader:@"expires" fromHeaders:cachedHeaders];
if (expires) {
if ([[ASIHTTPRequest dateFromRFC1123String:expires] timeIntervalSinceNow] < 0) {
return NO;
}
}
// Look for a max-age header
NSString *cacheControl = [[[self class] responseHeader:@"cache-control" fromHeaders:cachedHeaders] lowercaseString];
if (cacheControl) {
NSScanner *scanner = [NSScanner scannerWithString:cacheControl];
if ([scanner scanString:@"max-age" intoString:NULL]) {
[scanner scanString:@"=" intoString:NULL];
NSTimeInterval maxAge = 0;
[scanner scanDouble:&maxAge];
NSDate *fetchDate = [[cachedHeaders objectForKey:@"X-ASIHTTPRequest-Fetch-date"] dateValue];
NSDate *expiryDate = [fetchDate addTimeInterval:maxAge];
if ([expiryDate timeIntervalSinceNow] < 0) {
return NO;
}
}
}
return YES;
}
... ...
... ... @@ -702,6 +702,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
// And also by ASIS3Request
+ (NSString *)base64forData:(NSData *)theData;
// Returns a date from a string in RFC1123 format
+ (NSDate *)dateFromRFC1123String:(NSString *)string;
#pragma mark ===
@property (retain) NSString *username;
... ...
... ... @@ -23,7 +23,7 @@
// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.6.2-12 2010-05-03";
NSString *ASIHTTPRequestVersion = @"v1.6.2-13 2010-05-03";
NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain";
... ... @@ -3780,6 +3780,25 @@ static id <ASICacheDelegate> defaultCache = nil;
return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
}
// Based on hints from http://stackoverflow.com/questions/1850824/parsing-a-rfc-822-date-with-nsdateformatter
+ (NSDate *)dateFromRFC1123String:(NSString *)string
{
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
// Does the string include a week day?
NSString *day = @"";
if ([string rangeOfString:@","].location != NSNotFound) {
day = @"EEE, ";
}
// Does the string include seconds?
NSString *seconds = @"";
if ([[string componentsSeparatedByString:@":"] count] == 3) {
seconds = @":ss";
}
[formatter setDateFormat:[NSString stringWithFormat:@"%@dd MMM yyyy HH:mm%@ z",day,seconds]];
return [formatter dateFromString:string];
}
#pragma mark ===
@synthesize username;
... ...
... ... @@ -1579,5 +1579,25 @@
[[self responseData] appendData:data];
}
- (void)testRFC1123DateParsing
{
unsigned dateUnits = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit;
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
NSString *dateString = @"Thu, 19 Nov 1981 08:52:01 GMT";
NSDate *date = [ASIHTTPRequest dateFromRFC1123String:dateString];
NSDateComponents *components = [calendar components:dateUnits fromDate:date];
NSLog(@"%i",[components weekday]);
BOOL success = ([components year] == 1981 && [components month] == 11 && [components day] == 19 && [components weekday] == 5 && [components hour] == 8 && [components minute] == 52 && [components second] == 1);
GHAssertTrue(success,@"Failed to parse an RFC1123 date correctly");
dateString = @"4 May 2010 00:59 CET";
date = [ASIHTTPRequest dateFromRFC1123String:dateString];
components = [calendar components:dateUnits fromDate:date];
success = ([components year] == 2010 && [components month] == 5 && [components day] == 3 && [components hour] == 23 && [components minute] == 59);
GHAssertTrue(success,@"Failed to parse an RFC1123 date correctly");
}
@synthesize responseData;
@end
\ No newline at end of file
... ...
This diff was suppressed by a .gitattributes entry.