Ben Copsey

Added basic unit tests

Added responseStatusCode property
Various cleanups
@@ -26,9 +26,12 @@ @@ -26,9 +26,12 @@
26 //Files that will be POSTed to the url 26 //Files that will be POSTed to the url
27 NSMutableDictionary *fileData; 27 NSMutableDictionary *fileData;
28 28
29 - //Dictionary for custom request headers 29 + //Dictionary for custom HTTP request headers
30 NSMutableDictionary *requestHeaders; 30 NSMutableDictionary *requestHeaders;
31 31
  32 + //Will be populate with HTTP response headers from the server
  33 + NSDictionary *responseHeaders;
  34 +
32 //If useKeychainPersistance is true, network requests will attempt to read credentials from the keychain, and will save them in the keychain when they are successfully presented 35 //If useKeychainPersistance is true, network requests will attempt to read credentials from the keychain, and will save them in the keychain when they are successfully presented
33 BOOL useKeychainPersistance; 36 BOOL useKeychainPersistance;
34 37
@@ -72,11 +75,15 @@ @@ -72,11 +75,15 @@
72 CFReadStreamRef readStream; 75 CFReadStreamRef readStream;
73 76
74 // Authentication currently being used for prompting and resuming 77 // Authentication currently being used for prompting and resuming
75 - CFHTTPAuthenticationRef authentication; 78 + CFHTTPAuthenticationRef requestAuthentication;
  79 + NSMutableDictionary *requestCredentials;
76 80
77 // Credentials associated with the authentication (reused until server says no) 81 // Credentials associated with the authentication (reused until server says no)
78 //CFMutableDictionaryRef credentials; 82 //CFMutableDictionaryRef credentials;
79 83
  84 + // HTTP status code, eg: 200 = OK, 404 = Not found etc
  85 + int responseStatusCode;
  86 +
80 //Size of the response 87 //Size of the response
81 double contentLength; 88 double contentLength;
82 89
@@ -103,8 +110,6 @@ @@ -103,8 +110,6 @@
103 //Called on the delegate when the request fails 110 //Called on the delegate when the request fails
104 SEL didFailSelector; 111 SEL didFailSelector;
105 112
106 - NSDictionary *responseHeaders;  
107 - NSMutableDictionary *requestCredentials;  
108 113
109 } 114 }
110 115
@@ -113,9 +118,6 @@ @@ -113,9 +118,6 @@
113 // Should be an HTTP or HTTPS url, may include username and password if appropriate 118 // Should be an HTTP or HTTPS url, may include username and password if appropriate
114 - (id)initWithURL:(NSURL *)newURL; 119 - (id)initWithURL:(NSURL *)newURL;
115 120
116 -#pragma mark delegate configuration  
117 -  
118 -  
119 #pragma mark setup request 121 #pragma mark setup request
120 122
121 //Add a custom header to the request 123 //Add a custom header to the request
@@ -159,10 +161,10 @@ @@ -159,10 +161,10 @@
159 161
160 #pragma mark handling request complete / failure 162 #pragma mark handling request complete / failure
161 163
162 -//Called when a request completes successfully - defaults to: @selector(requestFinished:) 164 +// Called when a request completes successfully - defaults to: @selector(requestFinished:)
163 - (void)requestFinished; 165 - (void)requestFinished;
164 166
165 -//Called when a request fails - defaults to: @selector(requestFailed:) 167 +// Called when a request fails - defaults to: @selector(requestFailed:)
166 - (void)failWithProblem:(NSString *)problem; 168 - (void)failWithProblem:(NSString *)problem;
167 169
168 #pragma mark http authentication stuff 170 #pragma mark http authentication stuff
@@ -170,6 +172,12 @@ @@ -170,6 +172,12 @@
170 // Reads the response headers to find the content length, and returns true if the request needs a username and password (or if those supplied were incorrect) 172 // Reads the response headers to find the content length, and returns true if the request needs a username and password (or if those supplied were incorrect)
171 - (BOOL)readResponseHeadersReturningAuthenticationFailure; 173 - (BOOL)readResponseHeadersReturningAuthenticationFailure;
172 174
  175 +// Apply credentials to this request
  176 +- (BOOL)applyCredentials:(NSMutableDictionary *)newCredentials;
  177 +
  178 +// Attempt to obtain credentials for this request from the URL, username and password or keychain
  179 +- (NSMutableDictionary *)findCredentials;
  180 +
