Ben Copsey

ASIDownloadCache now stores files with extensions for common web scripting langu…

…ages with a .html extension
This will help users that need to cache HTML content for display in a webview
closes gh-241
... ... @@ -35,6 +35,10 @@
// A helper function that determines if the server has requested data should not be cached by looking at the request's response headers
+ (BOOL)serverAllowsResponseCachingForRequest:(ASIHTTPRequest *)request;
// A list of file extensions that we know won't be readable by a webview when accessed locally
// If we're asking for a path to cache a particular url and it has one of these extensions, we change it to '.html'
+ (NSArray *)fileExtensionsToHandleAsHTML;
@property (assign, nonatomic) ASICachePolicy defaultCachePolicy;
@property (retain, nonatomic) NSString *storagePath;
@property (retain) NSRecursiveLock *accessLock;
... ...
... ... @@ -14,6 +14,7 @@ static ASIDownloadCache *sharedCache = nil;
static NSString *sessionCacheFolder = @"SessionStore";
static NSString *permanentCacheFolder = @"PermanentStore";
static NSArray *fileExtensionsToHandleAsHTML = nil;
@interface ASIDownloadCache ()
+ (NSString *)keyForURL:(NSURL *)url;
... ... @@ -22,6 +23,15 @@ static NSString *permanentCacheFolder = @"PermanentStore";
@implementation ASIDownloadCache
+ (void)initialize
{
if (self == [ASIDownloadCache class]) {
// Obviously this is not an exhaustive list, but hopefully these are the most commonly used and this will 'just work' for the widest range of people
// I imagine many web developers probably use url rewriting anyway
fileExtensionsToHandleAsHTML = [[NSArray alloc] initWithObjects:@"asp",@"aspx",@"jsp",@"php",@"rb",@"py",@"pl",@"cgi", nil];
}
}
- (id)init
{
self = [super init];
... ... @@ -193,12 +203,21 @@ static NSString *permanentCacheFolder = @"PermanentStore";
{
// Grab the file extension, if there is one. We do this so we can save the cached response with the same file extension - this is important if you want to display locally cached data in a web view
NSString *extension = [[url path] pathExtension];
if (![extension length]) {
// If the url doesn't have an extension, we'll add one so a webview can read it when locally cached
// If the url has the extension of a common web scripting language, we'll change the extension on the cached path to html for the same reason
if (![extension length] || [[[self class] fileExtensionsToHandleAsHTML] containsObject:[extension lowercaseString]]) {
extension = @"html";
}
return [self pathToFile:[[[self class] keyForURL:url] stringByAppendingPathExtension:extension]];
}
+ (NSArray *)fileExtensionsToHandleAsHTML
{
return fileExtensionsToHandleAsHTML;
}
- (NSString *)pathToCachedResponseHeadersForURL:(NSURL *)url
{
return [self pathToFile:[[[self class] keyForURL:url] stringByAppendingPathExtension:@"cachedheaders"]];
... ... @@ -243,7 +262,10 @@ static NSString *permanentCacheFolder = @"PermanentStore";
// Grab the file extension, if there is one. We do this so we can save the cached response with the same file extension - this is important if you want to display locally cached data in a web view
NSString *extension = [[[request url] path] pathExtension];
if (![extension length]) {
// If the url doesn't have an extension, we'll add one so a webview can read it when locally cached
// If the url has the extension of a common web scripting language, we'll change the extension on the cached path to html for the same reason
if (![extension length] || [[[self class] fileExtensionsToHandleAsHTML] containsObject:[extension lowercaseString]]) {
extension = @"html";
}
path = [path stringByAppendingPathComponent:[[[self class] keyForURL:[request url]] stringByAppendingPathExtension:extension]];
... ...
... ... @@ -24,7 +24,7 @@
#import "ASIDataCompressor.h"
// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.8.1-27 2011-08-07";
NSString *ASIHTTPRequestVersion = @"v1.8.1-28 2011-08-20";
static NSString *defaultUserAgent = nil;
... ... @@ -4026,7 +4026,6 @@ static NSOperationQueue *sharedQueue = nil;
}
#pragma mark NSCopying
- (id)copyWithZone:(NSZone *)zone
{
// Don't forget - this will return a retained copy!
... ... @@ -4420,6 +4419,7 @@ static NSOperationQueue *sharedQueue = nil;
}
return [[defaultUserAgent retain] autorelease];
}
return nil;
}
+ (void)setDefaultUserAgentString:(NSString *)agent
... ... @@ -4690,6 +4690,7 @@ static NSOperationQueue *sharedQueue = nil;
@synchronized(self) {
return [[defaultCache retain] autorelease];
}
return nil;
}
... ...
... ... @@ -298,6 +298,30 @@
GHAssertTrue(success,@"Failed to use cached response");
}
- (void)testExtensionHandling
{
NSArray *extensions = [ASIDownloadCache fileExtensionsToHandleAsHTML];
for (NSString *extension in extensions) {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://allseeing-i.com/file.%@",extension]];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
NSString *path = [[ASIDownloadCache sharedCache] pathToStoreCachedResponseDataForRequest:request];
BOOL success = [[path pathExtension] isEqualToString:@"html"];
GHAssertTrue(success, @"Failed to use html extension on cached path for a resource we know a webview won't be able to open locally");
}
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
NSString *path = [[ASIDownloadCache sharedCache] pathToStoreCachedResponseDataForRequest:request];
BOOL success = [[path pathExtension] isEqualToString:@"html"];
GHAssertTrue(success, @"Failed to use html extension on cached path for a url without an extension");
url = [NSURL URLWithString:@"http://allseeing-i.com/i/logo.png"];
request = [ASIHTTPRequest requestWithURL:url];
path = [[ASIDownloadCache sharedCache] pathToStoreCachedResponseDataForRequest:request];
success = [[path pathExtension] isEqualToString:@"png"];
GHAssertTrue(success, @"Failed to preserve file extension on cached path");
}
- (void)testCustomExpiry
{
[[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICacheForSessionDurationCacheStoragePolicy];
... ...