iOS web browser with a focus on security and privacy
at remove_ckhttpconnection 100 lines 2.5 kB view raw
1/* 2 * Endless 3 * Copyright (c) 2014-2015 joshua stein <jcs@jcs.org> 4 * 5 * See LICENSE file for redistribution terms. 6 */ 7 8#import "URLBlocker.h" 9 10@implementation URLBlocker 11 12static NSDictionary *_targets; 13static NSCache *ruleCache; 14 15#define RULE_CACHE_SIZE 20 16 17+ (NSDictionary *)targets 18{ 19 if (_targets == nil) { 20 NSString *path = [[NSBundle mainBundle] pathForResource:@"urlblocker_targets" ofType:@"plist"]; 21 if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { 22 NSLog(@"[URLBlocker] no target plist at %@", path); 23 abort(); 24 } 25 26 _targets = [NSDictionary dictionaryWithContentsOfFile:path]; 27 28#ifdef TRACE_URL_BLOCKER 29 NSLog(@"[URLBlocker] locked and loaded with %lu target domains", [_targets count]); 30#endif 31 } 32 33 return _targets; 34} 35 36+ (void)cacheBlockedURL:(NSURL *)url withRule:(NSString *)rule 37{ 38 if (!ruleCache) { 39 ruleCache = [[NSCache alloc] init]; 40 [ruleCache setCountLimit:RULE_CACHE_SIZE]; 41 } 42 43 [ruleCache setObject:rule forKey:url]; 44} 45 46+ (NSString *)blockRuleForURL:(NSURL *)url 47{ 48 NSString *blocker; 49 50 if (!(ruleCache && (blocker = [ruleCache objectForKey:url]))) { 51 NSString *host = [[url host] lowercaseString]; 52 53 blocker = [[[self class] targets] objectForKey:host]; 54 55 if (!blocker) { 56 /* now for x.y.z.example.com, try *.y.z.example.com, *.z.example.com, *.example.com, etc. */ 57 /* TODO: should we skip the last component for obviously non-matching things like "*.com", "*.net"? */ 58 NSArray *hostp = [host componentsSeparatedByString:@"."]; 59 for (int i = 1; i < [hostp count]; i++) { 60 NSString *wc = [[hostp subarrayWithRange:NSMakeRange(i, [hostp count] - i)] componentsJoinedByString:@"."]; 61 62 if ((blocker = [[[self class] targets] objectForKey:wc]) != nil) { 63 break; 64 } 65 } 66 } 67 } 68 69 if (blocker) { 70 [[self class] cacheBlockedURL:url withRule:blocker]; 71 } 72 73 return blocker; 74} 75 76+ (BOOL)shouldBlockURL:(NSURL *)url 77{ 78 return ([self blockRuleForURL:url] != nil); 79} 80 81+ (BOOL)shouldBlockURL:(NSURL *)url fromMainDocumentURL:(NSURL *)mainUrl 82{ 83 NSString *blocker = [self blockRuleForURL:url]; 84 if (blocker != nil && mainUrl != nil) { 85 /* if this same rule would have blocked our main URL, allow it since the user is probably viewing this site and this isn't a sneaky tracker */ 86 if ([blocker isEqualToString:[self blockRuleForURL:mainUrl]]) { 87 return NO; 88 } 89 90#ifdef TRACE_URL_BLOCKER 91 NSLog(@"[URLBlocker] blocking %@ (via %@) (%@)", url, mainUrl, blocker); 92#endif 93 94 return YES; 95 } 96 97 return NO; 98} 99 100@end