173 // Unlock (unpause) the request thread so it can resume the request 181 // Unlock (unpause) the request thread so it can resume the request
174 // Should be called by delegates when they have populated the authentication information after an authentication challenge 182 // Should be called by delegates when they have populated the authentication information after an authentication challenge
175 - (void)retryWithAuthentication; 183 - (void)retryWithAuthentication;
@@ -188,16 +196,23 @@ @@ -188,16 +196,23 @@
188 - (void)handleStreamComplete; 196 - (void)handleStreamComplete;
189 - (void)handleStreamError; 197 - (void)handleStreamError;
190 198
  199 +#pragma mark managing the session
  200 +
  201 ++ (void)setSessionCredentials:(NSMutableDictionary *)newCredentials;
  202 ++ (void)setSessionAuthentication:(CFHTTPAuthenticationRef)newAuthentication;
191 203
192 #pragma mark keychain storage 204 #pragma mark keychain storage
193 205
194 -//Save credentials to the keychain 206 +// Save credentials for this request to the keychain
  207 +- (void)saveCredentialsToKeychain:(NSMutableDictionary *)newCredentials;
  208 +
  209 +// Save creddentials to the keychain
195 + (void)saveCredentials:(NSURLCredential *)credentials forHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm; 210 + (void)saveCredentials:(NSURLCredential *)credentials forHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm;
196 211
197 -//Return credentials from the keychain 212 +// Return credentials from the keychain
198 + (NSURLCredential *)savedCredentialsForHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm; 213 + (NSURLCredential *)savedCredentialsForHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm;
199 214
200 -//Remove credentials from the keychain 215 +// Remove credentials from the keychain
201 + (void)removeCredentialsForHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm; 216 + (void)removeCredentialsForHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm;
202 217
203 218
@@ -215,9 +230,7 @@ @@ -215,9 +230,7 @@
215 @property (assign,readonly) BOOL complete; 230 @property (assign,readonly) BOOL complete;
216 @property (retain) NSDictionary *responseHeaders; 231 @property (retain) NSDictionary *responseHeaders;
217 @property (retain) NSDictionary *requestCredentials; 232 @property (retain) NSDictionary *requestCredentials;
218 - 233 +@property (assign) int responseStatusCode;
219 -- (void)saveCredentialsToKeychain:(NSMutableDictionary *)newCredentials;  
220 -- (BOOL)applyCredentials:(NSMutableDictionary *)newCredentials;  
221 234
222 235
223 @end 236 @end
@@ -33,12 +33,6 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -33,12 +33,6 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
33 33
34 - (id)initWithURL:(NSURL *)newURL 34 - (id)initWithURL:(NSURL *)newURL
35 { 35 {
36 - [self init];  
37 - url = [newURL retain];  
38 - return self;  
39 -}  
40 -  
41 -- (id)init {  
42 [super init]; 36 [super init];
43 lastBytesSent = 0; 37 lastBytesSent = 0;
44 postData = nil; 38 postData = nil;
@@ -48,7 +42,7 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -48,7 +42,7 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
48 requestHeaders = nil; 42 requestHeaders = nil;
49 authenticationRealm = nil; 43 authenticationRealm = nil;
50 outputStream = nil; 44 outputStream = nil;
51 - authentication = NULL; 45 + requestAuthentication = NULL;
52 //credentials = NULL; 46 //credentials = NULL;
53 request = NULL; 47 request = NULL;
54 responseHeaders = nil; 48 responseHeaders = nil;
@@ -57,13 +51,14 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -57,13 +51,14 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
57 didFinishSelector = @selector(requestFinished:); 51 didFinishSelector = @selector(requestFinished:);
58 didFailSelector = @selector(requestFailed:); 52 didFailSelector = @selector(requestFailed:);
59 delegate = nil; 53 delegate = nil;
60 - return self; 54 + url = [newURL retain];
  55 + return self;
61 } 56 }
62 57
63 - (void)dealloc 58 - (void)dealloc
64 { 59 {
65 - if (authentication) { 60 + if (requestAuthentication) {
66 - CFRelease(authentication); 61 + CFRelease(requestAuthentication);
67 } 62 }
68 if (request) { 63 if (request) {
69 CFRelease(request); 64 CFRelease(request);
@@ -146,12 +141,6 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -146,12 +141,6 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
146 141
147 #pragma mark request logic 142 #pragma mark request logic
148 143
149 -+ (void)setSessionCredentials:(NSMutableDictionary *)newCredentials  
150 -{  
151 - [sessionCredentials release];  
152 - sessionCredentials = [newCredentials retain];  
153 -}  
154 -  
155 // Create the request 144 // Create the request
156 - (void)main 145 - (void)main
157 { 146 {
@@ -173,8 +162,7 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -173,8 +162,7 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
173 //If we've already talked to this server and have valid credentials, let's apply them to the request 162 //If we've already talked to this server and have valid credentials, let's apply them to the request
174 if (useSessionPersistance && sessionCredentials && sessionAuthentication) { 163 if (useSessionPersistance && sessionCredentials && sessionAuthentication) {
175 if (!CFHTTPMessageApplyCredentialDictionary(request, sessionAuthentication, (CFMutableDictionaryRef)sessionCredentials, NULL)) { 164 if (!CFHTTPMessageApplyCredentialDictionary(request, sessionAuthentication, (CFMutableDictionaryRef)sessionCredentials, NULL)) {
176 - CFRelease(sessionAuthentication); 165 + [ASIHTTPRequest setSessionAuthentication:NULL];
177 - sessionAuthentication = NULL;  
178 [ASIHTTPRequest setSessionCredentials:nil]; 166 [ASIHTTPRequest setSessionCredentials:nil];
179 } 167 }
180 } 168 }
@@ -415,9 +403,10 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -415,9 +403,10 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
415 CFHTTPMessageRef headers = (CFHTTPMessageRef)CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPResponseHeader); 403 CFHTTPMessageRef headers = (CFHTTPMessageRef)CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPResponseHeader);
416 if (CFHTTPMessageIsHeaderComplete(headers)) { 404 if (CFHTTPMessageIsHeaderComplete(headers)) {
417 responseHeaders = (NSDictionary *)CFHTTPMessageCopyAllHeaderFields(headers); 405 responseHeaders = (NSDictionary *)CFHTTPMessageCopyAllHeaderFields(headers);
418 - 406 + responseStatusCode = CFHTTPMessageGetResponseStatusCode(headers);
  407 +
419 // Is the server response a challenge for credentials? 408 // Is the server response a challenge for credentials?
420 - isAuthenticationChallenge = (CFHTTPMessageGetResponseStatusCode(headers) == 401); 409 + isAuthenticationChallenge = (responseStatusCode == 401);
421 410
422 //We won't reset the download progress delegate if we got an authentication challenge 411 //We won't reset the download progress delegate if we got an authentication challenge
423 if (!isAuthenticationChallenge) { 412 if (!isAuthenticationChallenge) {
@@ -438,13 +427,6 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -438,13 +427,6 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
438 } 427 }
439 428
440 429
441 -// Called by delegate to resume loading once authentication info has been populated  
442 -- (void)retryWithAuthentication  
443 -{  
444 - [authenticationLock lockWhenCondition:1];  
445 - [authenticationLock unlockWithCondition:2];  
446 -}  
447 -  
448 - (void)saveCredentialsToKeychain:(NSMutableDictionary *)newCredentials 430 - (void)saveCredentialsToKeychain:(NSMutableDictionary *)newCredentials
449 { 431 {
450 NSURLCredential *authenticationCredentials = [NSURLCredential credentialWithUser:[newCredentials objectForKey:(NSString *)kCFHTTPAuthenticationUsername] 432 NSURLCredential *authenticationCredentials = [NSURLCredential credentialWithUser:[newCredentials objectForKey:(NSString *)kCFHTTPAuthenticationUsername]
@@ -458,20 +440,16 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -458,20 +440,16 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
458 - (BOOL)applyCredentials:(NSMutableDictionary *)newCredentials 440 - (BOOL)applyCredentials:(NSMutableDictionary *)newCredentials
459 { 441 {
460 442
461 - if (newCredentials && authentication && request) { 443 + if (newCredentials && requestAuthentication && request) {
462 // Apply whatever credentials we've built up to the old request 444 // Apply whatever credentials we've built up to the old request
463 - if (CFHTTPMessageApplyCredentialDictionary(request, authentication, (CFMutableDictionaryRef)newCredentials, NULL)) { 445 + if (CFHTTPMessageApplyCredentialDictionary(request, requestAuthentication, (CFMutableDictionaryRef)newCredentials, NULL)) {
464 //If we have credentials and they're ok, let's save them to the keychain 446 //If we have credentials and they're ok, let's save them to the keychain
465 if (useKeychainPersistance) { 447 if (useKeychainPersistance) {
466 [self saveCredentialsToKeychain:newCredentials]; 448 [self saveCredentialsToKeychain:newCredentials];
467 } 449 }
468 if (useSessionPersistance) { 450 if (useSessionPersistance) {
469 - if (sessionAuthentication) {  
470 - CFRelease(sessionAuthentication);  
471 - }  
472 - sessionAuthentication = authentication;  
473 - CFRetain(sessionAuthentication);  
474 451
  452 + [ASIHTTPRequest setSessionAuthentication:requestAuthentication];
475 [ASIHTTPRequest setSessionCredentials:newCredentials]; 453 [ASIHTTPRequest setSessionCredentials:newCredentials];
476 } 454 }
477 [self setRequestCredentials:newCredentials]; 455 [self setRequestCredentials:newCredentials];
@@ -481,15 +459,15 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -481,15 +459,15 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
481 return FALSE; 459 return FALSE;
482 } 460 }
483 461
484 -- (NSMutableDictionary *)getCredentials 462 +- (NSMutableDictionary *)findCredentials
485 { 463 {
486 NSMutableDictionary *newCredentials = [[[NSMutableDictionary alloc] init] autorelease]; 464 NSMutableDictionary *newCredentials = [[[NSMutableDictionary alloc] init] autorelease];
487 465
488 // Get the authentication realm 466 // Get the authentication realm
489 [authenticationRealm release]; 467 [authenticationRealm release];
490 authenticationRealm = nil; 468 authenticationRealm = nil;
491 - if (!CFHTTPAuthenticationRequiresAccountDomain(authentication)) { 469 + if (!CFHTTPAuthenticationRequiresAccountDomain(requestAuthentication)) {
492 - authenticationRealm = (NSString *)CFHTTPAuthenticationCopyRealm(authentication); 470 + authenticationRealm = (NSString *)CFHTTPAuthenticationCopyRealm(requestAuthentication);
493 } 471 }
494 472
495 //First, let's look at the url to see if the username and password were included 473 //First, let's look at the url to see if the username and password were included
@@ -519,30 +497,37 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -519,30 +497,37 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
519 [newCredentials setObject:pass forKey:(NSString *)kCFHTTPAuthenticationPassword]; 497 [newCredentials setObject:pass forKey:(NSString *)kCFHTTPAuthenticationPassword];
520 return newCredentials; 498 return newCredentials;
521 } 499 }
522 - return NULL; 500 + return nil;
  501 +}
  502 +
  503 +// Called by delegate to resume loading once authentication info has been populated
  504 +- (void)retryWithAuthentication
  505 +{
  506 + [authenticationLock lockWhenCondition:1];
  507 + [authenticationLock unlockWithCondition:2];
523 } 508 }
524 509
525 - (void)attemptToApplyCredentialsAndResume 510 - (void)attemptToApplyCredentialsAndResume
526 { 511 {
527 512
528 //Read authentication data 513 //Read authentication data
529 - if (!authentication) { 514 + if (!requestAuthentication) {
530 CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader); 515 CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader);
531 - authentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader); 516 + requestAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader);
532 CFRelease(responseHeader); 517 CFRelease(responseHeader);
533 } 518 }
534 519
535 - if (!authentication) { 520 + if (!requestAuthentication) {
536 [self failWithProblem:@"Failed to get authentication object from response headers"]; 521 [self failWithProblem:@"Failed to get authentication object from response headers"];
537 return; 522 return;
538 } 523 }
539 524
540 //See if authentication is valid 525 //See if authentication is valid
541 CFStreamError err; 526 CFStreamError err;
542 - if (!CFHTTPAuthenticationIsValid(authentication, &err)) { 527 + if (!CFHTTPAuthenticationIsValid(requestAuthentication, &err)) {
543 528
544 - CFRelease(authentication); 529 + CFRelease(requestAuthentication);
545 - authentication = NULL; 530 + requestAuthentication = NULL;
546 531
547 // check for bad credentials, so we can give the delegate a chance to replace them 532 // check for bad credentials, so we can give the delegate a chance to replace them
548 if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName || err.error == kCFStreamErrorHTTPAuthenticationBadPassword)) { 533 if (err.domain == kCFStreamErrorDomainHTTP && (err.error == kCFStreamErrorHTTPAuthenticationBadUserName || err.error == kCFStreamErrorHTTPAuthenticationBadPassword)) {
@@ -572,9 +557,9 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -572,9 +557,9 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
572 } 557 }
573 558
574 // are a user name & password needed? 559 // are a user name & password needed?
575 - } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(authentication)) { 560 + } else if (CFHTTPAuthenticationRequiresUserNameAndPassword(requestAuthentication)) {
576 561
577 - NSMutableDictionary *newCredentials = [self getCredentials]; 562 + NSMutableDictionary *newCredentials = [self findCredentials];
578 563
579 //If we have some credentials to use let's apply them to the request and continue 564 //If we have some credentials to use let's apply them to the request and continue
580 if (newCredentials) { 565 if (newCredentials) {
@@ -714,6 +699,24 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -714,6 +699,24 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
714 } 699 }
715 } 700 }
716 701
  702 +#pragma mark managing the session
  703 +
  704 ++ (void)setSessionCredentials:(NSMutableDictionary *)newCredentials
  705 +{
  706 + [sessionCredentials release];
  707 + sessionCredentials = [newCredentials retain];
  708 +}
  709 +
  710 ++ (void)setSessionAuthentication:(CFHTTPAuthenticationRef)newAuthentication
  711 +{
  712 + if (sessionAuthentication) {
  713 + CFRelease(sessionAuthentication);
  714 + }
  715 + sessionAuthentication = newAuthentication;
  716 + if (newAuthentication) {
  717 + CFRetain(sessionAuthentication);
  718 + }
  719 +}
717 720
718 #pragma mark keychain storage 721 #pragma mark keychain storage
719 722
@@ -774,4 +777,5 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy @@ -774,4 +777,5 @@ static void ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventTy
774 @synthesize complete; 777 @synthesize complete;
775 @synthesize responseHeaders; 778 @synthesize responseHeaders;
776 @synthesize requestCredentials; 779 @synthesize requestCredentials;
  780 +@synthesize responseStatusCode;
777 @end 781 @end
  1 +//
  2 +// ASIHTTPRequestTests.h
  3 +// asi-http-request
  4 +//
  5 +// Created by Ben Copsey on 01/08/2008.
  6 +// Copyright 2008 All-Seeing Interactive. All rights reserved.
  7 +//
  8 +
  9 +#import <SenTestingKit/SenTestingKit.h>
  10 +
  11 +
  12 +@interface ASIHTTPRequestTests : SenTestCase {
  13 +}
  14 +
  15 +- (void)testBasicDownload;
  16 +
  17 +@end
  1 +//
  2 +// ASIHTTPRequestTests.m
  3 +// asi-http-request
  4 +//
  5 +// Created by Ben Copsey on 01/08/2008.
  6 +// Copyright 2008 All-Seeing Interactive. All rights reserved.
  7 +//
  8 +
  9 +#import "ASIHTTPRequestTests.h"
  10 +#import "ASIHTTPRequest.h"
  11 +
  12 +@implementation ASIHTTPRequestTests
  13 +
  14 +- (void)testBasicDownload
  15 +{
  16 + //Grab data
  17 + NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
  18 + ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
  19 + [request start];
  20 + NSString *html = [request dataString];
  21 + STAssertNotNil(html,@"Basic synchronous request failed");
  22 +
  23 + //Check we're getting the correct response headers
  24 + NSString *pingBackHeader = [[request responseHeaders] objectForKey:@"X-Pingback"];
  25 + BOOL success = [pingBackHeader isEqualToString:@"http://allseeing-i.com/Ping-Back"];
  26 + STAssertTrue(success,@"Failed to populate response headers");
  27 +
  28 + //Check we're getting back the correct status code
  29 + url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/a-page-that-does-not-exist"] autorelease];
  30 + request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
  31 + [request start];
  32 + success = ([request responseStatusCode] == 404);
  33 + STAssertTrue(success,@"Didn't get correct status code");
  34 +
  35 + //Check data
  36 + NSRange notFound = NSMakeRange(NSNotFound, 0);
  37 + success = !NSEqualRanges([html rangeOfString:@"All-Seeing Interactive"],notFound);
  38 + STAssertTrue(success,@"Failed to download the correct data");
  39 +
  40 + //Attempt to grab from bad url (astonishingly, there is a website at http://aaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com !)
  41 + url = [[[NSURL alloc] initWithString:@"http://aaaaaaaaaaaaaaaaaaaaaaaaaaaaab.com"] autorelease];
  42 + request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
  43 + [request start];
  44 + NSError *error = [request error];
  45 + STAssertNotNil(error,@"Failed to generate an error for a bad host");
  46 +}
  47 +
  48 +@end
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>English</string>
  7 + <key>CFBundleExecutable</key>
  8 + <string>${EXECUTABLE_NAME}</string>
  9 + <key>CFBundleIdentifier</key>
  10 + <string>com.yourcompany.${PRODUCT_NAME:identifier}</string>
  11 + <key>CFBundleInfoDictionaryVersion</key>
  12 + <string>6.0</string>
  13 + <key>CFBundlePackageType</key>
  14 + <string>BNDL</string>
  15 + <key>CFBundleSignature</key>
  16 + <string>????</string>
  17 + <key>CFBundleVersion</key>
  18 + <string>1.0</string>
  19 +</dict>
  20 +</plist>
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff was suppressed by a .gitattributes entry.