Showing
5 changed files
with
71 additions
and
1 deletions
@@ -109,6 +109,8 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | @@ -109,6 +109,8 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | ||
109 | if ([request isResponseCompressed]) { | 109 | if ([request isResponseCompressed]) { |
110 | [responseHeaders removeObjectForKey:@"Content-Encoding"]; | 110 | [responseHeaders removeObjectForKey:@"Content-Encoding"]; |
111 | } | 111 | } |
112 | + // We use this special key to help expire the request when we get a max-age header | ||
113 | + [responseHeaders setObject:[NSDate date] forKey:@"X-ASIHTTPRequest-Fetch-date"]; | ||
112 | [responseHeaders writeToFile:metadataPath atomically:NO]; | 114 | [responseHeaders writeToFile:metadataPath atomically:NO]; |
113 | 115 | ||
114 | if ([request responseData]) { | 116 | if ([request responseData]) { |
@@ -182,12 +184,38 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | @@ -182,12 +184,38 @@ static NSString *permanentCacheFolder = @"PermanentStore"; | ||
182 | if (!dataPath) { | 184 | if (!dataPath) { |
183 | return NO; | 185 | return NO; |
184 | } | 186 | } |
187 | + // If the Etag or Last-Modified date are different from the one we have, fetch the document again | ||
185 | NSArray *headersToCompare = [NSArray arrayWithObjects:@"etag",@"last-modified",nil]; | 188 | NSArray *headersToCompare = [NSArray arrayWithObjects:@"etag",@"last-modified",nil]; |
186 | for (NSString *header in headersToCompare) { | 189 | for (NSString *header in headersToCompare) { |
187 | if (![[[self class] responseHeader:header fromHeaders:[request responseHeaders]] isEqualToString:[[self class] responseHeader:header fromHeaders:cachedHeaders]]) { | 190 | if (![[[self class] responseHeader:header fromHeaders:[request responseHeaders]] isEqualToString:[[self class] responseHeader:header fromHeaders:cachedHeaders]]) { |
188 | return NO; | 191 | return NO; |
189 | } | 192 | } |
190 | } | 193 | } |
194 | + if (![self shouldRespectCacheControlHeaders]) { | ||
195 | + return YES; | ||
196 | + } | ||
197 | + // Look for an Expires header to see if the content is out of data | ||
198 | + NSString *expires = [[self class] responseHeader:@"expires" fromHeaders:cachedHeaders]; | ||
199 | + if (expires) { | ||
200 | + if ([[ASIHTTPRequest dateFromRFC1123String:expires] timeIntervalSinceNow] < 0) { | ||
201 | + return NO; | ||
202 | + } | ||
203 | + } | ||
204 | + // Look for a max-age header | ||
205 | + NSString *cacheControl = [[[self class] responseHeader:@"cache-control" fromHeaders:cachedHeaders] lowercaseString]; | ||
206 | + if (cacheControl) { | ||
207 | + NSScanner *scanner = [NSScanner scannerWithString:cacheControl]; | ||
208 | + if ([scanner scanString:@"max-age" intoString:NULL]) { | ||
209 | + [scanner scanString:@"=" intoString:NULL]; | ||
210 | + NSTimeInterval maxAge = 0; | ||
211 | + [scanner scanDouble:&maxAge]; | ||
212 | + NSDate *fetchDate = [[cachedHeaders objectForKey:@"X-ASIHTTPRequest-Fetch-date"] dateValue]; | ||
213 | + NSDate *expiryDate = [fetchDate addTimeInterval:maxAge]; | ||
214 | + if ([expiryDate timeIntervalSinceNow] < 0) { | ||
215 | + return NO; | ||
216 | + } | ||
217 | + } | ||
218 | + } | ||
191 | return YES; | 219 | return YES; |
192 | } | 220 | } |
193 | 221 |
@@ -702,6 +702,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -702,6 +702,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
702 | // And also by ASIS3Request | 702 | // And also by ASIS3Request |
703 | + (NSString *)base64forData:(NSData *)theData; | 703 | + (NSString *)base64forData:(NSData *)theData; |
704 | 704 | ||
705 | +// Returns a date from a string in RFC1123 format | ||
706 | ++ (NSDate *)dateFromRFC1123String:(NSString *)string; | ||
707 | + | ||
705 | #pragma mark === | 708 | #pragma mark === |
706 | 709 | ||
707 | @property (retain) NSString *username; | 710 | @property (retain) NSString *username; |
@@ -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-12 2010-05-03"; | 26 | +NSString *ASIHTTPRequestVersion = @"v1.6.2-13 2010-05-03"; |
27 | 27 | ||
28 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; | 28 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; |
29 | 29 | ||
@@ -3780,6 +3780,25 @@ static id <ASICacheDelegate> defaultCache = nil; | @@ -3780,6 +3780,25 @@ static id <ASICacheDelegate> defaultCache = nil; | ||
3780 | return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease]; | 3780 | return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease]; |
3781 | } | 3781 | } |
3782 | 3782 | ||
3783 | +// Based on hints from http://stackoverflow.com/questions/1850824/parsing-a-rfc-822-date-with-nsdateformatter | ||
3784 | ++ (NSDate *)dateFromRFC1123String:(NSString *)string | ||
3785 | +{ | ||
3786 | + NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease]; | ||
3787 | + [formatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]]; | ||
3788 | + // Does the string include a week day? | ||
3789 | + NSString *day = @""; | ||
3790 | + if ([string rangeOfString:@","].location != NSNotFound) { | ||
3791 | + day = @"EEE, "; | ||
3792 | + } | ||
3793 | + // Does the string include seconds? | ||
3794 | + NSString *seconds = @""; | ||
3795 | + if ([[string componentsSeparatedByString:@":"] count] == 3) { | ||
3796 | + seconds = @":ss"; | ||
3797 | + } | ||
3798 | + [formatter setDateFormat:[NSString stringWithFormat:@"%@dd MMM yyyy HH:mm%@ z",day,seconds]]; | ||
3799 | + return [formatter dateFromString:string]; | ||
3800 | +} | ||
3801 | + | ||
3783 | #pragma mark === | 3802 | #pragma mark === |
3784 | 3803 | ||
3785 | @synthesize username; | 3804 | @synthesize username; |
@@ -1579,5 +1579,25 @@ | @@ -1579,5 +1579,25 @@ | ||
1579 | [[self responseData] appendData:data]; | 1579 | [[self responseData] appendData:data]; |
1580 | } | 1580 | } |
1581 | 1581 | ||
1582 | +- (void)testRFC1123DateParsing | ||
1583 | +{ | ||
1584 | + unsigned dateUnits = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit; | ||
1585 | + NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; | ||
1586 | + [calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]; | ||
1587 | + NSString *dateString = @"Thu, 19 Nov 1981 08:52:01 GMT"; | ||
1588 | + NSDate *date = [ASIHTTPRequest dateFromRFC1123String:dateString]; | ||
1589 | + NSDateComponents *components = [calendar components:dateUnits fromDate:date]; | ||
1590 | + NSLog(@"%i",[components weekday]); | ||
1591 | + BOOL success = ([components year] == 1981 && [components month] == 11 && [components day] == 19 && [components weekday] == 5 && [components hour] == 8 && [components minute] == 52 && [components second] == 1); | ||
1592 | + GHAssertTrue(success,@"Failed to parse an RFC1123 date correctly"); | ||
1593 | + | ||
1594 | + dateString = @"4 May 2010 00:59 CET"; | ||
1595 | + date = [ASIHTTPRequest dateFromRFC1123String:dateString]; | ||
1596 | + components = [calendar components:dateUnits fromDate:date]; | ||
1597 | + success = ([components year] == 2010 && [components month] == 5 && [components day] == 3 && [components hour] == 23 && [components minute] == 59); | ||
1598 | + GHAssertTrue(success,@"Failed to parse an RFC1123 date correctly"); | ||
1599 | + | ||
1600 | +} | ||
1601 | + | ||
1582 | @synthesize responseData; | 1602 | @synthesize responseData; |
1583 | @end | 1603 | @end |
This diff was suppressed by a .gitattributes entry.
-
Please register or login to post a comment