Allow Timeout caching and ETag caching to play nice with each other. Update the internal cache date when we get a 304 back.

This commit is contained in:
Jeremy Ellison
2011-06-28 11:44:55 -04:00
committed by Blake Watters
parent 67a6df359d
commit eea75bdb3c
5 changed files with 88 additions and 12 deletions

View File

@@ -439,6 +439,12 @@
}
}
- (void)updateInternalCacheDate {
NSDate* date = [NSDate date];
RKLogInfo(@"Updating cache date for request %@ to %@", self, date);
[self.cache setCacheDate:date forRequest:self];
}
- (void)didFinishLoad:(RKResponse*)response {
_isLoading = NO;
_isLoaded = YES;
@@ -450,6 +456,7 @@
if ((_cachePolicy & RKRequestCachePolicyEtag) && [response isNotModified]) {
finalResponse = [self loadResponseFromCache];
[self updateInternalCacheDate];
}
if (![response wasLoadedFromCache] && [response isSuccessful] && (_cachePolicy != RKRequestCachePolicyNone)) {
@@ -535,7 +542,8 @@
if (_method == RKRequestMethodDELETE) {
return nil;
}
NSString* compositCacheKey = [NSString stringWithFormat:@"%@-%d-%@", self.URL, _method, [_URLRequest HTTPBody]];
// Use [_params HTTPBody] because the URLRequest body may not have been set up yet.
NSString* compositCacheKey = [NSString stringWithFormat:@"%@-%d-%@", self.URL, _method, [_params HTTPBody]];
return [compositCacheKey MD5];
}

View File

@@ -50,6 +50,8 @@ typedef enum {
- (NSDate*)cacheDateForRequest:(RKRequest*)request;
- (void)setCacheDate:(NSDate*)date forRequest:(RKRequest*)request;
- (void)invalidateRequest:(RKRequest*)request;
- (void)invalidateWithStoragePolicy:(RKRequestCacheStoragePolicy)storagePolicy;

View File

@@ -128,6 +128,19 @@ static NSDateFormatter* __rfc1123DateFormatter;
return hasEntryForRequest;
}
- (void)writeHeaders:(NSDictionary*)headers toCachePath:(NSString*)cachePath {
RKLogTrace(@"Writing headers to cache path: '%@'", cachePath);
BOOL success = [headers writeToFile:[cachePath
stringByAppendingPathExtension:headersExtension]
atomically:YES];
if (success) {
RKLogTrace(@"Wrote cached response header to path '%@'", cachePath);
} else {
RKLogError(@"Failed to write cached response headers to path '%@'", cachePath);
}
}
- (void)storeResponse:(RKResponse*)response forRequest:(RKRequest*)request {
[_cacheLock lock];
@@ -166,15 +179,7 @@ static NSDateFormatter* __rfc1123DateFormatter;
[headers setObject:[urlResponse.URL absoluteString]
forKey:cacheURLKey];
// Save
BOOL success = [headers writeToFile:[cachePath
stringByAppendingPathExtension:headersExtension]
atomically:YES];
if (success) {
RKLogTrace(@"Wrote cached response header to path '%@'", cachePath);
} else {
RKLogError(@"Failed to write cached response headers to path '%@'", cachePath);
}
[self writeHeaders:headers toCachePath:cachePath];
}
[headers release];
@@ -245,6 +250,16 @@ static NSDateFormatter* __rfc1123DateFormatter;
return etag;
}
- (void)setCacheDate:(NSDate*)date forRequest:(RKRequest*)request {
NSMutableDictionary* responseHeaders = [[self headersForRequest:request] mutableCopy];
[responseHeaders setObject:[[RKRequestCache rfc1123DateFormatter] stringFromDate:date]
forKey:cacheDateHeaderKey];
[self writeHeaders:responseHeaders toCachePath:[self pathForRequest:request]];
[responseHeaders release];
}
- (NSDate*)cacheDateForRequest:(RKRequest*)request {
NSDate* date;
NSString* dateString;

View File

@@ -22,6 +22,10 @@
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetwork
@interface RKRequest (Private)
- (void)updateInternalCacheDate;
@end
@implementation RKObjectLoader
@synthesize objectManager = _objectManager, response = _response;
@@ -321,6 +325,7 @@
[_response release];
_response = nil;
_response = [[[[RKClient sharedClient] cache] responseForRequest:self] retain];
[self updateInternalCacheDate];
}
if (![_response wasLoadedFromCache] && [_response isSuccessful] && (_cachePolicy != RKRequestCachePolicyNone)) {

View File

@@ -286,6 +286,54 @@
}
}
- (void)itShouldUpdateTheInternalCacheDateWhenWeRecieveA304 {
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
NSString* baseURL = RKSpecGetBaseURL();
NSString* cacheDirForClient = [NSString stringWithFormat:@"RKClientRequestCache-%@",
[[NSURL URLWithString:baseURL] host]];
NSString* cachePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]
stringByAppendingPathComponent:cacheDirForClient];
RKRequestCache* cache = [[RKRequestCache alloc] initWithCachePath:cachePath
storagePolicy:RKRequestCacheStoragePolicyPermanently];
[cache invalidateWithStoragePolicy:RKRequestCacheStoragePolicyPermanently];
NSDate* internalCacheDate1;
NSDate* internalCacheDate2;
{
RKSpecResponseLoader* loader = [RKSpecResponseLoader responseLoader];
NSString* url = [NSString stringWithFormat:@"%@/etags/cached", RKSpecGetBaseURL()];
NSURL* URL = [NSURL URLWithString:url];
RKRequest* request = [[RKRequest alloc] initWithURL:URL];
request.cachePolicy = RKRequestCachePolicyEtag;
request.cache = cache;
request.delegate = loader;
[request sendAsynchronously];
[loader waitForResponse];
[expectThat([loader success]) should:be(YES)];
[expectThat([loader.response bodyAsString]) should:be(@"This Should Get Cached")];
[expectThat([cache etagForRequest:request]) should:be(@"686897696a7c876b7e")];
[expectThat([loader.response wasLoadedFromCache]) should:be(NO)];
internalCacheDate1 = [cache cacheDateForRequest:request];
}
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.5]];
{
RKSpecResponseLoader* loader = [RKSpecResponseLoader responseLoader];
NSString* url = [NSString stringWithFormat:@"%@/etags/cached", RKSpecGetBaseURL()];
NSURL* URL = [NSURL URLWithString:url];
RKRequest* request = [[RKRequest alloc] initWithURL:URL];
request.cachePolicy = RKRequestCachePolicyEtag;
request.cache = cache;
request.delegate = loader;
[request sendAsynchronously];
[loader waitForResponse];
[expectThat([loader success]) should:be(YES)];
[expectThat([loader.response bodyAsString]) should:be(@"This Should Get Cached")];
[expectThat([loader.response wasLoadedFromCache]) should:be(YES)];
internalCacheDate2 = [cache cacheDateForRequest:request];
}
[expectThat(internalCacheDate1) shouldNot:be(internalCacheDate2)];
}
- (void)itShouldLoadFromTheCacheIfThereIsAnError {
NSString* baseURL = RKSpecGetBaseURL();
NSString* cacheDirForClient = [NSString stringWithFormat:@"RKClientRequestCache-%@",
@@ -325,8 +373,6 @@
}
- (void)itShouldLoadFromTheCacheIfWeAreWithinTheTimeout {
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
NSString* baseURL = RKSpecGetBaseURL();
NSString* cacheDirForClient = [NSString stringWithFormat:@"RKClientRequestCache-%@",
[[NSURL URLWithString:baseURL] host]];