Showing
8 changed files
with
338 additions
and
50 deletions
Classes/ASIAuthenticationDialog.h
0 → 100644
| 1 | +// | ||
| 2 | +// ASIAuthenticationDialog.h | ||
| 3 | +// iPhone | ||
| 4 | +// | ||
| 5 | +// Created by Ben Copsey on 21/08/2009. | ||
| 6 | +// Copyright 2009 All-Seeing Interactive. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <Foundation/Foundation.h> | ||
| 10 | +@class ASIHTTPRequest; | ||
| 11 | + | ||
| 12 | +typedef enum _ASIAuthenticationType { | ||
| 13 | + ASIStandardAuthenticationType = 0, | ||
| 14 | + ASIProxyAuthenticationType = 1 | ||
| 15 | +} ASIAuthenticationType; | ||
| 16 | + | ||
| 17 | +@interface ASIAuthenticationDialog : NSObject <UIActionSheetDelegate, UITableViewDelegate, UITableViewDataSource> { | ||
| 18 | + ASIHTTPRequest *request; | ||
| 19 | + UIActionSheet *loginDialog; | ||
| 20 | + ASIAuthenticationType type; | ||
| 21 | +} | ||
| 22 | ++ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request; | ||
| 23 | ++ (void)presentProxyAuthenticationDialogForRequest:(ASIHTTPRequest *)request; | ||
| 24 | + | ||
| 25 | +@property (retain) ASIHTTPRequest *request; | ||
| 26 | +@property (retain) UIActionSheet *loginDialog; | ||
| 27 | +@property (assign) ASIAuthenticationType type; | ||
| 28 | +@end |
Classes/ASIAuthenticationDialog.m
0 → 100644
| 1 | +// | ||
| 2 | +// ASIAuthenticationDialog.m | ||
| 3 | +// iPhone | ||
| 4 | +// | ||
| 5 | +// Created by Ben Copsey on 21/08/2009. | ||
| 6 | +// Copyright 2009 All-Seeing Interactive. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "ASIAuthenticationDialog.h" | ||
| 10 | +#import "ASIHTTPRequest.h" | ||
| 11 | + | ||
| 12 | +ASIAuthenticationDialog *sharedDialog = nil; | ||
| 13 | +NSLock *dialogLock = nil; | ||
| 14 | + | ||
| 15 | +@interface ASIAuthenticationDialog () | ||
| 16 | +- (void)show; | ||
| 17 | +@end | ||
| 18 | + | ||
| 19 | +@implementation ASIAuthenticationDialog | ||
| 20 | + | ||
| 21 | ++ (void)initialize | ||
| 22 | +{ | ||
| 23 | + if (self == [ASIAuthenticationDialog class]) { | ||
| 24 | + dialogLock = [[NSLock alloc] init]; | ||
| 25 | + } | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | ++ (void)presentProxyAuthenticationDialogForRequest:(ASIHTTPRequest *)request | ||
| 29 | +{ | ||
| 30 | + [dialogLock lock]; | ||
| 31 | + [sharedDialog release]; | ||
| 32 | + sharedDialog = [[self alloc] init]; | ||
| 33 | + [sharedDialog setRequest:request]; | ||
| 34 | + [sharedDialog setType:ASIProxyAuthenticationType]; | ||
| 35 | + [sharedDialog show]; | ||
| 36 | + [dialogLock unlock]; | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | ++ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request | ||
| 40 | +{ | ||
| 41 | + [dialogLock lock]; | ||
| 42 | + [sharedDialog release]; | ||
| 43 | + sharedDialog = [[self alloc] init]; | ||
| 44 | + [sharedDialog setRequest:request]; | ||
| 45 | + [sharedDialog show]; | ||
| 46 | + [dialogLock unlock]; | ||
| 47 | + | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +- (void)show | ||
| 51 | +{ | ||
| 52 | + // Create an action sheet to show the login dialog | ||
| 53 | + [self setLoginDialog:[[[UIActionSheet alloc] init] autorelease]]; | ||
| 54 | + [[self loginDialog] setActionSheetStyle:UIActionSheetStyleBlackOpaque]; | ||
| 55 | + [[self loginDialog] setDelegate:self]; | ||
| 56 | + | ||
| 57 | + // We show the login form in a table view, similar to Safari's authentication dialog | ||
| 58 | + UITableView *table = [[[UITableView alloc] initWithFrame:CGRectMake(0,50,320,480) style:UITableViewStyleGrouped] autorelease]; | ||
| 59 | + [table setDelegate:self]; | ||
| 60 | + [table setDataSource:self]; | ||
| 61 | + [[self loginDialog] addSubview:table]; | ||
| 62 | + [[self loginDialog] showInView:[[[UIApplication sharedApplication] windows] objectAtIndex:0]]; | ||
| 63 | + [[self loginDialog] setFrame:CGRectMake(0,0,320,480)]; | ||
| 64 | + | ||
| 65 | + UIToolbar *toolbar = [[[UIToolbar alloc] initWithFrame:CGRectMake(0,0,320,80)] autorelease]; | ||
| 66 | + //[toolbar setFrame:CGRectMake(0,20,320,50)]; | ||
| 67 | + NSMutableArray *items = [[[NSMutableArray alloc] init] autorelease]; | ||
| 68 | + UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAuthenticationFromDialog:)] autorelease]; | ||
| 69 | + //[backButton setContentEdgeInsets:UIEdgeInsetsMake(0,20,0,0)]; | ||
| 70 | + [items addObject:backButton]; | ||
| 71 | + | ||
| 72 | + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,170,50)]; | ||
| 73 | + [label setText:[[[self request] url] host]]; | ||
| 74 | + [label setTextColor:[UIColor whiteColor]]; | ||
| 75 | + [label setFont:[UIFont boldSystemFontOfSize:22.0]]; | ||
| 76 | + [label setShadowColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]]; | ||
| 77 | + [label setShadowOffset:CGSizeMake(0, -1.0)]; | ||
| 78 | + [label setOpaque:NO]; | ||
| 79 | + [label setBackgroundColor:nil]; | ||
| 80 | + [label setTextAlignment:UITextAlignmentCenter]; | ||
| 81 | + | ||
| 82 | + [toolbar addSubview:label]; | ||
| 83 | + | ||
| 84 | + UIBarButtonItem *labelButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:nil action:nil] autorelease]; | ||
| 85 | + | ||
| 86 | + //[labelButton setCustomView:label]; | ||
| 87 | + //[items addObject:labelButton]; | ||
| 88 | + [items addObject:[[[UIBarButtonItem alloc] initWithTitle:@"Login" style:UIBarButtonItemStyleDone target:self action:@selector(loginWithCredentialsFromDialog:)] autorelease]]; | ||
| 89 | + [toolbar setItems:items]; | ||
| 90 | + [[self loginDialog] addSubview:toolbar]; | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +- (void)cancelAuthenticationFromDialog:(id)sender | ||
| 94 | +{ | ||
| 95 | + [[self request] cancelAuthentication]; | ||
| 96 | + [[self loginDialog] dismissWithClickedButtonIndex:0 animated:YES]; | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +- (void)loginWithCredentialsFromDialog:(id)sender | ||
| 100 | +{ | ||
| 101 | + [[self request] setUsername:[[[[[[[self loginDialog] subviews] objectAtIndex:0] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] subviews] objectAtIndex:2] text]]; | ||
| 102 | + [[self request] setPassword:[[[[[[[self loginDialog] subviews] objectAtIndex:0] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]] subviews] objectAtIndex:2] text]]; | ||
| 103 | + [[self loginDialog] dismissWithClickedButtonIndex:1 animated:YES]; | ||
| 104 | + [[self request] retryWithAuthentication]; | ||
| 105 | +} | ||
| 106 | + | ||
| 107 | + | ||
| 108 | +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView | ||
| 109 | +{ | ||
| 110 | + NSString *scheme = ([self type] == ASIStandardAuthenticationType) ? [[self request] authenticationScheme] : [[self request] proxyAuthenticationScheme]; | ||
| 111 | + if ([scheme isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeNTLM]) { | ||
| 112 | + return 3; | ||
| 113 | + } | ||
| 114 | + return 2; | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section | ||
| 118 | +{ | ||
| 119 | + if (section == [self numberOfSectionsInTableView:tableView]-1) { | ||
| 120 | + return 30; | ||
| 121 | + } | ||
| 122 | + return 0; | ||
| 123 | +} | ||
| 124 | + | ||
| 125 | +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section | ||
| 126 | +{ | ||
| 127 | + if (section == 0) { | ||
| 128 | + return 30; | ||
| 129 | + } | ||
| 130 | + return 0; | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section | ||
| 134 | +{ | ||
| 135 | + if (section == 0) { | ||
| 136 | + return [[self request] authenticationRealm]; | ||
| 137 | + } | ||
| 138 | + return nil; | ||
| 139 | +} | ||
| 140 | + | ||
| 141 | +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath | ||
| 142 | +{ | ||
| 143 | + UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease]; | ||
| 144 | + [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; | ||
| 145 | + UITextField *textField = [[[UITextField alloc] initWithFrame:CGRectMake(20,12,260,25)] autorelease]; | ||
| 146 | + if ([indexPath section] == 0) { | ||
| 147 | + [textField setPlaceholder:@"User"]; | ||
| 148 | + } else if ([indexPath section] == 1) { | ||
| 149 | + [textField setPlaceholder:@"Password"]; | ||
| 150 | + } else if ([indexPath section] == 2) { | ||
| 151 | + [textField setPlaceholder:@"Domain"]; | ||
| 152 | + } | ||
| 153 | + [cell addSubview:textField]; | ||
| 154 | + | ||
| 155 | + return cell; | ||
| 156 | +} | ||
| 157 | + | ||
| 158 | +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section | ||
| 159 | +{ | ||
| 160 | + return 1; | ||
| 161 | +} | ||
| 162 | + | ||
| 163 | + | ||
| 164 | +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section | ||
| 165 | +{ | ||
| 166 | + if (section == [self numberOfSectionsInTableView:tableView]-1) { | ||
| 167 | + if ([[[[self request] url] scheme] isEqualToString:@"https"]) { | ||
| 168 | + return @"Password will be sent securely."; | ||
| 169 | + } else { | ||
| 170 | + return @"Password will be sent in the clear."; | ||
| 171 | + } | ||
| 172 | + } | ||
| 173 | + return nil; | ||
| 174 | +} | ||
| 175 | + | ||
| 176 | +@synthesize request; | ||
| 177 | +@synthesize loginDialog; | ||
| 178 | +@synthesize type; | ||
| 179 | +@end |
| @@ -160,8 +160,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -160,8 +160,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
| 160 | // Used during NTLM authentication | 160 | // Used during NTLM authentication |
| 161 | int authenticationRetryCount; | 161 | int authenticationRetryCount; |
| 162 | 162 | ||
| 163 | - // Authentication method (Basic, Digest, NTLM) | 163 | + // Authentication scheme (Basic, Digest, NTLM) |
| 164 | - NSString *authenticationMethod; | 164 | + NSString *authenticationScheme; |
| 165 | 165 | ||
| 166 | // Realm for authentication when credentials are required | 166 | // Realm for authentication when credentials are required |
| 167 | NSString *authenticationRealm; | 167 | NSString *authenticationRealm; |
| @@ -169,6 +169,16 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -169,6 +169,16 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
| 169 | // And now, the same thing, but for authenticating proxies | 169 | // And now, the same thing, but for authenticating proxies |
| 170 | BOOL needsProxyAuthentication; | 170 | BOOL needsProxyAuthentication; |
| 171 | 171 | ||
| 172 | + // When YES, ASIHTTPRequest will present a dialog allowing users to enter credentials when no-matching credentials were found for a server that requires authentication | ||
| 173 | + // The dialog will not be shown if your delegate responds to authenticationNeededForRequest: | ||
| 174 | + // Default is NO. | ||
| 175 | + BOOL shouldPresentAuthenticationDialog; | ||
| 176 | + | ||
| 177 | + // When YES, ASIHTTPRequest will present a dialog allowing users to enter credentials when no-matching credentials were found for a proxy server that requires authentication | ||
| 178 | + // The dialog will not be shown if your delegate responds to proxyAuthenticationNeededForRequest: | ||
| 179 | + // Default is YES (basically, because most people won't want the hassle of adding support for authenticating proxies to their apps) | ||
| 180 | + BOOL shouldPresentProxyAuthenticationDialog; | ||
| 181 | + | ||
| 172 | // Used for proxy authentication | 182 | // Used for proxy authentication |
| 173 | CFHTTPAuthenticationRef proxyAuthentication; | 183 | CFHTTPAuthenticationRef proxyAuthentication; |
| 174 | NSMutableDictionary *proxyCredentials; | 184 | NSMutableDictionary *proxyCredentials; |
| @@ -176,8 +186,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -176,8 +186,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
| 176 | // Used during authentication with an NTLM proxy | 186 | // Used during authentication with an NTLM proxy |
| 177 | int proxyAuthenticationRetryCount; | 187 | int proxyAuthenticationRetryCount; |
| 178 | 188 | ||
| 179 | - // Authentication method for the proxy (Basic, Digest, NTLM) | 189 | + // Authentication scheme for the proxy (Basic, Digest, NTLM) |
| 180 | - NSString *proxyAuthenticationMethod; | 190 | + NSString *proxyAuthenticationScheme; |
| 181 | 191 | ||
| 182 | // Realm for proxy authentication when credentials are required | 192 | // Realm for proxy authentication when credentials are required |
| 183 | NSString *proxyAuthenticationRealm; | 193 | NSString *proxyAuthenticationRealm; |
| @@ -378,6 +388,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -378,6 +388,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
| 378 | // Should be called by delegates when they have populated the authentication information after an authentication challenge | 388 | // Should be called by delegates when they have populated the authentication information after an authentication challenge |
| 379 | - (void)retryWithAuthentication; | 389 | - (void)retryWithAuthentication; |
| 380 | 390 | ||
| 391 | +// Should be called by delegates when they wish to cancel authentication and stop | ||
| 392 | +- (void)cancelAuthentication; | ||
| 393 | + | ||
| 381 | // Apply authentication information and resume the request after an authentication challenge | 394 | // Apply authentication information and resume the request after an authentication challenge |
| 382 | - (void)attemptToApplyCredentialsAndResume; | 395 | - (void)attemptToApplyCredentialsAndResume; |
| 383 | - (void)attemptToApplyProxyCredentialsAndResume; | 396 | - (void)attemptToApplyProxyCredentialsAndResume; |
| @@ -484,6 +497,10 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -484,6 +497,10 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
| 484 | + (void)reachabilityChanged:(NSNotification *)note; | 497 | + (void)reachabilityChanged:(NSNotification *)note; |
| 485 | #endif | 498 | #endif |
| 486 | 499 | ||
| 500 | + | ||
| 501 | +- (BOOL)showProxyAuthenticationDialog; | ||
| 502 | +- (BOOL)showAuthenticationDialog; | ||
| 503 | + | ||
| 487 | + (unsigned long)maxUploadReadLength; | 504 | + (unsigned long)maxUploadReadLength; |
| 488 | 505 | ||
| 489 | @property (retain) NSString *username; | 506 | @property (retain) NSString *username; |
| @@ -546,4 +563,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -546,4 +563,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
| 546 | @property (assign) BOOL shouldCompressRequestBody; | 563 | @property (assign) BOOL shouldCompressRequestBody; |
| 547 | @property (assign) BOOL needsProxyAuthentication; | 564 | @property (assign) BOOL needsProxyAuthentication; |
| 548 | @property (retain) NSURL *PACurl; | 565 | @property (retain) NSURL *PACurl; |
| 566 | +@property (retain) NSString *authenticationScheme; | ||
| 567 | +@property (retain) NSString *proxyAuthenticationScheme; | ||
| 568 | +@property (assign) BOOL shouldPresentAuthenticationDialog; | ||
| 569 | +@property (assign) BOOL shouldPresentProxyAuthenticationDialog; | ||
| 549 | @end | 570 | @end |
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | #import <SystemConfiguration/SystemConfiguration.h> | 18 | #import <SystemConfiguration/SystemConfiguration.h> |
| 19 | #endif | 19 | #endif |
| 20 | #import "ASIInputStream.h" | 20 | #import "ASIInputStream.h" |
| 21 | +#import "ASIAuthenticationDialog.h" | ||
| 21 | 22 | ||
| 22 | // We use our own custom run loop mode as CoreAnimation seems to want to hijack our threads otherwise | 23 | // We use our own custom run loop mode as CoreAnimation seems to want to hijack our threads otherwise |
| 23 | static CFStringRef ASIHTTPRequestRunMode = CFSTR("ASIHTTPRequest"); | 24 | static CFStringRef ASIHTTPRequestRunMode = CFSTR("ASIHTTPRequest"); |
| @@ -77,6 +78,8 @@ BOOL shouldThrottleBandwithForWWANOnly = NO; | @@ -77,6 +78,8 @@ BOOL shouldThrottleBandwithForWWANOnly = NO; | ||
| 77 | 78 | ||
| 78 | static NSLock *sessionCookiesLock = nil; | 79 | static NSLock *sessionCookiesLock = nil; |
| 79 | 80 | ||
| 81 | +UIActionSheet *loginDialog = nil; | ||
| 82 | + | ||
| 80 | // Private stuff | 83 | // Private stuff |
| 81 | @interface ASIHTTPRequest () | 84 | @interface ASIHTTPRequest () |
| 82 | 85 | ||
| @@ -196,14 +199,14 @@ static NSLock *sessionCookiesLock = nil; | @@ -196,14 +199,14 @@ static NSLock *sessionCookiesLock = nil; | ||
| 196 | [password release]; | 199 | [password release]; |
| 197 | [domain release]; | 200 | [domain release]; |
| 198 | [authenticationRealm release]; | 201 | [authenticationRealm release]; |
| 199 | - [authenticationMethod release]; | 202 | + [authenticationScheme release]; |
| 200 | [requestCredentials release]; | 203 | [requestCredentials release]; |
| 201 | [proxyHost release]; | 204 | [proxyHost release]; |
| 202 | [proxyUsername release]; | 205 | [proxyUsername release]; |
| 203 | [proxyPassword release]; | 206 | [proxyPassword release]; |
| 204 | [proxyDomain release]; | 207 | [proxyDomain release]; |
| 205 | [proxyAuthenticationRealm release]; | 208 | [proxyAuthenticationRealm release]; |
| 206 | - [proxyAuthenticationMethod release]; | 209 | + [proxyAuthenticationScheme release]; |
| 207 | [proxyCredentials release]; | 210 | [proxyCredentials release]; |
| 208 | [url release]; | 211 | [url release]; |
| 209 | [authenticationLock release]; | 212 | [authenticationLock release]; |
| @@ -1401,24 +1404,44 @@ static NSLock *sessionCookiesLock = nil; | @@ -1401,24 +1404,44 @@ static NSLock *sessionCookiesLock = nil; | ||
| 1401 | return nil; | 1404 | return nil; |
| 1402 | } | 1405 | } |
| 1403 | 1406 | ||
| 1404 | -// Called by delegate to resume loading once authentication info has been populated | 1407 | +// Called by delegate or authentication dialog to resume loading once authentication info has been populated |
| 1405 | - (void)retryWithAuthentication | 1408 | - (void)retryWithAuthentication |
| 1406 | { | 1409 | { |
| 1407 | [[self authenticationLock] lockWhenCondition:1]; | 1410 | [[self authenticationLock] lockWhenCondition:1]; |
| 1408 | [[self authenticationLock] unlockWithCondition:2]; | 1411 | [[self authenticationLock] unlockWithCondition:2]; |
| 1409 | } | 1412 | } |
| 1410 | 1413 | ||
| 1414 | +// Called by delegate or authentication dialog to cancel authentication | ||
| 1415 | +- (void)cancelAuthentication | ||
| 1416 | +{ | ||
| 1417 | + [self failWithError:ASIAuthenticationError]; | ||
| 1418 | + [[self authenticationLock] lockWhenCondition:1]; | ||
| 1419 | + [[self authenticationLock] unlockWithCondition:2]; | ||
| 1420 | +} | ||
| 1421 | + | ||
| 1422 | +- (BOOL)showProxyAuthenticationDialog | ||
| 1423 | +{ | ||
| 1424 | + if ([self shouldPresentProxyAuthenticationDialog]) { | ||
| 1425 | + [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentProxyAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | ||
| 1426 | + [[self authenticationLock] lockWhenCondition:2]; | ||
| 1427 | + [[self authenticationLock] unlockWithCondition:1]; | ||
| 1428 | + return YES; | ||
| 1429 | + } | ||
| 1430 | + return NO; | ||
| 1431 | +} | ||
| 1432 | + | ||
| 1433 | + | ||
| 1411 | - (BOOL)askDelegateForProxyCredentials | 1434 | - (BOOL)askDelegateForProxyCredentials |
| 1412 | { | 1435 | { |
| 1413 | - // If we have a delegate, we'll see if it can handle proxyAuthorizationNeededForRequest:. | 1436 | + // If we have a delegate, we'll see if it can handle proxyAuthenticationNeededForRequest:. |
| 1414 | // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate | 1437 | // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate |
| 1415 | - id authorizationDelegate = [self delegate]; | 1438 | + id authenticationDelegate = [self delegate]; |
| 1416 | - if (!authorizationDelegate) { | 1439 | + if (!authenticationDelegate) { |
| 1417 | - authorizationDelegate = [self queue]; | 1440 | + authenticationDelegate = [self queue]; |
| 1418 | } | 1441 | } |
| 1419 | 1442 | ||
| 1420 | - if ([authorizationDelegate respondsToSelector:@selector(proxyAuthorizationNeededForRequest:)]) { | 1443 | + if ([authenticationDelegate respondsToSelector:@selector(proxyAuthenticationNeededForRequest:)]) { |
| 1421 | - [authorizationDelegate performSelectorOnMainThread:@selector(proxyAuthorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | 1444 | + [authenticationDelegate performSelectorOnMainThread:@selector(proxyAuthenticationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; |
| 1422 | [[self authenticationLock] lockWhenCondition:2]; | 1445 | [[self authenticationLock] lockWhenCondition:2]; |
| 1423 | [[self authenticationLock] unlockWithCondition:1]; | 1446 | [[self authenticationLock] unlockWithCondition:1]; |
| 1424 | 1447 | ||
| @@ -1430,12 +1453,16 @@ static NSLock *sessionCookiesLock = nil; | @@ -1430,12 +1453,16 @@ static NSLock *sessionCookiesLock = nil; | ||
| 1430 | - (void)attemptToApplyProxyCredentialsAndResume | 1453 | - (void)attemptToApplyProxyCredentialsAndResume |
| 1431 | { | 1454 | { |
| 1432 | 1455 | ||
| 1456 | + if ([self error]) { | ||
| 1457 | + return; | ||
| 1458 | + } | ||
| 1459 | + | ||
| 1433 | // Read authentication data | 1460 | // Read authentication data |
| 1434 | if (!proxyAuthentication) { | 1461 | if (!proxyAuthentication) { |
| 1435 | CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader); | 1462 | CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader); |
| 1436 | proxyAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader); | 1463 | proxyAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader); |
| 1437 | CFRelease(responseHeader); | 1464 | CFRelease(responseHeader); |
| 1438 | - proxyAuthenticationMethod = (NSString *)CFHTTPAuthenticationCopyMethod(proxyAuthentication); | 1465 | + [self setProxyAuthenticationScheme:[(NSString *)CFHTTPAuthenticationCopyMethod(proxyAuthentication) autorelease]]; |
| 1439 | } | 1466 | } |
| 1440 | 1467 | ||
| 1441 | // If we haven't got a CFHTTPAuthenticationRef by now, something is badly wrong, so we'll have to give up | 1468 | // If we haven't got a CFHTTPAuthenticationRef by now, something is badly wrong, so we'll have to give up |
| @@ -1472,11 +1499,11 @@ static NSLock *sessionCookiesLock = nil; | @@ -1472,11 +1499,11 @@ static NSLock *sessionCookiesLock = nil; | ||
| 1472 | if (proxyCredentials) { | 1499 | if (proxyCredentials) { |
| 1473 | 1500 | ||
| 1474 | // We use startRequest rather than starting all over again in load request because NTLM requires we reuse the request | 1501 | // We use startRequest rather than starting all over again in load request because NTLM requires we reuse the request |
| 1475 | - if (((proxyAuthenticationMethod != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || proxyAuthenticationRetryCount < 2) && [self applyCredentials:proxyCredentials]) { | 1502 | + if ((([self proxyAuthenticationScheme] != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || proxyAuthenticationRetryCount < 2) && [self applyCredentials:proxyCredentials]) { |
| 1476 | [self startRequest]; | 1503 | [self startRequest]; |
| 1477 | 1504 | ||
| 1478 | // We've failed NTLM authentication twice, we should assume our credentials are wrong | 1505 | // We've failed NTLM authentication twice, we should assume our credentials are wrong |
| 1479 | - } else if (proxyAuthenticationMethod == (NSString *)kCFHTTPAuthenticationSchemeNTLM && proxyAuthenticationRetryCount == 2) { | 1506 | + } else if ([self proxyAuthenticationScheme] == (NSString *)kCFHTTPAuthenticationSchemeNTLM && proxyAuthenticationRetryCount == 2) { |
| 1480 | [self failWithError:ASIAuthenticationError]; | 1507 | [self failWithError:ASIAuthenticationError]; |
| 1481 | 1508 | ||
| 1482 | // Something went wrong, we'll have to give up | 1509 | // Something went wrong, we'll have to give up |
| @@ -1505,24 +1532,39 @@ static NSLock *sessionCookiesLock = nil; | @@ -1505,24 +1532,39 @@ static NSLock *sessionCookiesLock = nil; | ||
| 1505 | return; | 1532 | return; |
| 1506 | } | 1533 | } |
| 1507 | 1534 | ||
| 1508 | - // The delegate isn't interested, we'll have to give up | 1535 | + if ([self showProxyAuthenticationDialog]) { |
| 1536 | + [self attemptToApplyProxyCredentialsAndResume]; | ||
| 1537 | + } | ||
| 1538 | + | ||
| 1539 | + // The delegate isn't interested and we aren't showing the authentication dialog, we'll have to give up | ||
| 1509 | [self failWithError:ASIAuthenticationError]; | 1540 | [self failWithError:ASIAuthenticationError]; |
| 1510 | return; | 1541 | return; |
| 1511 | } | 1542 | } |
| 1512 | 1543 | ||
| 1513 | } | 1544 | } |
| 1514 | 1545 | ||
| 1546 | +- (BOOL)showAuthenticationDialog | ||
| 1547 | +{ | ||
| 1548 | + if ([self shouldPresentAuthenticationDialog]) { | ||
| 1549 | + [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | ||
| 1550 | + [[self authenticationLock] lockWhenCondition:2]; | ||
| 1551 | + [[self authenticationLock] unlockWithCondition:1]; | ||
| 1552 | + return YES; | ||
| 1553 | + } | ||
| 1554 | + return NO; | ||
| 1555 | +} | ||
| 1556 | + | ||
| 1515 | - (BOOL)askDelegateForCredentials | 1557 | - (BOOL)askDelegateForCredentials |
| 1516 | { | 1558 | { |
| 1517 | - // If we have a delegate, we'll see if it can handle proxyAuthorizationNeededForRequest:. | 1559 | + // If we have a delegate, we'll see if it can handle proxyAuthenticationNeededForRequest:. |
| 1518 | // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate | 1560 | // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate |
| 1519 | - id authorizationDelegate = [self delegate]; | 1561 | + id authenticationDelegate = [self delegate]; |
| 1520 | - if (!authorizationDelegate) { | 1562 | + if (!authenticationDelegate) { |
| 1521 | - authorizationDelegate = [self queue]; | 1563 | + authenticationDelegate = [self queue]; |
| 1522 | } | 1564 | } |
| 1523 | 1565 | ||
| 1524 | - if ([authorizationDelegate respondsToSelector:@selector(authorizationNeededForRequest:)]) { | 1566 | + if ([authenticationDelegate respondsToSelector:@selector(authenticationNeededForRequest:)]) { |
| 1525 | - [authorizationDelegate performSelectorOnMainThread:@selector(authorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; | 1567 | + [authenticationDelegate performSelectorOnMainThread:@selector(authenticationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; |
| 1526 | [[self authenticationLock] lockWhenCondition:2]; | 1568 | [[self authenticationLock] lockWhenCondition:2]; |
| 1527 | [[self authenticationLock] unlockWithCondition:1]; | 1569 | [[self authenticationLock] unlockWithCondition:1]; |
| 1528 | 1570 | ||
| @@ -1533,6 +1575,10 @@ static NSLock *sessionCookiesLock = nil; | @@ -1533,6 +1575,10 @@ static NSLock *sessionCookiesLock = nil; | ||
| 1533 | 1575 | ||
| 1534 | - (void)attemptToApplyCredentialsAndResume | 1576 | - (void)attemptToApplyCredentialsAndResume |
| 1535 | { | 1577 | { |
| 1578 | + if ([self error]) { | ||
| 1579 | + return; | ||
| 1580 | + } | ||
| 1581 | + | ||
| 1536 | if ([self needsProxyAuthentication]) { | 1582 | if ([self needsProxyAuthentication]) { |
| 1537 | [self attemptToApplyProxyCredentialsAndResume]; | 1583 | [self attemptToApplyProxyCredentialsAndResume]; |
| 1538 | return; | 1584 | return; |
| @@ -1543,7 +1589,7 @@ static NSLock *sessionCookiesLock = nil; | @@ -1543,7 +1589,7 @@ static NSLock *sessionCookiesLock = nil; | ||
| 1543 | CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader); | 1589 | CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader); |
| 1544 | requestAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader); | 1590 | requestAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader); |
| 1545 | CFRelease(responseHeader); | 1591 | CFRelease(responseHeader); |
| 1546 | - authenticationMethod = (NSString *)CFHTTPAuthenticationCopyMethod(requestAuthentication); | 1592 | + [self setAuthenticationScheme:[(NSString *)CFHTTPAuthenticationCopyMethod(requestAuthentication) autorelease]]; |
| 1547 | } | 1593 | } |
| 1548 | 1594 | ||
| 1549 | if (!requestAuthentication) { | 1595 | if (!requestAuthentication) { |
| @@ -1570,6 +1616,9 @@ static NSLock *sessionCookiesLock = nil; | @@ -1570,6 +1616,9 @@ static NSLock *sessionCookiesLock = nil; | ||
| 1570 | [self attemptToApplyCredentialsAndResume]; | 1616 | [self attemptToApplyCredentialsAndResume]; |
| 1571 | return; | 1617 | return; |
| 1572 | } | 1618 | } |
| 1619 | + if ([self showAuthenticationDialog]) { | ||
| 1620 | + [self attemptToApplyCredentialsAndResume]; | ||
| 1621 | + } | ||
| 1573 | } | 1622 | } |
| 1574 | [self cancelLoad]; | 1623 | [self cancelLoad]; |
| 1575 | [self failWithError:ASIAuthenticationError]; | 1624 | [self failWithError:ASIAuthenticationError]; |
| @@ -1580,11 +1629,11 @@ static NSLock *sessionCookiesLock = nil; | @@ -1580,11 +1629,11 @@ static NSLock *sessionCookiesLock = nil; | ||
| 1580 | 1629 | ||
| 1581 | if (requestCredentials) { | 1630 | if (requestCredentials) { |
| 1582 | 1631 | ||
| 1583 | - if (((authenticationMethod != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || authenticationRetryCount < 2) && [self applyCredentials:requestCredentials]) { | 1632 | + if ((([self authenticationScheme] != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || authenticationRetryCount < 2) && [self applyCredentials:requestCredentials]) { |
| 1584 | [self startRequest]; | 1633 | [self startRequest]; |
| 1585 | 1634 | ||
| 1586 | // We've failed NTLM authentication twice, we should assume our credentials are wrong | 1635 | // We've failed NTLM authentication twice, we should assume our credentials are wrong |
| 1587 | - } else if (authenticationMethod == (NSString *)kCFHTTPAuthenticationSchemeNTLM && authenticationRetryCount == 2) { | 1636 | + } else if ([self authenticationScheme] == (NSString *)kCFHTTPAuthenticationSchemeNTLM && authenticationRetryCount == 2) { |
| 1588 | [self failWithError:ASIAuthenticationError]; | 1637 | [self failWithError:ASIAuthenticationError]; |
| 1589 | 1638 | ||
| 1590 | } else { | 1639 | } else { |
| @@ -1612,8 +1661,9 @@ static NSLock *sessionCookiesLock = nil; | @@ -1612,8 +1661,9 @@ static NSLock *sessionCookiesLock = nil; | ||
| 1612 | return; | 1661 | return; |
| 1613 | } | 1662 | } |
| 1614 | 1663 | ||
| 1615 | - // The delegate isn't interested, we'll have to give up | 1664 | + if ([self showAuthenticationDialog]) { |
| 1616 | - [self failWithError:ASIAuthenticationError]; | 1665 | + [self attemptToApplyCredentialsAndResume]; |
| 1666 | + } | ||
| 1617 | return; | 1667 | return; |
| 1618 | } | 1668 | } |
| 1619 | 1669 | ||
| @@ -2498,6 +2548,7 @@ static NSLock *sessionCookiesLock = nil; | @@ -2498,6 +2548,7 @@ static NSLock *sessionCookiesLock = nil; | ||
| 2498 | return toRead; | 2548 | return toRead; |
| 2499 | } | 2549 | } |
| 2500 | 2550 | ||
| 2551 | + | ||
| 2501 | @synthesize username; | 2552 | @synthesize username; |
| 2502 | @synthesize password; | 2553 | @synthesize password; |
| 2503 | @synthesize domain; | 2554 | @synthesize domain; |
| @@ -2572,6 +2623,10 @@ static NSLock *sessionCookiesLock = nil; | @@ -2572,6 +2623,10 @@ static NSLock *sessionCookiesLock = nil; | ||
| 2572 | @synthesize proxyHost; | 2623 | @synthesize proxyHost; |
| 2573 | @synthesize proxyPort; | 2624 | @synthesize proxyPort; |
| 2574 | @synthesize PACurl; | 2625 | @synthesize PACurl; |
| 2626 | +@synthesize authenticationScheme; | ||
| 2627 | +@synthesize proxyAuthenticationScheme; | ||
| 2628 | +@synthesize shouldPresentAuthenticationDialog; | ||
| 2629 | +@synthesize shouldPresentProxyAuthenticationDialog; | ||
| 2575 | @end | 2630 | @end |
| 2576 | 2631 | ||
| 2577 | 2632 |
| @@ -13,6 +13,7 @@ | @@ -13,6 +13,7 @@ | ||
| 13 | @interface AuthenticationViewController : UIViewController { | 13 | @interface AuthenticationViewController : UIViewController { |
| 14 | ASINetworkQueue *networkQueue; | 14 | ASINetworkQueue *networkQueue; |
| 15 | IBOutlet UISwitch *useKeychain; | 15 | IBOutlet UISwitch *useKeychain; |
| 16 | + IBOutlet UISwitch *useBuiltInDialog; | ||
| 16 | IBOutlet UILabel *topSecretInfo; | 17 | IBOutlet UILabel *topSecretInfo; |
| 17 | ASIHTTPRequest *requestRequiringAuthentication; | 18 | ASIHTTPRequest *requestRequiringAuthentication; |
| 18 | ASIHTTPRequest *requestRequiringProxyAuthentication; | 19 | ASIHTTPRequest *requestRequiringProxyAuthentication; |
| @@ -27,6 +27,7 @@ | @@ -27,6 +27,7 @@ | ||
| 27 | 27 | ||
| 28 | ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/top_secret/"]]; | 28 | ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/top_secret/"]]; |
| 29 | [request setUseKeychainPersistance:[useKeychain isOn]]; | 29 | [request setUseKeychainPersistance:[useKeychain isOn]]; |
| 30 | + [request setShouldPresentAuthenticationDialog:[useBuiltInDialog isOn]]; | ||
| 30 | [networkQueue addOperation:request]; | 31 | [networkQueue addOperation:request]; |
| 31 | [networkQueue go]; | 32 | [networkQueue go]; |
| 32 | 33 | ||
| @@ -44,28 +45,31 @@ | @@ -44,28 +45,31 @@ | ||
| 44 | [topSecretInfo setFont:[UIFont boldSystemFontOfSize:12]]; | 45 | [topSecretInfo setFont:[UIFont boldSystemFontOfSize:12]]; |
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | -- (void)authorizationNeededForRequest:(ASIHTTPRequest *)request | 48 | +//- (void)authorizationNeededForRequest:(ASIHTTPRequest *)request |
| 48 | -{ | 49 | +//{ |
| 49 | - // Why oh why is there no contextInfo for alertView like on Mac OS ?! | 50 | +// // Why oh why is there no contextInfo for alertView like on Mac OS ?! |
| 50 | - [self setRequestRequiringProxyAuthentication:nil]; | 51 | +// [self setRequestRequiringProxyAuthentication:nil]; |
| 51 | - [self setRequestRequiringAuthentication:request]; | 52 | +// [self setRequestRequiringAuthentication:request]; |
| 52 | - UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Please Login" message:[request authenticationRealm] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil] autorelease]; | 53 | +// |
| 53 | - // These are undocumented, use at your own risk! | 54 | +// [ASIHTTPRequest showAuthenticationDialogForRequest:request]; |
| 54 | - // A better general approach would be to subclass UIAlertView | 55 | +// |
| 55 | - [alertView addTextFieldWithValue:@"" label:@"Username"]; | 56 | +// //UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Please Login" message:[request authenticationRealm] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil] autorelease]; |
| 56 | - [alertView addTextFieldWithValue:@"" label:@"Password"]; | 57 | +// // These are undocumented, use at your own risk! |
| 57 | - [alertView show]; | 58 | +// // A better general approach would be to subclass UIAlertView |
| 58 | -} | 59 | +// //[alertView addTextFieldWithValue:@"" label:@"Username"]; |
| 59 | - | 60 | +// //[alertView addTextFieldWithValue:@"" label:@"Password"]; |
| 60 | -- (void)proxyAuthorizationNeededForRequest:(ASIHTTPRequest *)request | 61 | +// |
| 61 | -{ | 62 | +//} |
| 62 | - [self setRequestRequiringAuthentication:nil]; | 63 | +// |
| 63 | - [self setRequestRequiringProxyAuthentication:request]; | 64 | +//- (void)proxyAuthorizationNeededForRequest:(ASIHTTPRequest *)request |
| 64 | - UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Please Login to proxy" message:[request authenticationRealm] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil] autorelease]; | 65 | +//{ |
| 65 | - [alertView addTextFieldWithValue:@"" label:@"Username"]; | 66 | +// [self setRequestRequiringAuthentication:nil]; |
| 66 | - [alertView addTextFieldWithValue:@"" label:@"Password"]; | 67 | +// [self setRequestRequiringProxyAuthentication:request]; |
| 67 | - [alertView show]; | 68 | +// UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Please Login to proxy" message:[request authenticationRealm] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil] autorelease]; |
| 68 | -} | 69 | +// [alertView addTextFieldWithValue:@"" label:@"Username"]; |
| 70 | +// [alertView addTextFieldWithValue:@"" label:@"Password"]; | ||
| 71 | +// [alertView show]; | ||
| 72 | +//} | ||
| 69 | 73 | ||
| 70 | 74 | ||
| 71 | 75 |
This diff is collapsed. Click to expand it.
This diff was suppressed by a .gitattributes entry.
-
Please register or login to post a comment