Update Google+ integration.
[UPDATED] Google+ SDK to 1.1.0.
This commit is contained in:
@@ -40,10 +40,10 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// add all cookies in the new cookie array to the storage,
|
||||
// replacing stored cookies as appropriate
|
||||
// Add all cookies in the new cookie array to the storage,
|
||||
// replacing stored cookies as appropriate.
|
||||
//
|
||||
// Side effect: removes expired cookies from the storage array
|
||||
// Side effect: removes expired cookies from the storage array.
|
||||
- (void)setCookies:(NSArray *)newCookies {
|
||||
|
||||
@synchronized(cookies_) {
|
||||
@@ -82,9 +82,9 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
}
|
||||
}
|
||||
|
||||
// retrieve all cookies appropriate for the given URL, considering
|
||||
// Retrieve all cookies appropriate for the given URL, considering
|
||||
// domain, path, cookie name, expiration, security setting.
|
||||
// Side effect: removed expired cookies from the storage array
|
||||
// Side effect: removed expired cookies from the storage array.
|
||||
- (NSArray *)cookiesForURL:(NSURL *)theURL {
|
||||
|
||||
NSMutableArray *foundCookies = nil;
|
||||
@@ -92,9 +92,9 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
@synchronized(cookies_) {
|
||||
[self removeExpiredCookies];
|
||||
|
||||
// we'll prepend "." to the desired domain, since we want the
|
||||
// We'll prepend "." to the desired domain, since we want the
|
||||
// actual domain "nytimes.com" to still match the cookie domain
|
||||
// ".nytimes.com" when we check it below with hasSuffix
|
||||
// ".nytimes.com" when we check it below with hasSuffix.
|
||||
NSString *host = [[theURL host] lowercaseString];
|
||||
NSString *path = [theURL path];
|
||||
NSString *scheme = [theURL scheme];
|
||||
@@ -144,13 +144,13 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
return foundCookies;
|
||||
}
|
||||
|
||||
// return a cookie from the array with the same name, domain, and path as the
|
||||
// given cookie, or else return nil if none found
|
||||
// Return a cookie from the array with the same name, domain, and path as the
|
||||
// given cookie, or else return nil if none found.
|
||||
//
|
||||
// Both the cookie being tested and all cookies in the storage array should
|
||||
// be valid (non-nil name, domains, paths)
|
||||
// be valid (non-nil name, domains, paths).
|
||||
//
|
||||
// note: this should only be called from inside a @synchronized(cookies_) block
|
||||
// Note: this should only be called from inside a @synchronized(cookies_) block
|
||||
- (NSHTTPCookie *)cookieMatchingCookie:(NSHTTPCookie *)cookie {
|
||||
|
||||
NSUInteger numberOfCookies = [cookies_ count];
|
||||
@@ -176,10 +176,10 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
}
|
||||
|
||||
|
||||
// internal routine to remove any expired cookies from the array, excluding
|
||||
// cookies with nil expirations
|
||||
// Internal routine to remove any expired cookies from the array, excluding
|
||||
// cookies with nil expirations.
|
||||
//
|
||||
// note: this should only be called from inside a @synchronized(cookies_) block
|
||||
// Note: this should only be called from inside a @synchronized(cookies_) block
|
||||
- (void)removeExpiredCookies {
|
||||
|
||||
// count backwards since we're deleting items from the array
|
||||
@@ -281,18 +281,18 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
[self class], self, [responses_ allValues]];
|
||||
}
|
||||
|
||||
// setters/getters
|
||||
// Setters/getters
|
||||
|
||||
- (void)pruneCacheResponses {
|
||||
// internal routine to remove the least-recently-used responses when the
|
||||
// Internal routine to remove the least-recently-used responses when the
|
||||
// cache has grown too large
|
||||
if (memoryCapacity_ >= totalDataSize_) return;
|
||||
|
||||
// sort keys by date
|
||||
// Sort keys by date
|
||||
SEL sel = @selector(compareUseDate:);
|
||||
NSArray *sortedKeys = [responses_ keysSortedByValueUsingSelector:sel];
|
||||
|
||||
// the least-recently-used keys are at the beginning of the sorted array;
|
||||
// The least-recently-used keys are at the beginning of the sorted array;
|
||||
// remove those (except ones still reserved) until the total data size is
|
||||
// reduced sufficiently
|
||||
for (NSURL *key in sortedKeys) {
|
||||
@@ -303,13 +303,13 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
&& ([resDate timeIntervalSinceNow] > -reservationInterval_);
|
||||
|
||||
if (!isResponseReserved) {
|
||||
// we can remove this response from the cache
|
||||
// We can remove this response from the cache
|
||||
NSUInteger storedSize = [[response data] length];
|
||||
totalDataSize_ -= storedSize;
|
||||
[responses_ removeObjectForKey:key];
|
||||
}
|
||||
|
||||
// if we've removed enough response data, then we're done
|
||||
// If we've removed enough response data, then we're done
|
||||
if (memoryCapacity_ >= totalDataSize_) break;
|
||||
}
|
||||
}
|
||||
@@ -317,7 +317,7 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
- (void)storeCachedResponse:(GTMCachedURLResponse *)cachedResponse
|
||||
forRequest:(NSURLRequest *)request {
|
||||
@synchronized(self) {
|
||||
// remove any previous entry for this request
|
||||
// Remove any previous entry for this request
|
||||
[self removeCachedResponseForRequest:request];
|
||||
|
||||
// cache this one only if it's not bigger than our cache
|
||||
@@ -340,7 +340,7 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
NSURL *key = [request URL];
|
||||
response = [[[responses_ objectForKey:key] retain] autorelease];
|
||||
|
||||
// touch the date to indicate this was recently retrieved
|
||||
// Touch the date to indicate this was recently retrieved
|
||||
[response setUseDate:[NSDate date]];
|
||||
}
|
||||
return response;
|
||||
@@ -376,7 +376,7 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
}
|
||||
}
|
||||
|
||||
// methods for unit testing
|
||||
// Methods for unit testing.
|
||||
- (void)setReservationInterval:(NSTimeInterval)secs {
|
||||
reservationInterval_ = secs;
|
||||
}
|
||||
@@ -432,32 +432,34 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
}
|
||||
|
||||
- (void)updateRequest:(NSMutableURLRequest *)request isHTTPGet:(BOOL)isHTTPGet {
|
||||
if ([self shouldRememberETags]) {
|
||||
// If this URL is in the history, and no ETag has been set, then
|
||||
// set the ETag header field
|
||||
@synchronized(self) {
|
||||
if ([self shouldRememberETags]) {
|
||||
// If this URL is in the history, and no ETag has been set, then
|
||||
// set the ETag header field
|
||||
|
||||
// if we have a history, we're tracking across fetches, so we don't
|
||||
// want to pull results from any other cache
|
||||
[request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
|
||||
// If we have a history, we're tracking across fetches, so we don't
|
||||
// want to pull results from any other cache
|
||||
[request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
|
||||
|
||||
if (isHTTPGet) {
|
||||
// we'll only add an ETag if there's no ETag specified in the user's
|
||||
// request
|
||||
NSString *specifiedETag = [request valueForHTTPHeaderField:kGTMIfNoneMatchHeader];
|
||||
if (specifiedETag == nil) {
|
||||
// no ETag: extract the previous ETag for this request from the
|
||||
// fetch history, and add it to the request
|
||||
NSString *cachedETag = [self cachedETagForRequest:request];
|
||||
if (isHTTPGet) {
|
||||
// We'll only add an ETag if there's no ETag specified in the user's
|
||||
// request
|
||||
NSString *specifiedETag = [request valueForHTTPHeaderField:kGTMIfNoneMatchHeader];
|
||||
if (specifiedETag == nil) {
|
||||
// No ETag: extract the previous ETag for this request from the
|
||||
// fetch history, and add it to the request
|
||||
NSString *cachedETag = [self cachedETagForRequest:request];
|
||||
|
||||
if (cachedETag != nil) {
|
||||
[request addValue:cachedETag forHTTPHeaderField:kGTMIfNoneMatchHeader];
|
||||
if (cachedETag != nil) {
|
||||
[request addValue:cachedETag forHTTPHeaderField:kGTMIfNoneMatchHeader];
|
||||
}
|
||||
} else {
|
||||
// Has an ETag: remove any stored response in the fetch history
|
||||
// for this request, as the If-None-Match header could lead to
|
||||
// a 304 Not Modified, and we want that error delivered to the
|
||||
// user since they explicitly specified the ETag
|
||||
[self removeCachedDataForRequest:request];
|
||||
}
|
||||
} else {
|
||||
// has an ETag: remove any stored response in the fetch history
|
||||
// for this request, as the If-None-Match header could lead to
|
||||
// a 304 Not Modified, and we want that error delivered to the
|
||||
// user since they explicitly specified the ETag
|
||||
[self removeCachedDataForRequest:request];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -466,38 +468,41 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
- (void)updateFetchHistoryWithRequest:(NSURLRequest *)request
|
||||
response:(NSURLResponse *)response
|
||||
downloadedData:(NSData *)downloadedData {
|
||||
if (![self shouldRememberETags]) return;
|
||||
@synchronized(self) {
|
||||
if (![self shouldRememberETags]) return;
|
||||
|
||||
if (![response respondsToSelector:@selector(allHeaderFields)]) return;
|
||||
if (![response respondsToSelector:@selector(allHeaderFields)]) return;
|
||||
|
||||
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
|
||||
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
|
||||
|
||||
if (statusCode != kGTMHTTPFetcherStatusNotModified) {
|
||||
// save this ETag string for successful results (<300)
|
||||
// If there's no last modified string, clear the dictionary
|
||||
// entry for this URL. Also cache or delete the data, if appropriate
|
||||
// (when etaggedDataCache is non-nil.)
|
||||
NSDictionary *headers = [(NSHTTPURLResponse *)response allHeaderFields];
|
||||
NSString* etag = [headers objectForKey:kGTMETagHeader];
|
||||
if (statusCode != kGTMHTTPFetcherStatusNotModified) {
|
||||
// Save this ETag string for successful results (<300)
|
||||
// If there's no last modified string, clear the dictionary
|
||||
// entry for this URL. Also cache or delete the data, if appropriate
|
||||
// (when etaggedDataCache is non-nil.)
|
||||
NSDictionary *headers = [(NSHTTPURLResponse *)response allHeaderFields];
|
||||
NSString* etag = [headers objectForKey:kGTMETagHeader];
|
||||
|
||||
if (etag != nil && statusCode < 300) {
|
||||
if (etag != nil && statusCode < 300) {
|
||||
|
||||
// we want to cache responses for the headers, even if the client
|
||||
// doesn't want the response body data caches
|
||||
NSData *dataToStore = shouldCacheETaggedData_ ? downloadedData : nil;
|
||||
// we want to cache responses for the headers, even if the client
|
||||
// doesn't want the response body data caches
|
||||
NSData *dataToStore = shouldCacheETaggedData_ ? downloadedData : nil;
|
||||
|
||||
GTMCachedURLResponse *cachedResponse;
|
||||
cachedResponse = [[[GTMCachedURLResponse alloc] initWithResponse:response
|
||||
data:dataToStore] autorelease];
|
||||
[etaggedDataCache_ storeCachedResponse:cachedResponse
|
||||
forRequest:request];
|
||||
} else {
|
||||
[etaggedDataCache_ removeCachedResponseForRequest:request];
|
||||
GTMCachedURLResponse *cachedResponse;
|
||||
cachedResponse = [[[GTMCachedURLResponse alloc] initWithResponse:response
|
||||
data:dataToStore] autorelease];
|
||||
[etaggedDataCache_ storeCachedResponse:cachedResponse
|
||||
forRequest:request];
|
||||
} else {
|
||||
[etaggedDataCache_ removeCachedResponseForRequest:request];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)cachedETagForRequest:(NSURLRequest *)request {
|
||||
// Internal routine.
|
||||
GTMCachedURLResponse *cachedResponse;
|
||||
cachedResponse = [etaggedDataCache_ cachedResponseForRequest:request];
|
||||
|
||||
@@ -505,46 +510,56 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
NSDictionary *headers = [(NSHTTPURLResponse *)response allHeaderFields];
|
||||
NSString *cachedETag = [headers objectForKey:kGTMETagHeader];
|
||||
if (cachedETag) {
|
||||
// since the request having an ETag implies this request is about
|
||||
// Since the request having an ETag implies this request is about
|
||||
// to be fetched again, reserve the cached response to ensure that
|
||||
// that it will be around at least until the fetch completes
|
||||
// that it will be around at least until the fetch completes.
|
||||
//
|
||||
// when the fetch completes, either the cached response will be replaced
|
||||
// When the fetch completes, either the cached response will be replaced
|
||||
// with a new response, or the cachedDataForRequest: method below will
|
||||
// clear the reservation
|
||||
// clear the reservation.
|
||||
[cachedResponse setReservationDate:[NSDate date]];
|
||||
}
|
||||
return cachedETag;
|
||||
}
|
||||
|
||||
- (NSData *)cachedDataForRequest:(NSURLRequest *)request {
|
||||
GTMCachedURLResponse *cachedResponse;
|
||||
cachedResponse = [etaggedDataCache_ cachedResponseForRequest:request];
|
||||
@synchronized(self) {
|
||||
GTMCachedURLResponse *cachedResponse;
|
||||
cachedResponse = [etaggedDataCache_ cachedResponseForRequest:request];
|
||||
|
||||
NSData *cachedData = [cachedResponse data];
|
||||
NSData *cachedData = [cachedResponse data];
|
||||
|
||||
// since the data for this cached request is being obtained from the cache,
|
||||
// we can clear the reservation as the fetch has completed
|
||||
[cachedResponse setReservationDate:nil];
|
||||
// Since the data for this cached request is being obtained from the cache,
|
||||
// we can clear the reservation as the fetch has completed.
|
||||
[cachedResponse setReservationDate:nil];
|
||||
|
||||
return cachedData;
|
||||
return cachedData;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeCachedDataForRequest:(NSURLRequest *)request {
|
||||
[etaggedDataCache_ removeCachedResponseForRequest:request];
|
||||
@synchronized(self) {
|
||||
[etaggedDataCache_ removeCachedResponseForRequest:request];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearETaggedDataCache {
|
||||
[etaggedDataCache_ removeAllCachedResponses];
|
||||
@synchronized(self) {
|
||||
[etaggedDataCache_ removeAllCachedResponses];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearHistory {
|
||||
[self clearETaggedDataCache];
|
||||
[cookieStorage_ removeAllCookies];
|
||||
@synchronized(self) {
|
||||
[self clearETaggedDataCache];
|
||||
[cookieStorage_ removeAllCookies];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeAllCookies {
|
||||
[cookieStorage_ removeAllCookies];
|
||||
@synchronized(self) {
|
||||
[cookieStorage_ removeAllCookies];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldRememberETags {
|
||||
@@ -556,7 +571,7 @@ static NSString* const kGTMETagHeader = @"Etag";
|
||||
shouldRememberETags_ = flag;
|
||||
|
||||
if (wasRemembering && !flag) {
|
||||
// free up the cache memory
|
||||
// Free up the cache memory
|
||||
[self clearETaggedDataCache];
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user