Showing
4 changed files
with
95 additions
and
5 deletions
| @@ -275,6 +275,8 @@ extern NSString* const NetworkRequestErrorDomain; | @@ -275,6 +275,8 @@ extern NSString* const NetworkRequestErrorDomain; | ||
| 275 | // Details on the proxy to use - you could set these yourself, but it's probably best to let ASIHTTPRequest detect the system proxy settings | 275 | // Details on the proxy to use - you could set these yourself, but it's probably best to let ASIHTTPRequest detect the system proxy settings |
| 276 | NSString *proxyHost; | 276 | NSString *proxyHost; |
| 277 | int proxyPort; | 277 | int proxyPort; |
| 278 | + | ||
| 279 | + NSURL *PACurl; | ||
| 278 | } | 280 | } |
| 279 | 281 | ||
| 280 | #pragma mark init / dealloc | 282 | #pragma mark init / dealloc |
| @@ -437,6 +439,11 @@ extern NSString* const NetworkRequestErrorDomain; | @@ -437,6 +439,11 @@ extern NSString* const NetworkRequestErrorDomain; | ||
| 437 | // Is only used when you have specified a Bundle Display Name (CFDisplayBundleName) or Bundle Name (CFBundleName) in your plist | 439 | // Is only used when you have specified a Bundle Display Name (CFDisplayBundleName) or Bundle Name (CFBundleName) in your plist |
| 438 | + (NSString *)defaultUserAgentString; | 440 | + (NSString *)defaultUserAgentString; |
| 439 | 441 | ||
| 442 | +#pragma mark proxy autoconfiguration | ||
| 443 | + | ||
| 444 | +// Returns an array of proxies to use for a particular url, given the url of a PAC script | ||
| 445 | ++ (NSArray *)proxiesForURL:(NSURL *)theURL fromPAC:(NSURL *)pacScriptURL; | ||
| 446 | + | ||
| 440 | @property (retain) NSString *username; | 447 | @property (retain) NSString *username; |
| 441 | @property (retain) NSString *password; | 448 | @property (retain) NSString *password; |
| 442 | @property (retain) NSString *domain; | 449 | @property (retain) NSString *domain; |
| @@ -495,4 +502,6 @@ extern NSString* const NetworkRequestErrorDomain; | @@ -495,4 +502,6 @@ extern NSString* const NetworkRequestErrorDomain; | ||
| 495 | @property (assign) BOOL shouldRedirect; | 502 | @property (assign) BOOL shouldRedirect; |
| 496 | @property (assign) BOOL validatesSecureCertificate; | 503 | @property (assign) BOOL validatesSecureCertificate; |
| 497 | @property (assign) BOOL shouldCompressRequestBody; | 504 | @property (assign) BOOL shouldCompressRequestBody; |
| 505 | +@property (assign) BOOL needsProxyAuthentication; | ||
| 506 | +@property (retain) NSURL *PACurl; | ||
| 498 | @end | 507 | @end |
| @@ -76,7 +76,6 @@ static NSError *ASITooMuchRedirectionError; | @@ -76,7 +76,6 @@ static NSError *ASITooMuchRedirectionError; | ||
| 76 | @property (retain, nonatomic) NSOutputStream *fileDownloadOutputStream; | 76 | @property (retain, nonatomic) NSOutputStream *fileDownloadOutputStream; |
| 77 | @property (assign, nonatomic) int authenticationRetryCount; | 77 | @property (assign, nonatomic) int authenticationRetryCount; |
| 78 | @property (assign, nonatomic) int proxyAuthenticationRetryCount; | 78 | @property (assign, nonatomic) int proxyAuthenticationRetryCount; |
| 79 | -@property (assign, nonatomic) BOOL needsProxyAuthentication; | ||
| 80 | @property (assign, nonatomic) BOOL updatedProgress; | 79 | @property (assign, nonatomic) BOOL updatedProgress; |
| 81 | @property (assign, nonatomic) BOOL needsRedirect; | 80 | @property (assign, nonatomic) BOOL needsRedirect; |
| 82 | @property (assign, nonatomic) int redirectCount; | 81 | @property (assign, nonatomic) int redirectCount; |
| @@ -518,9 +517,23 @@ static NSError *ASITooMuchRedirectionError; | @@ -518,9 +517,23 @@ static NSError *ASITooMuchRedirectionError; | ||
| 518 | } | 517 | } |
| 519 | 518 | ||
| 520 | 519 | ||
| 520 | + // Handle proxy settings | ||
| 521 | + | ||
| 522 | + // Have details of the proxy been set on this request | ||
| 521 | if (![self proxyHost] && ![self proxyPort]) { | 523 | if (![self proxyHost] && ![self proxyPort]) { |
| 522 | 524 | ||
| 525 | + // If not, we need to figure out what they'll be | ||
| 526 | + | ||
| 527 | + NSArray *proxies = nil; | ||
| 528 | + | ||
| 529 | + // Have we been given a proxy auto config file? | ||
| 530 | + if ([self PACurl]) { | ||
| 531 | + | ||
| 532 | + proxies = [ASIHTTPRequest proxiesForURL:[self url] fromPAC:[self PACurl]]; | ||
| 533 | + | ||
| 523 | // Detect proxy settings and apply them | 534 | // Detect proxy settings and apply them |
| 535 | + } else { | ||
| 536 | + | ||
| 524 | #if TARGET_OS_IPHONE | 537 | #if TARGET_OS_IPHONE |
| 525 | #if !defined(TARGET_IPHONE_SIMULATOR) || __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_2_2 | 538 | #if !defined(TARGET_IPHONE_SIMULATOR) || __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_2_2 |
| 526 | NSDictionary *proxySettings = [(NSDictionary *)CFNetworkCopySystemProxySettings() autorelease]; | 539 | NSDictionary *proxySettings = [(NSDictionary *)CFNetworkCopySystemProxySettings() autorelease]; |
| @@ -532,8 +545,16 @@ static NSError *ASITooMuchRedirectionError; | @@ -532,8 +545,16 @@ static NSError *ASITooMuchRedirectionError; | ||
| 532 | NSDictionary *proxySettings = [(NSDictionary *)SCDynamicStoreCopyProxies(NULL) autorelease]; | 545 | NSDictionary *proxySettings = [(NSDictionary *)SCDynamicStoreCopyProxies(NULL) autorelease]; |
| 533 | #endif | 546 | #endif |
| 534 | 547 | ||
| 535 | - NSArray *proxies = [(NSArray *)CFNetworkCopyProxiesForURL((CFURLRef)[self url], (CFDictionaryRef)proxySettings) autorelease]; | 548 | + proxies = [(NSArray *)CFNetworkCopyProxiesForURL((CFURLRef)[self url], (CFDictionaryRef)proxySettings) autorelease]; |
| 536 | - if (proxies == NULL) { | 549 | + |
| 550 | + // Now check to see if the proxy settings contained a PAC url, we need to run the script to get the real list of proxies if so | ||
| 551 | + NSDictionary *settings = [proxies objectAtIndex:0]; | ||
| 552 | + if ([settings objectForKey:(NSString *)kCFProxyAutoConfigurationURLKey]) { | ||
| 553 | + proxies = [ASIHTTPRequest proxiesForURL:[self url] fromPAC:[settings objectForKey:(NSString *)kCFProxyAutoConfigurationURLKey]]; | ||
| 554 | + } | ||
| 555 | + } | ||
| 556 | + | ||
| 557 | + if (!proxies) { | ||
| 537 | CFRelease(readStream); | 558 | CFRelease(readStream); |
| 538 | readStream = NULL; | 559 | readStream = NULL; |
| 539 | [[self cancelledLock] unlock]; | 560 | [[self cancelledLock] unlock]; |
| @@ -546,8 +567,6 @@ static NSError *ASITooMuchRedirectionError; | @@ -546,8 +567,6 @@ static NSError *ASITooMuchRedirectionError; | ||
| 546 | NSDictionary *settings = [proxies objectAtIndex:0]; | 567 | NSDictionary *settings = [proxies objectAtIndex:0]; |
| 547 | [self setProxyHost:[settings objectForKey:(NSString *)kCFProxyHostNameKey]]; | 568 | [self setProxyHost:[settings objectForKey:(NSString *)kCFProxyHostNameKey]]; |
| 548 | [self setProxyPort:[[settings objectForKey:(NSString *)kCFProxyPortNumberKey] intValue]]; | 569 | [self setProxyPort:[[settings objectForKey:(NSString *)kCFProxyPortNumberKey] intValue]]; |
| 549 | - //NSLog(@"%@",proxySettings); | ||
| 550 | - //NSLog(@"%@",[proxies objectAtIndex:0]); | ||
| 551 | } | 570 | } |
| 552 | } | 571 | } |
| 553 | if ([self proxyHost] && [self proxyPort]) { | 572 | if ([self proxyHost] && [self proxyPort]) { |
| @@ -2173,6 +2192,31 @@ static NSError *ASITooMuchRedirectionError; | @@ -2173,6 +2192,31 @@ static NSError *ASITooMuchRedirectionError; | ||
| 2173 | return [NSString stringWithFormat:@"%@ %@ (%@; %@ %@; %@)", appName, appVersion, deviceName, OSName, OSVersion, locale]; | 2192 | return [NSString stringWithFormat:@"%@ %@ (%@; %@ %@; %@)", appName, appVersion, deviceName, OSName, OSVersion, locale]; |
| 2174 | } | 2193 | } |
| 2175 | 2194 | ||
| 2195 | +#pragma mark proxy autoconfiguration | ||
| 2196 | + | ||
| 2197 | +// Returns an array of proxies to use for a particular url, given the url of a PAC script | ||
| 2198 | ++ (NSArray *)proxiesForURL:(NSURL *)theURL fromPAC:(NSURL *)pacScriptURL | ||
| 2199 | +{ | ||
| 2200 | + // From: http://developer.apple.com/samplecode/CFProxySupportTool/listing1.html | ||
| 2201 | + // Work around <rdar://problem/5530166>. This dummy call to | ||
| 2202 | + // CFNetworkCopyProxiesForURL initialise some state within CFNetwork | ||
| 2203 | + // that is required by CFNetworkCopyProxiesForAutoConfigurationScript. | ||
| 2204 | + (void) CFNetworkCopyProxiesForURL((CFURLRef)theURL, NULL); | ||
| 2205 | + | ||
| 2206 | + NSStringEncoding encoding; | ||
| 2207 | + NSError *err = nil; | ||
| 2208 | + NSString *script = [NSString stringWithContentsOfURL:pacScriptURL usedEncoding:&encoding error:&err]; | ||
| 2209 | + if (err) { | ||
| 2210 | + return nil; | ||
| 2211 | + } | ||
| 2212 | + CFErrorRef err2 = NULL; | ||
| 2213 | + // Obtain the list of proxies by running the autoconfiguration script | ||
| 2214 | + NSArray *proxies = [(NSArray *)CFNetworkCopyProxiesForAutoConfigurationScript((CFStringRef)script,(CFURLRef)theURL, &err2) autorelease]; | ||
| 2215 | + if (err2) { | ||
| 2216 | + return nil; | ||
| 2217 | + } | ||
| 2218 | + return proxies; | ||
| 2219 | +} | ||
| 2176 | 2220 | ||
| 2177 | 2221 | ||
| 2178 | @synthesize username; | 2222 | @synthesize username; |
| @@ -2249,4 +2293,5 @@ static NSError *ASITooMuchRedirectionError; | @@ -2249,4 +2293,5 @@ static NSError *ASITooMuchRedirectionError; | ||
| 2249 | 2293 | ||
| 2250 | @synthesize proxyHost; | 2294 | @synthesize proxyHost; |
| 2251 | @synthesize proxyPort; | 2295 | @synthesize proxyPort; |
| 2296 | +@synthesize PACurl; | ||
| 2252 | @end | 2297 | @end |
| @@ -18,6 +18,37 @@ static NSString *proxyPassword = @""; | @@ -18,6 +18,37 @@ static NSString *proxyPassword = @""; | ||
| 18 | 18 | ||
| 19 | @implementation ProxyTests | 19 | @implementation ProxyTests |
| 20 | 20 | ||
| 21 | +- (void)testAutoConfigureWithPAC | ||
| 22 | +{ | ||
| 23 | + // To run this test, specify the location of the pac script that is available at http://developer.apple.com/samplecode/CFProxySupportTool/listing1.html | ||
| 24 | + NSString *pacurl = @"file:///Users/ben/Desktop/test.pac"; | ||
| 25 | + ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]]; | ||
| 26 | + [request setPACurl:[NSURL URLWithString:pacurl]]; | ||
| 27 | + [request start]; | ||
| 28 | + NSLog(@"%@",[request proxyHost]); | ||
| 29 | + BOOL success = [[request proxyHost] isEqualToString:@"proxy1.apple.com"]; | ||
| 30 | + GHAssertTrue(success,@"Failed to use the correct proxy"); | ||
| 31 | + | ||
| 32 | + request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com"]]; | ||
| 33 | + [request setPACurl:[NSURL URLWithString:pacurl]]; | ||
| 34 | + [request start]; | ||
| 35 | + GHAssertNil([request proxyHost],@"Used a proxy when the script told us to go direct"); | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +- (void)testAutoConfigureWithSystemPAC | ||
| 39 | +{ | ||
| 40 | + // To run this test, specify the pac script above in your network settings | ||
| 41 | + ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]]; | ||
| 42 | + [request start]; | ||
| 43 | + NSLog(@"%@",[request proxyHost]); | ||
| 44 | + BOOL success = [[request proxyHost] isEqualToString:@"proxy1.apple.com"]; | ||
| 45 | + GHAssertTrue(success,@"Failed to use the correct proxy"); | ||
| 46 | + | ||
| 47 | + request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com"]]; | ||
| 48 | + [request start]; | ||
| 49 | + GHAssertNil([request proxyHost],@"Used a proxy when the script told us to go direct"); | ||
| 50 | +} | ||
| 51 | + | ||
| 21 | - (void)testProxy | 52 | - (void)testProxy |
| 22 | { | 53 | { |
| 23 | BOOL success = (![proxyHost isEqualToString:@""] && proxyPort > 0); | 54 | BOOL success = (![proxyHost isEqualToString:@""] && proxyPort > 0); |
| @@ -217,8 +217,13 @@ | @@ -217,8 +217,13 @@ | ||
| 217 | - (void)authSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { | 217 | - (void)authSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { |
| 218 | ASIHTTPRequest *request = (ASIHTTPRequest *)contextInfo; | 218 | ASIHTTPRequest *request = (ASIHTTPRequest *)contextInfo; |
| 219 | if (returnCode == NSOKButton) { | 219 | if (returnCode == NSOKButton) { |
| 220 | + if ([request needsProxyAuthentication]) { | ||
| 221 | + [request setProxyUsername:[[[username stringValue] copy] autorelease]]; | ||
| 222 | + [request setProxyPassword:[[[password stringValue] copy] autorelease]]; | ||
| 223 | + } else { | ||
| 220 | [request setUsername:[[[username stringValue] copy] autorelease]]; | 224 | [request setUsername:[[[username stringValue] copy] autorelease]]; |
| 221 | [request setPassword:[[[password stringValue] copy] autorelease]]; | 225 | [request setPassword:[[[password stringValue] copy] autorelease]]; |
| 226 | + } | ||
| 222 | [request retryWithAuthentication]; | 227 | [request retryWithAuthentication]; |
| 223 | } else { | 228 | } else { |
| 224 | [request cancelLoad]; | 229 | [request cancelLoad]; |
-
Please register or login to post a comment