Statistics
| Branch: | Revision:

root / asi-http-request-with-pithos / Classes / Tests / ASIHTTPRequestTests.m @ cc176feb

History | View | Annotate | Download (85 kB)

1
//
2
//  ASIHTTPRequestTests.m
3
//  Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
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
#import "ASINetworkQueue.h"
12
#import "ASIFormDataRequest.h"
13
#import <SystemConfiguration/SystemConfiguration.h>
14
#import <unistd.h>
15

    
16
// Used for subclass test
17
@interface ASIHTTPRequestSubclass : ASIHTTPRequest {}
18
@end
19
@implementation ASIHTTPRequestSubclass;
20

    
21
// For testing exceptions are caught
22
- (void)startRequest
23
{
24
	[[NSException exceptionWithName:@"Test Exception" reason:@"Test Reason" userInfo:nil] raise];
25
}
26
@end
27

    
28

    
29
// Stop clang complaining about undeclared selectors
30
@interface ASIHTTPRequestTests ()
31
- (void)runCancelTest;
32
- (void)performDelegateMethodsTest;
33
- (void)requestStarted:(ASIHTTPRequest *)request;
34
- (void)requestFinished:(ASIHTTPRequest *)request;
35
- (void)requestFailed:(ASIHTTPRequest *)request;
36
- (void)delegateTestStarted:(ASIHTTPRequest *)request;
37
- (void)delegateTestResponseHeaders:(ASIHTTPRequest *)request;
38
- (void)delegateTestFinished:(ASIHTTPRequest *)request;
39
- (void)delegateTestFailed:(ASIHTTPRequest *)request;
40
- (void)runRemoveUploadProgressTest;
41
- (void)runRedirectedResume;
42
- (void)performDownloadProgressTest;
43
- (void)theTestRequest:(ASIHTTPRequest *)request didReceiveData:(NSData *)data;
44
- (void)theTestRequestFinished:(ASIHTTPRequest *)request;
45
- (void)performUploadProgressTest;
46
- (void)performPostBodyStreamedFromDiskTest;
47
- (void)performPartialFetchTest;
48
- (void)asyncFail:(ASIHTTPRequest *)request;
49
- (void)asyncSuccess:(ASIHTTPRequest *)request;
50
- (void)request:(ASIHTTPRequest *)request isGoingToRedirectToURL:(NSURL *)url;
51
- (void)redirectURLTestFailed:(ASIHTTPRequest *)request;
52
- (void)redirectURLTestSucceeded:(ASIHTTPRequest *)request;
53
@end
54

    
55
@implementation ASIHTTPRequestTests
56

    
57
- (void)testBasicDownload
58
{
59
	NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
60
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
61
	[request startSynchronous];
62
	NSString *html = [request responseString];
63
	GHAssertNotNil(html,@"Basic synchronous request failed");
64

    
65
	// Check we're getting the correct response headers
66
	NSString *pingBackHeader = [[request responseHeaders] objectForKey:@"X-Pingback"];
67
	BOOL success = [pingBackHeader isEqualToString:@"http://allseeing-i.com/Ping-Back"];
68
	GHAssertTrue(success,@"Failed to populate response headers");
69
	
70
	// Check we're getting back the correct status code
71
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/a-page-that-does-not-exist"] autorelease];
72
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
73
	[request startSynchronous];
74
	success = ([request responseStatusCode] == 404);
75
	GHAssertTrue(success,@"Didn't get correct status code");	
76
	
77
	// Check data is as expected
78
	NSRange notFound = NSMakeRange(NSNotFound, 0);
79
	success = !NSEqualRanges([html rangeOfString:@"All-Seeing Interactive"],notFound);
80
	GHAssertTrue(success,@"Failed to download the correct data");
81
	
82
	// Attempt to grab from bad url
83
	url = [[[NSURL alloc] initWithString:@""] autorelease];
84
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
85
	[request startSynchronous];
86
	success = [[request error] code] == ASIInternalErrorWhileBuildingRequestType;
87
	GHAssertTrue(success,@"Failed to generate an error for a bad host");
88
	
89
	request = [[[ASIHTTPRequest alloc] initWithURL:nil] autorelease];
90
	[request startSynchronous];
91
	success = [[request error] code] == ASIUnableToCreateRequestErrorType;
92
	GHAssertTrue(success,@"Failed to generate an error for a bad host");
93
}
94

    
95
- (void)testBase64Encode
96
{
97
	NSData *data = [@"Hello, world" dataUsingEncoding:NSUTF8StringEncoding];
98
	NSString *base64 = [ASIHTTPRequest base64forData:data];
99
	BOOL success = [base64 isEqualToString:@"SGVsbG8sIHdvcmxk"];
100
	GHAssertTrue(success,@"Failed to encode data using base64 data correctly");
101
}
102

    
103
- (void)testCancel
104
{
105
	// We run this test on the main thread because otherwise we can't depend on the  delegate being notified before we need to test it's working
106
	[self performSelectorOnMainThread:@selector(runCancelTest) withObject:nil waitUntilDone:YES];
107

    
108
}
109

    
110
- (void)runCancelTest
111
{
112
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel_%28abridged%29.txt"]];
113
	[request startAsynchronous];
114
	[request cancel];
115
	[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
116
	GHAssertNotNil([request error],@"Failed to cancel the request");
117
	
118
	// Test cancelling a redirected request works
119
	// This test is probably unreliable on very slow or very fast connections, as it depends on being able to complete the first request (but not the second) in under 2 seconds
120
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/cancel_redirect"]];
121
	[request startAsynchronous];
122
	
123
	[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
124
	[request cancel];
125
	[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
126
	
127
	BOOL success = ([[[request url] absoluteString] isEqualToString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel.txt"]);
128

    
129
	GHAssertTrue(success, @"Request did not redirect quickly enough, cannot proceed with test");
130
	
131
	GHAssertNotNil([request error],@"Failed to cancel the request");	 
132
	
133
	success = [request totalBytesRead] < 7900198;
134
	GHAssertTrue(success, @"Downloaded the whole of the response even though we should have cancelled by now");
135
	
136

    
137
}
138

    
139

    
140

    
141
- (void)testDelegateMethods
142
{
143
	// We run this test on the main thread because otherwise we can't depend on the  delegate being notified before we need to test it's working
144
	[self performSelectorOnMainThread:@selector(performDelegateMethodsTest) withObject:nil waitUntilDone:YES];
145
}
146

    
147
- (void)performDelegateMethodsTest
148
{
149
	started = NO;
150
	finished = NO;
151
	failed = NO;
152
	
153
	// Test default delegate methods
154
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
155
	[request setDelegate:self];
156
	[request startSynchronous];
157

    
158
	
159
	GHAssertTrue(started,@"Failed to call the delegate method when the request started");	
160
	GHAssertTrue(receivedResponseHeaders,@"Failed to call the delegate method when the request started");	
161
	GHAssertTrue(finished,@"Failed to call the delegate method when the request finished");
162
	
163
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel.txt"]];
164
	[request setDelegate:self];
165
	[request setTimeOutSeconds:0.01];
166
	[request startSynchronous];
167
	
168
	GHAssertTrue(failed,@"Failed to call the delegate method when the request failed");
169
	
170
	started = NO;
171
	finished = NO;
172
	failed = NO;
173
	receivedResponseHeaders = NO;
174
	
175
	// Test custom delegate methods
176
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
177
	[request setDelegate:self];
178
	[request setDidStartSelector:@selector(delegateTestStarted:)];
179
	[request setDidReceiveResponseHeadersSelector:@selector(delegateTestResponseHeaders:)];
180
	[request setDidFinishSelector:@selector(delegateTestFinished:)];
181
	[request startSynchronous];
182
	
183

    
184
	GHAssertTrue(started,@"Failed to call the delegate method when the request started");	
185
	GHAssertTrue(finished,@"Failed to call the delegate method when the request finished");
186
	
187
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel.txt"]];
188
	[request setDidFailSelector:@selector(delegateTestFailed:)];
189
	[request setDelegate:self];
190
	[request setTimeOutSeconds:0.01];
191
	[request startSynchronous];
192
	
193
	GHAssertTrue(failed,@"Failed to call the delegate method when the request failed");
194
	
195
}
196

    
197
- (void)requestStarted:(ASIHTTPRequest *)request
198
{
199
	started = YES;
200
}
201

    
202
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)newResponseHeaders
203
{
204
	GHAssertNotNil(newResponseHeaders,@"Called request:didReceiveResponseHeaders: when we have no headers");
205
	receivedResponseHeaders = YES;
206
}
207

    
208

    
209
- (void)requestFinished:(ASIHTTPRequest *)request
210
{
211
	finished = YES;
212
}
213

    
214
- (void)requestFailed:(ASIHTTPRequest *)request
215
{
216
	failed = YES;
217
}
218

    
219
- (void)delegateTestStarted:(ASIHTTPRequest *)request
220
{
221
	started = YES;
222
}
223

    
224
- (void)delegateTestResponseHeaders:(ASIHTTPRequest *)request
225
{
226
	GHAssertNotNil([request responseHeaders],@"Called delegateTestResponseHeaders: when we have no headers");
227
	receivedResponseHeaders = YES;
228
}
229

    
230
- (void)delegateTestFinished:(ASIHTTPRequest *)request
231
{
232
	finished = YES;
233
}
234

    
235
- (void)delegateTestFailed:(ASIHTTPRequest *)request
236
{
237
	failed = YES;
238
}
239

    
240
- (void)testConditionalGET
241
{
242
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/i/logo.png"]];
243
	[request startSynchronous];
244
	BOOL success = ([request responseStatusCode] == 200);
245
	GHAssertTrue(success, @"Failed to download file, cannot proceed with this test");
246
	success = ([[request responseData] length] > 0);
247
	GHAssertTrue(success, @"Response length is 0, this shouldn't happen");
248
	
249
	NSString *etag = [[request responseHeaders] objectForKey:@"Etag"];
250
	NSString *lastModified = [[request responseHeaders] objectForKey:@"Last-Modified"];
251
	
252
	GHAssertNotNil(etag, @"Response didn't return an etag");
253
	GHAssertNotNil(lastModified, @"Response didn't return a last modified date");
254
	
255
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/i/logo.png"]];
256
	[request addRequestHeader:@"If-Modified-Since" value:lastModified];
257
	[request addRequestHeader:@"If-None-Match" value:etag];
258
	[request startSynchronous];
259
	success = ([request responseStatusCode] == 304);
260
	GHAssertTrue(success, @"Got wrong status code");
261
	success = ([[request responseData] length] == 0);
262
	GHAssertTrue(success, @"Response length is not 0, this shouldn't happen");
263
	
264
}
265

    
266
- (void)testException
267
{
268
	ASIHTTPRequestSubclass *request = [ASIHTTPRequestSubclass requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
269
	[request startSynchronous];
270
	NSError *error = [request error];
271
	GHAssertNotNil(error,@"Failed to generate an error for an exception");
272
	
273
	BOOL success = [[[error userInfo] objectForKey:NSLocalizedDescriptionKey] isEqualToString:@"Test Exception"];
274
	GHAssertTrue(success, @"Generated wrong error for exception");
275
	
276
}
277

    
278
- (void)testCharacterEncoding
279
{
280
	
281
	NSArray *IANAEncodings = [NSArray arrayWithObjects:@"UTF-8",@"US-ASCII",@"ISO-8859-1",@"UTF-16",nil];
282
	NSUInteger NSStringEncodings[] = {NSUTF8StringEncoding,NSASCIIStringEncoding,NSISOLatin1StringEncoding,NSUnicodeStringEncoding};
283
	
284
	NSUInteger i;
285
	for (i=0; i<[IANAEncodings count]; i++) {
286
		NSURL *url = [[[NSURL alloc] initWithString:[NSString stringWithFormat:@"http://allseeing-i.com/ASIHTTPRequest/tests/Character-Encoding/%@",[IANAEncodings objectAtIndex:i]]] autorelease];
287
		ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
288
		[request startSynchronous];
289
		BOOL success = [request responseEncoding] == NSStringEncodings[i];
290
		GHAssertTrue(success,[NSString stringWithFormat:@"Failed to use the correct text encoding for %@i",[IANAEncodings objectAtIndex:i]]);
291
	}
292
					 
293
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/Character-Encoding/Something-else"] autorelease];
294
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
295
	[request setDefaultResponseEncoding:NSWindowsCP1251StringEncoding];
296
	[request startSynchronous];
297
	BOOL success = [request responseEncoding] == [request defaultResponseEncoding];
298
	GHAssertTrue(success,[NSString stringWithFormat:@"Failed to use the default string encoding"]);
299
	
300
	// Will return a Content-Type header with charset in the middle of the value (Fix contributed by Roman Busyghin)
301
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/Character-Encoding/utf-16-with-type-header"] autorelease];
302
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
303
	[request startSynchronous];
304
	success = [request responseEncoding] == NSUnicodeStringEncoding;
305
	GHAssertTrue(success,[NSString stringWithFormat:@"Failed to parse the content type header correctly"]);
306
}
307

    
308
- (void)testTimeOut
309
{
310
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel_%28abridged%29.txt"] autorelease];
311
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
312
	[request setTimeOutSeconds:0.0001]; //It's pretty unlikely we will be able to grab the data this quickly, so the request should timeout
313
	[request startSynchronous];
314
	
315
	BOOL success = [[request error] code] == ASIRequestTimedOutErrorType;
316
	GHAssertTrue(success,@"Timeout didn't generate the correct error");
317
	
318
	[ASIHTTPRequest setDefaultTimeOutSeconds:0.0001];
319
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
320
	[request startSynchronous];
321
	
322
	success = [[request error] code] == ASIRequestTimedOutErrorType;
323
	GHAssertTrue(success,@"Failed to change the default timeout");	
324
	
325
	[ASIHTTPRequest setDefaultTimeOutSeconds:10];
326
}
327

    
328

    
329
// Test fix for a bug that might have caused timeouts when posting data
330
- (void)testTimeOutWithoutDownloadDelegate
331
{
332
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel_%28young_readers_edition%29.txt"]];
333
	[request setTimeOutSeconds:5];
334
	[request setShowAccurateProgress:NO];
335
	[request setPostBody:[NSMutableData dataWithData:[@"Small Body" dataUsingEncoding:NSUTF8StringEncoding]]];
336
	[request startSynchronous];
337
	
338
	GHAssertNil([request error],@"Generated an error (most likely a timeout) - this test might fail on high latency connections");	
339
}
340

    
341

    
342
- (void)testRequestMethod
343
{
344
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/request-method"] autorelease];
345
	NSArray *methods = [[[NSArray alloc] initWithObjects:@"GET",@"POST",@"PUT",@"DELETE", nil] autorelease];
346
	for (NSString *method in methods) {
347
		ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
348
		[request setRequestMethod:method];
349
		[request startSynchronous];
350
		BOOL success = [[request responseString] isEqualToString:method];
351
		GHAssertTrue(success,@"Failed to set the request method correctly");	
352
	}
353
	
354
	// Test to ensure we don't change the request method when we have an unrecognised method already set
355
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
356
	[request setRequestMethod:@"FINK"];
357
	[request appendPostData:[@"King" dataUsingEncoding:NSUTF8StringEncoding]];
358
	[request buildPostBody];
359
	BOOL success = [[request requestMethod] isEqualToString:@"FINK"];
360
	GHAssertTrue(success,@"Erroneously changed request method");	
361
}
362

    
363
- (void)testHTTPVersion
364
{
365
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/http-version"] autorelease];
366
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
367
	[request startSynchronous];
368
	
369
	BOOL success = [[request responseString] isEqualToString:@"HTTP/1.1"];
370
	GHAssertTrue(success,@"Wrong HTTP version used (May fail when using a proxy that changes the HTTP version!)");
371
	
372
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
373
	[request setUseHTTPVersionOne:YES];
374
	[request startSynchronous];
375
	
376
	success = [[request responseString] isEqualToString:@"HTTP/1.0"];
377
	GHAssertTrue(success,@"Wrong HTTP version used (May fail when using a proxy that changes the HTTP version!)");	
378
}
379

    
380
- (void)testUserAgent
381
{
382
	// defaultUserAgentString will be nil if we haven't set a Bundle Name or Bundle Display Name
383
	if ([ASIHTTPRequest defaultUserAgentString]) {
384
		
385
		// Returns the user agent it received in the response body
386
		ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
387
		[request startSynchronous];
388
		BOOL success = [[request responseString] isEqualToString:[ASIHTTPRequest defaultUserAgentString]];
389
		GHAssertTrue(success,@"Failed to set the correct user agent");
390
	}
391

    
392
	NSString *customUserAgent = @"Ferdinand Fuzzworth's Magic Tent of Mystery";
393

    
394
	// Test specifying a custom user-agent for a single request
395
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
396
	[request addRequestHeader:@"User-Agent" value:customUserAgent];
397
	[request startSynchronous];
398
	BOOL success = [[request responseString] isEqualToString:customUserAgent];
399
	GHAssertTrue(success,@"Failed to set the correct user-agent for a single request");
400

    
401
	// Test again using userAgent
402
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
403
	[request setUserAgentString:customUserAgent];
404
	[request startSynchronous];
405
	success = [[request responseString] isEqualToString:customUserAgent];
406
	GHAssertTrue(success,@"Failed to set the correct user-agent for a single request");
407

    
408
	// Test again to ensure user-agent not reused
409
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
410
	[request startSynchronous];
411
	success = ![[request responseString] isEqualToString:customUserAgent];
412
	GHAssertTrue(success,@"Re-used a user agent when we shouldn't have done so");
413

    
414
	// Test setting a custom default user-agent string
415
	[ASIHTTPRequest setDefaultUserAgentString:customUserAgent];
416
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
417
	[request startSynchronous];
418
	success = [[request responseString] isEqualToString:customUserAgent];
419
	GHAssertTrue(success,@"Failed to set the correct user-agent when using a custom default");
420

    
421
	[ASIHTTPRequest setDefaultUserAgentString:nil];
422
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/user-agent"]];
423
	[request startSynchronous];
424
	success = ![[request responseString] isEqualToString:customUserAgent];
425
	GHAssertTrue(success,@"Failed to clear a custom default user-agent");
426
}
427

    
428
- (void)testAutomaticRedirection
429
{
430
	ASIHTTPRequest *request;
431
	ASIFormDataRequest *request2;
432
	BOOL success;
433
	unsigned int i;
434
	for (i=301; i<308; i++) {
435
		
436
		if (i > 304 && i < 307) {
437
			continue;
438
		}
439
		NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect/%hi",i]];
440
		request = [ASIHTTPRequest requestWithURL:url];
441
		[request setShouldRedirect:NO];
442
		[request startSynchronous];
443
		if (i == 304) { // 304s will not contain a body, as per rfc2616. Will test 304 handling in a future test when we have etag support
444
			continue;
445
		}
446
		success = [[request responseString] isEqualToString:[NSString stringWithFormat:@"Non-redirected content with %hi status code",i]];
447
		GHAssertTrue(success,[NSString stringWithFormat:@"Got the wrong content when not redirecting after a %hi",i]);
448
	
449
		request2 = [ASIFormDataRequest requestWithURL:url];
450
		[request2 setPostValue:@"Giant Monkey" forKey:@"lookbehindyou"];
451
		[request2 startSynchronous];
452
		
453
		NSString *method = @"GET";
454
		if (i>304) {
455
			method = @"POST";	
456
		}
457
		NSString *expectedString = [NSString stringWithFormat:@"Redirected as %@ after a %hi status code",method,i];
458
		if (i>304) {
459
			expectedString = [NSString stringWithFormat:@"%@\r\nWatch out for the Giant Monkey!",expectedString];
460
		}
461

    
462
		success = [[request2 responseString] isEqualToString:expectedString];
463
		GHAssertTrue(success,[NSString stringWithFormat:@"Got the wrong content when redirecting after a %hi",i]);
464
	
465
		success = ([request2 responseStatusCode] == 200);
466
		GHAssertTrue(success,@"Got the wrong status code (expected 200)");
467

    
468
	}
469
	
470
	// Test RFC 2616 behaviour
471
	for (i=301; i<303; i++) {
472
		
473
		NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect/%hi",i]];
474
		request2 = [ASIFormDataRequest requestWithURL:url];
475
		[request2 setPostValue:@"Giant Monkey" forKey:@"lookbehindyou"];
476
		[request2 setShouldUseRFC2616RedirectBehaviour:YES];
477
		[request2 startSynchronous];
478
		
479
		success = ([request2 responseStatusCode] == 200);
480
		GHAssertTrue(success,@"Got the wrong status code (expected 200)");	
481

    
482
		if (i == 303) {
483
			success = ([request2 postLength] == 0 && ![request2 postBody] && [[request2 requestMethod] isEqualToString:@"GET"]);
484
			GHAssertTrue(success,@"Failed to reset request to GET on 303 redirect");
485
			
486
			success = [[request2 responseString] isEqualToString:[NSString stringWithFormat:@"Redirected as GET after a %hi status code",i]];
487
			GHAssertTrue(success,@"Failed to dump the post body on 303 redirect");
488
			
489
		} else {
490
			success = ([request2 postLength] > 0 || ![request2 postBody] || ![[request2 requestMethod] isEqualToString:@"POST"]);
491
			GHAssertTrue(success,@"Failed to use the same request method and body for a redirect when using rfc2616 behaviour");
492
		
493
			success = ([[request2 responseString] isEqualToString:[NSString stringWithFormat:@"Redirected as POST after a %hi status code\r\nWatch out for the Giant Monkey!",i]]);
494
			GHAssertTrue(success,@"Failed to send the correct post body on redirect");
495
		}
496
	}
497
	
498
	// Ensure the file contains only the body of the last request (after redirects) when downloading to a file
499
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect/301"]];
500
	NSString *path = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"test.txt"];
501
	[request setDownloadDestinationPath:path];
502
	[request startSynchronous];
503
	NSString *result = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
504
	success = [result isEqualToString:@"Redirected as GET after a 301 status code"];
505
	GHAssertTrue(success,@"Failed to store just the body of the file request on redirect");
506
	
507
	success = ([request originalURL] != [request url]);
508
	GHAssertTrue(success,@"Failed to update request url on redirection");
509
	
510
	success = ([[[request originalURL] absoluteString] isEqualToString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect/301"]);
511
	GHAssertTrue(success,@"Failed to preserve original url");	
512

    
513
	// Ensure user agent is preserved
514
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect/301"]];
515
	[request addRequestHeader:@"User-Agent" value:@"test"];
516
	[request startSynchronous];
517
	success = ([[[request requestHeaders] objectForKey:@"User-Agent"] isEqualToString:@"test"]);
518
	GHAssertTrue(success,@"Failed to preserve original user agent on redirect");
519
}
520

    
521
// Using a persistent connection for HTTP 305-307 would cause crashes on the redirect, not really sure why
522
// Since 305 (use proxy) wasn't properly supported anyway, 306 is unused, and clients are supposed to confirm redirects for 307, I've simply removed automatic redirect for these codes
523
- (void)test30xCrash
524
{
525
	int i;
526
	for (i=305; i<308; i++) {
527
		ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect/%hi",i]]];
528
		[request setPostValue:@"foo" forKey:@"eep"];
529
		[request setShouldRedirect:NO];
530
		[request startSynchronous];
531
		request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect/%hi",i]]];
532
		[request setPostValue:@"foo" forKey:@"eep"];
533
		[request startSynchronous];
534
	}
535
}
536

    
537
- (void)testResumeChecksContentRangeHeader
538
{
539
	NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/no_resume"];
540
	NSString *temporaryPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"foo.temp"];
541

    
542
	[@"" writeToFile:temporaryPath atomically:NO encoding:NSUTF8StringEncoding error:NULL];
543

    
544
	NSString *downloadPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"foo.txt"];
545

    
546
	// Download part of a large file that is returned after a redirect
547
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
548
	[request setTemporaryFileDownloadPath:temporaryPath];
549
	[request setDownloadDestinationPath:downloadPath];
550
	[request setAllowResumeForFileDownloads:YES];
551
	[request setAllowCompressedResponse:NO];
552
	[request setShouldAttemptPersistentConnection:NO];
553
	[request startAsynchronous];
554

    
555
	// Cancel the request as soon as it has downloaded 64KB
556
	while (1) {
557
		sleep(0.5);
558
		if ([request totalBytesRead] > 32*1024) {
559
			[request cancel];
560
			break;
561
		}
562
	}
563
	NSNumber *fileSize =  [[[NSFileManager defaultManager] attributesOfItemAtPath:temporaryPath error:NULL] objectForKey:NSFileSize];
564
	unsigned long long partialFileSize = [fileSize unsignedLongLongValue];
565
	BOOL success = (partialFileSize < 1036935);
566
	GHAssertTrue(success,@"Downloaded whole file too quickly, cannot proceed with this test");
567

    
568

    
569
	// Resume the download
570
	request = [ASIHTTPRequest requestWithURL:url];
571
	[request setTemporaryFileDownloadPath:temporaryPath];
572
	[request setDownloadDestinationPath:downloadPath];
573
	[request setAllowResumeForFileDownloads:YES];
574
	[request setAllowCompressedResponse:NO];
575

    
576
	[request buildRequestHeaders];
577
	success = ([request partialDownloadSize] == partialFileSize);
578
	GHAssertTrue(success,@"Failed to obtain correct partial dowload size");
579
	[request startAsynchronous];
580

    
581
	while (1) {
582
		sleep(0.5);
583
		if ([request isFinished]) {
584
			break;
585
		}
586
	}
587

    
588
	GHAssertNil([request error],@"Request failed, cannot proceed with this test");
589

    
590
	success = (![[request responseHeaders] objectForKey:@"Content-Range"]);
591
	GHAssertTrue(success,@"Got range header back, cannot proceed with this test");
592

    
593
	NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:downloadPath error:NULL];
594
	fileSize =  [attributes objectForKey:NSFileSize];
595
	success = ([fileSize intValue] == 1036935);
596
	GHAssertTrue(success,@"Downloaded file has wrong length");
597

    
598
	success = ([request partialDownloadSize] == 0);
599
	GHAssertTrue(success,@"Failed to reset download size");
600
}
601

    
602

    
603
- (void)testRedirectedResume
604
{
605
	[self performSelectorOnMainThread:@selector(runRedirectedResume) withObject:nil waitUntilDone:YES];
606
}
607

    
608
- (void)runRedirectedResume
609
{
610
	NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect_resume"];
611
	NSString *temporaryPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"foo.temp"];
612
	
613
	[@"" writeToFile:temporaryPath atomically:NO encoding:NSUTF8StringEncoding error:NULL];
614
	
615
	NSString *downloadPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"foo.txt"];
616
	
617
	// Download part of a large file that is returned after a redirect
618
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
619
	[request setTemporaryFileDownloadPath:temporaryPath];
620
	[request setDownloadDestinationPath:downloadPath];
621
	[request setAllowResumeForFileDownloads:YES];
622
	[request setAllowCompressedResponse:NO];
623
	[request startAsynchronous];
624
	
625
	// Cancel the request as soon as it has downloaded 64KB
626
	while (1) {
627
		[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
628
		if ([request totalBytesRead] > 32*1024) {
629
			[request cancel];
630
			break;
631
		}
632
	}
633
	NSNumber *fileSize =  [[[NSFileManager defaultManager] attributesOfItemAtPath:temporaryPath error:NULL] objectForKey:NSFileSize];
634
	unsigned long long partialFileSize = [fileSize unsignedLongLongValue];
635
	BOOL success = (partialFileSize < 1036935);
636
	GHAssertTrue(success,@"Downloaded whole file too quickly, cannot proceed with this test");
637

    
638

    
639
	// Resume the download synchronously
640
	request = [ASIHTTPRequest requestWithURL:url];
641
	[request setTemporaryFileDownloadPath:temporaryPath];
642
	[request setDownloadDestinationPath:downloadPath];
643
	[request setAllowResumeForFileDownloads:YES];
644
	[request setAllowCompressedResponse:NO];
645
	[request startSynchronous];
646
	
647
	fileSize =  [[[NSFileManager defaultManager] attributesOfItemAtPath:downloadPath error:NULL] objectForKey:NSFileSize];
648
	success = ([fileSize intValue] == 1036935);
649
	GHAssertTrue(success,@"Downloaded file has wrong length");
650
	
651
	success = [[[request requestHeaders] objectForKey:@"Range"] isEqualToString:[NSString stringWithFormat:@"bytes=%llu-",partialFileSize]];
652
	GHAssertTrue(success,@"Restarted download when we should have resumed, or asked for the wrong segment of the file");
653
	
654
}
655

    
656
- (void)testUploadContentLength
657
{
658
	//This url will return the contents of the Content-Length request header
659
	NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/content-length"];
660
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
661
	[request setPostBody:[NSMutableData dataWithLength:1024*32]];
662
	[request startSynchronous];
663
	
664
	BOOL success = ([[request responseString] isEqualToString:[NSString stringWithFormat:@"%hu",(1024*32)]]);
665
	GHAssertTrue(success,@"Sent wrong content length");
666
}
667

    
668
- (void)testDownloadContentLength
669
{
670
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease];
671
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
672
	[request startSynchronous];
673
	
674
	BOOL success = ([request contentLength] == 27872);
675
	GHAssertTrue(success,@"Got wrong content length");
676
}
677

    
678
- (void)testFileDownload
679
{
680
	NSString *path = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"testimage.png"];
681
	
682
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease];
683
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
684
	[request setDownloadDestinationPath:path];
685
	[request startSynchronous];
686

    
687
#if TARGET_OS_IPHONE
688
	UIImage *image = [[[UIImage alloc] initWithContentsOfFile:path] autorelease];
689
#else
690
	NSImage *image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];	
691
#endif
692
	
693
	GHAssertNotNil(image,@"Failed to download data to a file");
694
}
695

    
696

    
697
- (void)testCompressedResponseDownloadToFile
698
{
699
	NSString *path = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"testfile"];
700

    
701
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/first"] autorelease];
702
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
703
	[request setDownloadDestinationPath:path];
704
	[request startSynchronous];
705

    
706
	NSString *tempPath = [request temporaryFileDownloadPath];
707
	GHAssertNil(tempPath,@"Failed to clean up temporary download file");		
708

    
709
	BOOL success = [[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL] isEqualToString:@"This is the expected content for the first string"];
710
	GHAssertTrue(success,@"Failed to download data to a file");
711

    
712
	// Now test with inflating the response on the fly
713
	NSError *error = nil;
714
	[ASIHTTPRequest removeFileAtPath:path error:&error];
715
	if (error) {
716
		GHFail(@"Failed to remove file, cannot proceed with test");
717
	}
718

    
719
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
720
	[request setDownloadDestinationPath:path];
721
	[request setShouldWaitToInflateCompressedResponses:NO];
722
	[request startSynchronous];
723

    
724
	tempPath = [request temporaryFileDownloadPath];
725
	GHAssertNil(tempPath,@"Failed to clean up temporary download file");
726

    
727
	success = [[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL] isEqualToString:@"This is the expected content for the first string"];
728
	GHAssertTrue(success,@"Failed to download data to a file");
729
}
730

    
731
- (void)request:(ASIHTTPRequest *)request didGetMoreData:(NSData *)data
732
{
733
	[[self responseData] appendData:data];
734
}
735

    
736
- (void)downloadFinished:(ASIHTTPRequest *)request
737
{
738
	finished = YES;
739
}
740

    
741
- (void)testCompressedResponseDelegateDataHandling
742
{
743
	finished = NO;
744
	[self setResponseData:[NSMutableData data]];
745

    
746
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_hound_of_the_baskervilles.text"] autorelease];
747

    
748
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
749
	[request startSynchronous];
750

    
751
	NSString *response = [request responseString];
752

    
753
	// Now download again, using the delegate to handle the data
754
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
755
	[request setDelegate:self];
756
	[request setDidReceiveDataSelector:@selector(request:didGetMoreData:)];
757
	[request setDidFinishSelector:@selector(downloadFinished:)];
758
	[request setShouldWaitToInflateCompressedResponses:NO];
759
	[request startSynchronous];
760

    
761
	while (!finished) {
762
		sleep(1);
763
	}
764

    
765
	NSString *delegateResponse = [[[NSString alloc] initWithBytes:[responseData bytes] length:[responseData length] encoding:[request responseEncoding]] autorelease];
766
	BOOL success = [delegateResponse isEqualToString:response];
767
	GHAssertTrue(success,@"Failed to correctly download the response using a delegate");
768

    
769
	// Test again without compression
770
	finished = NO;
771
	[self setResponseData:[NSMutableData data]];
772

    
773
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
774
	[request setAllowCompressedResponse:NO];
775
	[request startSynchronous];
776

    
777
	response = [request responseString];
778

    
779
	// Now download again, using the delegate to handle the data
780
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
781
	[request setDelegate:self];
782
	[request setDidReceiveDataSelector:@selector(request:didGetMoreData:)];
783
	[request setDidFinishSelector:@selector(downloadFinished:)];
784
	[request setAllowCompressedResponse:NO];
785
	[request startSynchronous];
786

    
787
	while (!finished) {
788
		sleep(1);
789
	}
790

    
791
	delegateResponse = [[[NSString alloc] initWithBytes:[responseData bytes] length:[responseData length] encoding:[request responseEncoding]] autorelease];
792
	success = [delegateResponse isEqualToString:response];
793
	GHAssertTrue(success,@"Failed to correctly download the response using a delegate");
794
}
795

    
796

    
797
- (void)testDownloadProgress
798
{
799
	// We run tests that measure progress on the main thread because otherwise we can't depend on the progress delegate being notified before we need to test it's working
800
	[self performSelectorOnMainThread:@selector(performDownloadProgressTest) withObject:nil waitUntilDone:YES];
801
}
802

    
803
- (void)performDownloadProgressTest
804
{
805
	progress = 0;
806
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease];
807
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
808
	[request setDownloadProgressDelegate:self];
809
	[request startSynchronous];
810

    
811
	BOOL success = (progress == 1.0);
812
	GHAssertTrue(success,@"Failed to properly increment download progress %f != 1.0",progress);	
813
	
814
	progress = 0;
815
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel.txt"]];
816
	[request setDownloadProgressDelegate:self];
817
	[request startAsynchronous];
818
	
819
	[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
820
	
821
	success = (progress != 1.0);
822
	GHAssertTrue(success,@"Downloaded too quickly, cannot proceed with test");	
823
	 
824
	success = (progress > 0);
825
	GHAssertTrue(success,@"Either downloaded too slowly, or progress is not being correctly updated");		 
826
	
827
	
828
}
829

    
830
- (void)testUploadProgress
831
{
832
	// We run tests that measure progress on the main thread because otherwise we can't depend on the progress delegate being notified before we need to test it's working
833
	[self performSelectorOnMainThread:@selector(performUploadProgressTest) withObject:nil waitUntilDone:YES];	
834
}
835

    
836
- (void)performUploadProgressTest
837
{
838
	progress = 0;
839
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ignore"]] autorelease];
840
	[request setPostBody:(NSMutableData *)[@"This is the request body" dataUsingEncoding:NSUTF8StringEncoding]];
841
	[request setUploadProgressDelegate:self];
842
	[request startSynchronous];
843
	
844
	
845
	BOOL success = (progress == 1.0);
846
	GHAssertTrue(success,@"Failed to properly increment upload progress %f != 1.0",progress);	
847
}
848

    
849
- (void)testPostBodyStreamedFromDisk
850
{
851
	// We run tests that measure progress on the main thread because otherwise we can't depend on the progress delegate being notified before we need to test it's working
852
	[self performSelectorOnMainThread:@selector(performPostBodyStreamedFromDiskTest) withObject:nil waitUntilDone:YES];
853
	
854
}
855

    
856
- (void)performPostBodyStreamedFromDiskTest
857
{
858
	NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/print_request_body"];
859
	NSString *requestBody = @"This is the request body";
860
	NSString *requestContentPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"testfile.txt"];
861
	[[requestBody dataUsingEncoding:NSUTF8StringEncoding] writeToFile:requestContentPath atomically:NO];
862
	
863
	
864
	// Test using a user-specified file as the request body (useful for PUT)
865
	progress = 0;
866
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
867
	[request setRequestMethod:@"PUT"];
868
	[request setShouldStreamPostDataFromDisk:YES];
869
	[request setUploadProgressDelegate:self];
870
	[request setPostBodyFilePath:requestContentPath];
871
	[request startSynchronous];
872
	
873
	BOOL success = (progress == 1.0);
874
	GHAssertTrue(success,@"Failed to properly increment upload progress %f != 1.0",progress);
875
	
876
	success = [[request responseString] isEqualToString:requestBody];
877
	GHAssertTrue(success,@"Failed upload the correct request body");
878
	
879
	
880
	// Test building a request body by appending data
881
	progress = 0;
882
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
883
	[request setShouldStreamPostDataFromDisk:YES];
884
	[request setRequestMethod:@"PUT"];
885
	[request setUploadProgressDelegate:self];
886
	[request appendPostDataFromFile:requestContentPath];
887
	[request startSynchronous];
888
	
889
	success = (progress == 1.0);
890
	GHAssertTrue(success,@"Failed to properly increment upload progress %f != 1.0",progress);
891
	
892
	success = [[request responseString] isEqualToString:requestBody];
893
	GHAssertTrue(success,@"Failed upload the correct request body");		
894
}
895

    
896
- (void)testCookies
897
{
898
	BOOL success;
899
	
900
	// Set setting a cookie
901
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/set_cookie"] autorelease];
902
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
903
	[request setUseCookiePersistence:YES];
904
	[request startSynchronous];
905
	NSString *html = [request responseString];
906
	success = [html isEqualToString:@"I have set a cookie"];
907
	GHAssertTrue(success,@"Failed to set a cookie");
908
	
909
	// Test a cookie is stored in responseCookies
910
	NSArray *cookies = [request responseCookies];
911
	GHAssertNotNil(cookies,@"Failed to store cookie data in responseCookies");
912
	
913

    
914
	// Test the cookie contains the correct data
915
	NSHTTPCookie *cookie = nil;
916
	BOOL foundCookie = NO;
917
	for (cookie in cookies) {
918
		if ([[cookie name] isEqualToString:@"ASIHTTPRequestTestCookie"]) {
919
			foundCookie = YES;
920
			success = [[cookie value] isEqualToString:@"This+is+the+value"];
921
			GHAssertTrue(success,@"Failed to store the correct value for a cookie");
922
			success = [[cookie domain] isEqualToString:@"allseeing-i.com"];
923
			GHAssertTrue(success,@"Failed to store the correct domain for a cookie");
924
			success = [[cookie path] isEqualToString:@"/ASIHTTPRequest/tests"];
925
			GHAssertTrue(success,@"Failed to store the correct path for a cookie");
926
			break;
927
		}
928
	}
929
	GHAssertTrue(foundCookie,@"Failed store a particular cookie - can't continue with the rest of the tests");
930
	
931
	if (!foundCookie) {
932
		return;
933
	}
934
	// Test a cookie is presented when manually added to the request
935
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/read_cookie"] autorelease];
936
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
937
	[request setUseCookiePersistence:NO];
938
	[request setRequestCookies:[NSMutableArray arrayWithObject:cookie]];
939
	[request startSynchronous];
940
	html = [request responseString];
941
	success = [html isEqualToString:@"I have 'This is the value' as the value of 'ASIHTTPRequestTestCookie'"];
942
	GHAssertTrue(success,@"Cookie not presented to the server with cookie persistence OFF");
943

    
944
	// Test a cookie is presented from the persistent store
945
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/read_cookie"] autorelease];
946
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
947
	[request setUseCookiePersistence:YES];
948
	[request startSynchronous];
949
	html = [request responseString];
950
	success = [html isEqualToString:@"I have 'This is the value' as the value of 'ASIHTTPRequestTestCookie'"];
951
	GHAssertTrue(success,@"Cookie not presented to the server with cookie persistence ON");
952
	
953
	// Test removing a cookie
954
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/remove_cookie"] autorelease];
955
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
956
	[request startSynchronous];
957
	html = [request responseString];
958
	success = [html isEqualToString:@"I have removed a cookie"];
959
	GHAssertTrue(success,@"Failed to remove a cookie");
960

    
961
	// Test making sure cookie was properly removed
962
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/read_cookie"] autorelease];
963
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
964
	[request startSynchronous];
965
	html = [request responseString];
966
	success = [html isEqualToString:@"No cookie exists"];
967
	GHAssertTrue(success,@"Cookie presented to the server when it should have been removed");
968
	
969
	// Test setting a custom cookie works
970
	NSDictionary *cookieProperties = [[[NSMutableDictionary alloc] init] autorelease];
971
	
972
	// We'll add a line break to our cookie value to test it gets correctly encoded
973
	[cookieProperties setValue:@"Test%0D%0AValue" forKey:NSHTTPCookieValue];
974
	[cookieProperties setValue:@"ASIHTTPRequestTestCookie" forKey:NSHTTPCookieName];
975
	[cookieProperties setValue:@"allseeing-i.com" forKey:NSHTTPCookieDomain];
976
	[cookieProperties setValue:[NSDate dateWithTimeIntervalSinceNow:60*60*4] forKey:NSHTTPCookieExpires];
977
	[cookieProperties setValue:@"/ASIHTTPRequest/tests" forKey:NSHTTPCookiePath];
978
	cookie = [[[NSHTTPCookie alloc] initWithProperties:cookieProperties] autorelease];
979
	
980
	GHAssertNotNil(cookie,@"Failed to create a cookie - cookie value was not correctly encoded?");
981

    
982
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/read_cookie"] autorelease];
983
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
984
	[request setUseCookiePersistence:NO];
985
	[request setRequestCookies:[NSMutableArray arrayWithObject:cookie]];
986
	[request startSynchronous];
987
	html = [request responseString];
988
	success = [html isEqualToString:@"I have 'Test\r\nValue' as the value of 'ASIHTTPRequestTestCookie'"];
989
	GHAssertTrue(success,@"Custom cookie not presented to the server with cookie persistence OFF");
990
	
991

    
992
	// Test removing all cookies works
993
	[ASIHTTPRequest clearSession];
994
	NSArray *sessionCookies = [ASIHTTPRequest sessionCookies];
995
	success = ([sessionCookies count] == 0);
996
	GHAssertTrue(success,@"Cookies not removed");
997

    
998
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/read_cookie"] autorelease];
999
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1000
	[request setUseCookiePersistence:YES];
1001
	[request startSynchronous];
1002
	html = [request responseString];
1003
	success = [html isEqualToString:@"No cookie exists"];
1004
	GHAssertTrue(success,@"Cookie presented to the server when it should have been removed");
1005
	
1006
	// Test fetching cookies for a relative url - fixes a problem where urls created with URLWithString:relativeToURL: wouldn't always read cookies from the persistent store
1007
	[ASIHTTPRequest clearSession];
1008
	
1009
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/set_cookie"] autorelease];
1010
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1011
	[request setUseCookiePersistence:YES];
1012
	[request setUseSessionPersistence:NO];
1013
	[request startSynchronous];
1014
	
1015
	NSURL *originalURL = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/"];
1016
	url = [NSURL URLWithString:@"read_cookie" relativeToURL:originalURL];
1017
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1018
	[request setUseCookiePersistence:YES];
1019
	[request setUseSessionPersistence:NO];
1020
	[request startSynchronous];
1021
	html = [request responseString];
1022
	NSLog(@"%@",html);
1023
	success = [html isEqualToString:@"I have 'This is the value' as the value of 'ASIHTTPRequestTestCookie'"];
1024
	GHAssertTrue(success,@"Custom cookie not presented to the server with cookie persistence OFF");
1025
	
1026
}
1027

    
1028
// Test fix for a crash if you tried to remove credentials that didn't exist
1029
- (void)testRemoveCredentialsFromKeychain
1030
{
1031
	[ASIHTTPRequest removeCredentialsForHost:@"apple.com" port:0 protocol:@"http" realm:@"Nothing to see here"];
1032
	[ASIHTTPRequest removeCredentialsForProxy:@"apple.com" port:0 realm:@"Nothing to see here"];
1033
	
1034
}
1035

    
1036
- (void)testPreserveResponseWhenDownloadComplete
1037
{
1038
	NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/basic-authentication"];
1039
	ASIHTTPRequest *request;
1040
	BOOL success;
1041

    
1042
	request = [ASIHTTPRequest requestWithURL:url];
1043
	[request startSynchronous];
1044

    
1045
	success = ([[request responseString] length]);
1046
	GHAssertTrue(success,@"Request removed the response body when we encountered an error, even though the download was complete");
1047

    
1048
	NSString *downloadPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"test.txt"];
1049
	if ([[NSFileManager defaultManager] fileExistsAtPath:downloadPath]) {
1050
		[[NSFileManager defaultManager] removeItemAtPath:downloadPath error:NULL];
1051
	}
1052

    
1053
	request = [ASIHTTPRequest requestWithURL:url];
1054
	[request setDownloadDestinationPath:downloadPath];
1055
	[request startSynchronous];
1056

    
1057
	success = ([[[NSFileManager defaultManager] attributesOfItemAtPath:downloadPath error:NULL] fileSize]);
1058
	GHAssertTrue(success,@"Request removed or failed to copy the response to downloadDestinationPath");
1059
}
1060

    
1061
- (void)testBasicAuthentication
1062
{
1063
	[ASIHTTPRequest removeCredentialsForHost:@"allseeing-i.com" port:0 protocol:@"http" realm:@"SECRET_STUFF"];
1064
	[ASIHTTPRequest clearSession];
1065

    
1066
	NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/basic-authentication"];
1067
	ASIHTTPRequest *request;
1068
	BOOL success;
1069
	NSError *err;
1070
	
1071
	// Test authentication needed when no credentials supplied
1072
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1073
	[request setUseKeychainPersistence:NO];
1074
	[request startSynchronous];
1075
	success = [[request error] code] == ASIAuthenticationErrorType;
1076
	GHAssertTrue(success,@"Failed to generate permission denied error with no credentials");
1077

    
1078
	// Test wrong credentials supplied
1079
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1080
	[request setUseKeychainPersistence:NO];
1081
	[request setUsername:@"wrong"];
1082
	[request setPassword:@"wrong"];
1083
	[request startSynchronous];
1084
	success = [[request error] code] == ASIAuthenticationErrorType;
1085
	GHAssertTrue(success,@"Failed to generate permission denied error with wrong credentials");
1086
	
1087
	// Test correct credentials supplied
1088
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1089
	[request setUseSessionPersistence:YES];
1090
	[request setUseKeychainPersistence:YES];
1091
	[request setShouldPresentCredentialsBeforeChallenge:NO];
1092
	[request setUsername:@"secret_username"];
1093
	[request setPassword:@"secret_password"];
1094
	[request startSynchronous];
1095
	err = [request error];
1096
	GHAssertNil(err,@"Failed to supply correct username and password");
1097
	
1098
	// Ensure credentials are not reused
1099
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1100
	[request setUseSessionPersistence:NO];
1101
	[request setUseKeychainPersistence:NO];
1102
	[request startSynchronous];
1103
	success = [[request error] code] == ASIAuthenticationErrorType;
1104
	GHAssertTrue(success,@"Reused credentials when we shouldn't have");
1105

    
1106
	// Ensure credentials stored in the session are reused
1107
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1108
	[request setUseSessionPersistence:YES];
1109
	[request setUseKeychainPersistence:NO];
1110
	[request startSynchronous];
1111
	err = [request error];
1112
	GHAssertNil(err,@"Failed to reuse credentials");
1113
	
1114
	// Ensure new credentials are used in place of those in the session
1115
	request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/basic-authentication-new-credentials"]] autorelease];
1116
	[request setUsername:@"secret_username_2"];
1117
	[request setPassword:@"secret_password_2"];
1118
	[request setUseSessionPersistence:YES];
1119
	[request setUseKeychainPersistence:NO];
1120
	[request startSynchronous];
1121
	err = [request error];
1122
	GHAssertNil(err,@"Failed to reuse credentials");
1123
	
1124
	[ASIHTTPRequest clearSession];
1125
	
1126
	// Ensure credentials stored in the session were wiped
1127
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1128
	[request setUseKeychainPersistence:NO];
1129
	[request startSynchronous];
1130
	success = [[request error] code] == ASIAuthenticationErrorType;
1131
	GHAssertTrue(success,@"Failed to clear credentials");
1132
	
1133
	// Ensure credentials stored in the keychain are reused
1134
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1135
	[request setUseKeychainPersistence:YES];
1136
	[request startSynchronous];
1137
	err = [request error];
1138
	GHAssertNil(err,@"Failed to use stored credentials");
1139
	
1140
	[ASIHTTPRequest removeCredentialsForHost:@"allseeing-i.com" port:0 protocol:@"http" realm:@"SECRET_STUFF"];
1141
	
1142
	// Ensure credentials stored in the keychain were wiped
1143
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1144
	[request setUseKeychainPersistence:YES];
1145
	[request setUseSessionPersistence:NO];
1146
	[request startSynchronous];
1147
	success = [[request error] code] == ASIAuthenticationErrorType;
1148
	GHAssertTrue(success,@"Failed to clear credentials");
1149
	
1150
	// Tests shouldPresentCredentialsBeforeChallenge with credentials stored in the session
1151
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1152
	[request setUseSessionPersistence:YES];
1153
	[request startSynchronous];
1154
	success = [request authenticationRetryCount] == 0;
1155
	GHAssertTrue(success,@"Didn't supply credentials before being asked for them when talking to the same server with shouldPresentCredentialsBeforeChallenge == YES");
1156
	
1157
	// Ensure credentials stored in the session were not presented to the server before it asked for them
1158
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1159
	[request setUseSessionPersistence:YES];
1160
	[request setShouldPresentCredentialsBeforeChallenge:NO];
1161
	[request startSynchronous];
1162
	success = [request authenticationRetryCount] == 1;
1163
	GHAssertTrue(success,@"Supplied session credentials before being asked for them");	
1164
	
1165
	[ASIHTTPRequest clearSession];
1166
	
1167
	// Test credentials set on the request are not sent before the server asks for them unless they are cached credentials from a previous request to this server
1168
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1169
	[request setUseSessionPersistence:NO];
1170
	[request setUsername:@"secret_username"];
1171
	[request setPassword:@"secret_password"];
1172
	[request setShouldPresentCredentialsBeforeChallenge:YES];
1173
	[request startSynchronous];
1174
	BOOL fail = [request authenticationRetryCount] == 0;
1175
	GHAssertFalse(fail,@"Sent Basic credentials even though request did not have kCFHTTPAuthenticationSchemeBasic set as authenticationScheme.");
1176

    
1177
	// Test basic credentials set on the request are sent before the server asks for them if we've explictly set the authentication scheme to basic
1178
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1179
	[request setUseSessionPersistence:NO];
1180
	[request setUsername:@"secret_username"];
1181
	[request setPassword:@"secret_password"];
1182
	[request setShouldPresentCredentialsBeforeChallenge:YES];
1183
	[request setAuthenticationScheme:(NSString *)kCFHTTPAuthenticationSchemeBasic];
1184
	[request startSynchronous];
1185
	success = [request authenticationRetryCount] == 0;
1186
	GHAssertTrue(success,@"Didn't supply credentials before being asked for them, even though they were set on the request and shouldPresentCredentialsBeforeChallenge == YES");
1187
	
1188
	// Test credentials set on the request aren't sent before the server asks for them
1189
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1190
	[request setUseSessionPersistence:NO];
1191
	[request setUsername:@"secret_username"];
1192
	[request setPassword:@"secret_password"];
1193
	[request setShouldPresentCredentialsBeforeChallenge:NO];
1194
	[request startSynchronous];
1195
	success = [request authenticationRetryCount] == 1;
1196
	GHAssertTrue(success,@"Supplied request credentials before being asked for them");	
1197
	
1198
	
1199
	// Test credentials presented before a challenge are stored in the session store
1200
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1201
	[request setUsername:@"secret_username"];
1202
	[request setPassword:@"secret_password"];
1203
	[request setShouldPresentCredentialsBeforeChallenge:YES];
1204
	[request startSynchronous];
1205
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1206
	[request startSynchronous];
1207
	err = [request error];
1208
	GHAssertNil(err,@"Failed to use stored credentials");	
1209
	
1210
	
1211
	// Ok, now let's test on a different server to sanity check that the credentials from out previous requests are not being used
1212
	url = [NSURL URLWithString:@"https://selfsigned.allseeing-i.com/ASIHTTPRequest/tests/basic-authentication"];
1213
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1214
	[request setUseSessionPersistence:YES];
1215
	[request setUseKeychainPersistence:NO];
1216
	[request setValidatesSecureCertificate:NO];
1217
	[request startSynchronous];
1218
	success = [[request error] code] == ASIAuthenticationErrorType;
1219
	GHAssertTrue(success,@"Reused credentials when we shouldn't have");	
1220
	
1221
}
1222

    
1223

    
1224

    
1225
- (void)testDigestAuthentication
1226
{
1227
	[ASIHTTPRequest removeCredentialsForHost:@"allseeing-i.com" port:0 protocol:@"http" realm:@"Keep out"];
1228
	[ASIHTTPRequest clearSession];
1229
	
1230
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/digest-authentication"] autorelease];
1231
	ASIHTTPRequest *request;
1232
	BOOL success;
1233
	NSError *err;
1234
	
1235
	// Test authentication needed when no credentials supplied
1236
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1237
	[request setUseKeychainPersistence:NO];
1238
	[request startSynchronous];
1239
	success = [[request error] code] == ASIAuthenticationErrorType;
1240
	GHAssertTrue(success,@"Failed to generate permission denied error with no credentials");
1241
	
1242
	// Test wrong credentials supplied
1243
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1244
	[request setUseKeychainPersistence:NO];
1245
	[request setUsername:@"wrong"];
1246
	[request setPassword:@"wrong"];
1247
	[request startSynchronous];
1248
	success = [[request error] code] == ASIAuthenticationErrorType;
1249
	GHAssertTrue(success,@"Failed to generate permission denied error with wrong credentials");
1250
	
1251
	// Test correct credentials supplied
1252
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1253
	[request setUseSessionPersistence:YES];
1254
	[request setUseKeychainPersistence:YES];
1255
	[request setUsername:@"secret_username"];
1256
	[request setPassword:@"secret_password"];
1257
	[request startSynchronous];
1258
	err = [request error];
1259
	GHAssertNil(err,@"Failed to supply correct username and password");
1260
	
1261
	// Ensure credentials are not reused
1262
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1263
	[request setUseSessionPersistence:NO];
1264
	[request setUseKeychainPersistence:NO];
1265
	[request startSynchronous];
1266
	success = [[request error] code] == ASIAuthenticationErrorType;
1267
	GHAssertTrue(success,@"Reused credentials when we shouldn't have");
1268
	
1269
	// Ensure credentials stored in the session are reused
1270
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1271
	[request setUseSessionPersistence:YES];
1272
	[request setUseKeychainPersistence:NO];
1273
	[request startSynchronous];
1274
	err = [request error];
1275
	GHAssertNil(err,@"Failed to reuse credentials");
1276
	
1277
	[ASIHTTPRequest clearSession];
1278
	
1279
	// Ensure credentials stored in the session were wiped
1280
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1281
	[request setUseKeychainPersistence:NO];
1282
	[request startSynchronous];
1283
	success = [[request error] code] == ASIAuthenticationErrorType;
1284
	GHAssertTrue(success,@"Failed to clear credentials");
1285
	
1286
	// Ensure credentials stored in the keychain are reused
1287
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1288
	[request setUseKeychainPersistence:YES];
1289
	[request startSynchronous];
1290
	err = [request error];
1291
	GHAssertNil(err,@"Failed to reuse credentials");
1292
	
1293
	[ASIHTTPRequest removeCredentialsForHost:@"allseeing-i.com" port:0 protocol:@"http" realm:@"Keep out"];
1294
	
1295
	// Ensure credentials stored in the keychain were wiped
1296
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1297
	[request setUseKeychainPersistence:YES];
1298
	[request setUseSessionPersistence:NO];
1299
	[request startSynchronous];
1300
	success = [[request error] code] == ASIAuthenticationErrorType;
1301
	GHAssertTrue(success,@"Failed to clear credentials");	
1302
	
1303
	
1304
	// Test credentials set on the request are sent before the server asks for them
1305
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1306
	[request setUseSessionPersistence:YES];
1307
	[request setShouldPresentCredentialsBeforeChallenge:YES];
1308
	[request startSynchronous];
1309
	success = [request authenticationRetryCount] == 0;
1310
	GHAssertTrue(success,@"Didn't supply credentials before being asked for them, even though they were set in the session and shouldPresentCredentialsBeforeChallenge == YES");	
1311
	
1312
}
1313

    
1314
- (void)testNTLMHandshake
1315
{
1316
	// This test connects to a script that masquerades as an NTLM server
1317
	// It tests that the handshake seems sane, but doesn't actually authenticate
1318
	
1319
	[ASIHTTPRequest clearSession];
1320
	
1321
	NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/pretend-ntlm-handshake"];
1322
	
1323
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
1324
	[request setUseKeychainPersistence:NO];
1325
	[request setUseSessionPersistence:NO];
1326
	[request startSynchronous];
1327
	BOOL success = [[request error] code] == ASIAuthenticationErrorType;
1328
	GHAssertTrue(success,@"Failed to generate permission denied error with no credentials");
1329

    
1330

    
1331
	request = [ASIHTTPRequest requestWithURL:url];
1332
	[request setUseSessionPersistence:YES];
1333
	[request setUseKeychainPersistence:NO];
1334
	[request setUsername:@"king"];
1335
	[request setPassword:@"fink"];
1336
	[request setDomain:@"Castle.Kingdom"];
1337
	[request startSynchronous];
1338

    
1339
	GHAssertNil([request error],@"Got an error when credentials were supplied");
1340
	
1341
	// NSProcessInfo returns a lower case string for host name, while CFNetwork will send a mixed case string for host name, so we'll compare by lowercasing everything
1342
	NSString *hostName = [[NSProcessInfo processInfo] hostName];
1343
	NSString *expectedResponse = [[NSString stringWithFormat:@"You are %@ from %@/%@",@"king",@"Castle.Kingdom",hostName] lowercaseString];
1344
	success = [[[request responseString] lowercaseString] isEqualToString:expectedResponse];
1345
	GHAssertTrue(success,@"Failed to send credentials correctly? (Expected: '%@', got '%@')",expectedResponse,[[request responseString] lowercaseString]);
1346
}
1347

    
1348
- (void)testCompressedResponse
1349
{
1350
	// allseeing-i.com does not gzip png images
1351
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease];
1352
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1353
	[request startSynchronous];
1354
	NSString *encoding = [[request responseHeaders] objectForKey:@"Content-Encoding"];
1355
	BOOL success = (!encoding || [encoding rangeOfString:@"gzip"].location != NSNotFound);
1356
	GHAssertTrue(success,@"Got incorrect request headers from server");
1357

    
1358
	success = ([request rawResponseData] == [request responseData]);
1359
	GHAssertTrue(success,@"Attempted to uncompress data that was not compressed");	
1360

    
1361
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/first"] autorelease];
1362
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1363
	[request startSynchronous];
1364
	success = ([request rawResponseData] != [request responseData]);
1365
	GHAssertTrue(success,@"Uncompressed data is the same as compressed data");	
1366

    
1367
	success = [[request responseString] isEqualToString:@"This is the expected content for the first string"];
1368
	GHAssertTrue(success,@"Failed to decompress data correctly?");
1369

    
1370
	url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/first"] autorelease];
1371
	request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1372
	[request setShouldWaitToInflateCompressedResponses:NO];
1373
	[request startSynchronous];
1374
	success = ([request rawResponseData] == [request responseData]);
1375
	GHAssertTrue(success,@"Failed to populate rawResponseData with the inflated data");
1376
}
1377

    
1378

    
1379
- (void)testPartialFetch
1380
{
1381
	// We run tests that measure progress on the main thread because otherwise we can't depend on the progress delegate being notified before we need to test it's working
1382
	[self performSelectorOnMainThread:@selector(performPartialFetchTest) withObject:nil waitUntilDone:YES];	
1383

    
1384
}
1385
					
1386
- (void)performPartialFetchTest
1387
{
1388
	NSString *downloadPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"testfile.txt"];
1389
	NSString *tempPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"tempfile.txt"];
1390
	NSString *partialContent = @"This file should be exactly 163 bytes long when encoded as UTF8, Unix line breaks with no BOM.\n";
1391
	[partialContent writeToFile:tempPath atomically:NO encoding:NSASCIIStringEncoding error:nil];
1392
	
1393
	progress = 0;
1394
	NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/test_partial_download.txt"] autorelease];
1395
	ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
1396
	[request setDownloadDestinationPath:downloadPath];
1397
	[request setTemporaryFileDownloadPath:tempPath];
1398
	[request setAllowResumeForFileDownloads:YES];
1399
	[request setAllowCompressedResponse:NO];
1400
	[request setDownloadProgressDelegate:self];
1401
	[request startSynchronous];
1402
	
1403
	BOOL success = ([request contentLength] == 163-95);
1404
	GHAssertTrue(success,@"Failed to download a segment of the data");
1405
	
1406
	NSString *content = [NSString stringWithContentsOfFile:downloadPath encoding:NSUTF8StringEncoding error:NULL];
1407
	
1408
	NSString *newPartialContent = [content substringFromIndex:95];
1409
	success = ([newPartialContent isEqualToString:@"This is the content we ought to be getting if we start from byte 95."]);
1410
	GHAssertTrue(success,@"Failed to append the correct data to the end of the file?");
1411
	
1412
	success = (progress == 1.0);
1413
	GHAssertTrue(success,@"Failed to correctly display increment progress for a partial download");
1414
}
1415

    
1416
// The '000' is to ensure this test runs first, as another test may connect to https://selfsigned.allseeing-i.com and accept the certificate
1417
- (void)test000SSL
1418
{
1419
	NSURL *url = [NSURL URLWithString:@"https://selfsigned.allseeing-i.com"];
1420
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
1421
	[request startSynchronous];
1422
	
1423
	GHAssertNotNil([request error],@"Failed to generate an error for a self-signed certificate (Will fail on the second run in the same session!)");		
1424
	
1425
	// Just for testing the request generated a custom error description - don't do this! You should look at the domain / code of the underlyingError in your own programs.
1426
	BOOL success = ([[[request error] localizedDescription] rangeOfString:@"SSL problem"].location != NSNotFound);
1427
	GHAssertTrue(success,@"Generated the wrong error for a self signed cert");
1428
	
1429
	// Turn off certificate validation, and try again
1430
	request = [ASIHTTPRequest requestWithURL:url];
1431
	[request setValidatesSecureCertificate:NO];
1432
	[request startSynchronous];
1433
	
1434
	GHAssertNil([request error],@"Failed to accept a self-signed certificate");	
1435
}
1436

    
1437
- (void)testRedirectPreservesSession
1438
{
1439
	// Remove any old session cookies
1440
	[ASIHTTPRequest clearSession];
1441
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/session_redirect"]];
1442
	[request startSynchronous];
1443
	BOOL success = [[request responseString] isEqualToString:@"Take me to your leader"];
1444
	GHAssertTrue(success,@"Failed to redirect preserving session cookies");	
1445
}
1446

    
1447
- (void)testTooMuchRedirection
1448
{
1449
	// This url will simply send a 302 redirect back to itself
1450
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/one_infinite_loop"]];
1451
	[request startSynchronous];
1452
	GHAssertNotNil([request error],@"Failed to generate an error when redirection occurs too many times");
1453
	BOOL success = ([[request error] code] == ASITooMuchRedirectionErrorType);
1454
	GHAssertTrue(success,@"Generated the wrong error for a redirection loop");		
1455
}
1456

    
1457
- (void)testRedirectToNewDomain
1458
{
1459
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect_to_new_domain"]];
1460
	[request startSynchronous];
1461
	BOOL success = [[[[request url] absoluteString] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"/"]] isEqualToString:@"http://www.apple.com"];
1462
	GHAssertTrue(success,@"Failed to redirect to a different domain");		
1463
}
1464

    
1465
// Ensure request method changes to get
1466
- (void)test303Redirect
1467
{
1468
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect_303"]];
1469
	[request setRequestMethod:@"PUT"];
1470
	[request appendPostData:[@"Fuzzy" dataUsingEncoding:NSUTF8StringEncoding]];
1471
	[request startSynchronous];
1472
	BOOL success = [[[request url] absoluteString] isEqualToString:@"http://allseeing-i.com/ASIHTTPRequest/tests/request-method"];
1473
	GHAssertTrue(success,@"Failed to redirect to correct location");
1474
	success = [[request responseString] isEqualToString:@"GET"];
1475
	GHAssertTrue(success,@"Failed to use GET on new URL");
1476
}
1477

    
1478
- (void)testCompressedBody
1479
{
1480
	
1481
	NSString *content = @"This is the test content. This is the test content. This is the test content. This is the test content.";
1482
	
1483
	// Test in memory compression / decompression
1484
	NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
1485

    
1486
	
1487
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/compressed_post_body"]];
1488
	[request setRequestMethod:@"PUT"];
1489
	[request setShouldCompressRequestBody:YES];
1490
	[request setShouldStreamPostDataFromDisk:YES];
1491
	[request setUploadProgressDelegate:self];
1492
	[request appendPostData:data];
1493
	[request startSynchronous];
1494

    
1495
	BOOL success = ([[request responseString] isEqualToString:content]);
1496
	GHAssertTrue(success,@"Failed to compress the body, or server failed to decompress it");
1497

    
1498
}
1499

    
1500

    
1501
// Ensure class convenience constructor returns an instance of our subclass
1502
- (void)testSubclass
1503
{
1504
	ASIHTTPRequestSubclass *instance = [ASIHTTPRequestSubclass requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1505
	BOOL success = [instance isKindOfClass:[ASIHTTPRequestSubclass class]];
1506
	GHAssertTrue(success,@"Convenience constructor failed to return an instance of the correct class");	
1507
}
1508

    
1509

    
1510
- (void)testThrottlingDownloadBandwidth
1511
{
1512
	[ASIHTTPRequest setMaxBandwidthPerSecond:0];
1513
	
1514
	// This content is around 128KB in size, and it won't be gzipped, so it should take more than 8 seconds to download at 14.5KB / second
1515
	// We'll test first without throttling
1516
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel_%28abridged%29.txt"]];
1517
	NSDate *date = [NSDate date];
1518
	[request startSynchronous];	
1519
	
1520
	NSTimeInterval interval =[date timeIntervalSinceNow];
1521
	BOOL success = (interval > -7);
1522
	GHAssertTrue(success,@"Downloaded the file too slowly - either this is a bug, or your internet connection is too slow to run this test (must be able to download 128KB in less than 7 seconds, without throttling)");
1523
	
1524
	// Now we'll test with throttling
1525
	[ASIHTTPRequest setMaxBandwidthPerSecond:ASIWWANBandwidthThrottleAmount];
1526
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel_%28abridged%29.txt"]];
1527
	date = [NSDate date];
1528
	[request startSynchronous];	
1529
	
1530
	[ASIHTTPRequest setMaxBandwidthPerSecond:0];
1531
	
1532
	interval =[date timeIntervalSinceNow];
1533
	success = (interval < -7);
1534
	GHAssertTrue(success,@"Failed to throttle download");		
1535
	GHAssertNil([request error],@"Request generated an error - timeout?");	
1536
	
1537
}
1538

    
1539
- (void)testThrottlingUploadBandwidth
1540
{
1541
	[ASIHTTPRequest setMaxBandwidthPerSecond:0];
1542
	
1543
	// Create a 64KB request body
1544
	NSData *data = [[[NSMutableData alloc] initWithLength:64*1024] autorelease];
1545
	
1546
	// We'll test first without throttling
1547
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ignore"]];
1548
	[request appendPostData:data];
1549
	NSDate *date = [NSDate date];
1550
	[request startSynchronous];	
1551
	
1552
	NSTimeInterval interval =[date timeIntervalSinceNow];
1553
	BOOL success = (interval > -3);
1554
	GHAssertTrue(success,@"Uploaded the data too slowly - either this is a bug, or your internet connection is too slow to run this test (must be able to upload 64KB in less than 3 seconds, without throttling)");
1555
	
1556
	// Now we'll test with throttling
1557
	[ASIHTTPRequest setMaxBandwidthPerSecond:ASIWWANBandwidthThrottleAmount];
1558
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ignore"]];
1559
	[request appendPostData:data];
1560
	date = [NSDate date];
1561
	[request startSynchronous];	
1562
	
1563
	[ASIHTTPRequest setMaxBandwidthPerSecond:0];
1564
	
1565
	interval =[date timeIntervalSinceNow];
1566
	success = (interval < -3);
1567
	GHAssertTrue(success,@"Failed to throttle upload");		
1568
	GHAssertNil([request error],@"Request generated an error - timeout?");	
1569
}
1570

    
1571

    
1572
- (void)testFetchToInvalidPath
1573
{
1574
	// Test gzipped content
1575
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL	URLWithString:@"http://allseeing-i.com"]];
1576
	[request setDownloadDestinationPath:@"/an/invalid/location.html"];
1577
	[request startSynchronous];
1578
	GHAssertNotNil([request error],@"Failed to generate an authentication when attempting to write to an invalid location");	
1579
	
1580
	//Test non-gzipped content
1581
	request = [ASIHTTPRequest requestWithURL:[NSURL	URLWithString:@"http://allseeing-i.com/i/logo.png"]];
1582
	[request setDownloadDestinationPath:@"/an/invalid/location.png"];
1583
	[request startSynchronous];
1584
	GHAssertNotNil([request error],@"Failed to generate an authentication when attempting to write to an invalid location");		
1585
}
1586

    
1587
- (void)testResponseStatusMessage
1588
{
1589
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL	URLWithString:@"http://allseeing-i.com/the-meaning-of-life"]];
1590
	[request startSynchronous];	
1591
	BOOL success = [[request responseStatusMessage] isEqualToString:@"HTTP/1.0 404 Not Found"];
1592
	GHAssertTrue(success,@"Got wrong response status message");
1593
}
1594

    
1595
- (void)testAsynchronous
1596
{
1597
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/first"]];
1598
	[request setTag:1];
1599
	[request setDidFailSelector:@selector(asyncFail:)];
1600
	[request setDidFinishSelector:@selector(asyncSuccess:)];
1601
	[request setDelegate:self];
1602
	[request startAsynchronous];
1603
	
1604
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/second"]];
1605
	[request setTag:2];
1606
	[request setDidFailSelector:@selector(asyncFail:)];
1607
	[request setDidFinishSelector:@selector(asyncSuccess:)];
1608
	[request setDelegate:self];
1609
	[request startAsynchronous];
1610
	
1611
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/third"]];
1612
	[request setTag:3];
1613
	[request setDidFailSelector:@selector(asyncFail:)];
1614
	[request setDidFinishSelector:@selector(asyncSuccess:)];
1615
	[request setDelegate:self];
1616
	[request startAsynchronous];	
1617
	
1618
	request = [ASIHTTPRequest requestWithURL:nil];
1619
	[request setTag:4];
1620
	[request setDidFailSelector:@selector(asyncFail:)];
1621
	[request setDidFinishSelector:@selector(asyncSuccess:)];
1622
	[request setDelegate:self];
1623
	[request startAsynchronous];	
1624
}
1625

    
1626

    
1627
- (void)asyncFail:(ASIHTTPRequest *)request
1628
{
1629
	BOOL success = ([request tag] == 4);
1630
	GHAssertTrue(success,@"Wrong request failed");
1631
}
1632

    
1633
- (void)asyncSuccess:(ASIHTTPRequest *)request
1634
{
1635
	BOOL success = ([request tag] != 4);
1636
	GHAssertTrue(success,@"Request succeeded when it should have failed");
1637
	
1638
	switch ([request tag]) {
1639
		case 1:
1640
			success = [[request responseString] isEqualToString:@"This is the expected content for the first string"];
1641
			break;
1642
		case 2:
1643
			success = [[request responseString] isEqualToString:@"This is the expected content for the second string"];
1644
			break;
1645
		case 3:
1646
			success = [[request responseString] isEqualToString:@"This is the expected content for the third string"];
1647
			break;
1648
	}
1649
	GHAssertTrue(success,@"Got wrong request content - very bad!");
1650
	
1651
}
1652

    
1653

    
1654

    
1655
// Will be called on Mac OS
1656
- (void)setDoubleValue:(double)newProgress;
1657
{
1658
	progress = (float)newProgress;
1659
}
1660

    
1661
// Will be called on iPhone OS
1662
- (void)setProgress:(float)newProgress;
1663
{
1664
	progress = newProgress;
1665
}
1666

    
1667
#if TARGET_OS_IPHONE
1668
- (void)testReachability
1669
{
1670
#if REACHABILITY_20_API
1671
	NSLog(@"Using Reachability 2.0 API");
1672
#else
1673
	NSLog(@"Using Reachability 1.5 API");
1674
#endif
1675
	if ([ASIHTTPRequest isNetworkReachableViaWWAN]) {
1676
		NSLog(@"Connected via WWAN");
1677
	} else {
1678
		NSLog(@"Not connected via WWAN");
1679
	}
1680
}
1681
#endif
1682

    
1683
- (void)testAutomaticRetry
1684
{
1685
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1686
	[request setTimeOutSeconds:0.001];
1687
	[request setNumberOfTimesToRetryOnTimeout:5];
1688
	[request startSynchronous];
1689
	GHAssertNotNil([request error],@"Request failed to timeout, cannot proceed with test");
1690
	BOOL success = ([request retryCount] == 5);
1691
	GHAssertTrue(success,@"Request failed to retry on timeout");
1692
}
1693

    
1694
- (void)testCopy
1695
{
1696
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1697
	
1698
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1699
	ASIHTTPRequest *request2 = [request copy];
1700
	
1701
	[pool release];
1702
	
1703
	GHAssertNotNil(request2,@"Failed to create a copy");
1704
	BOOL success = ([request2 retainCount] == 1);
1705
	GHAssertTrue(success,@"Failed to create a retained copy");
1706
	
1707
	[request2 release];
1708
}
1709

    
1710
- (void)testCloseConnection
1711
{
1712
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/close-connection"]];
1713
	[request startSynchronous];
1714
	
1715
	BOOL success = ![request connectionCanBeReused];
1716
	GHAssertTrue(success,@"Should not be able to re-use a request sent with Connection:close");
1717
	
1718
	// Ensure we close the connection when authentication is needed
1719
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/close-connection-auth-needed"]];
1720
	[request startSynchronous];
1721
	
1722
	success = ![request connectionCanBeReused];
1723
	GHAssertTrue(success,@"Should not be able to re-use a request sent with Connection:close");
1724
	
1725
}
1726

    
1727
- (void)testPersistentConnections
1728
{
1729
	// allseeing-i.com is configured to keep persistent connections alive for 2 seconds
1730

    
1731
	// Ensure we parse a keep-alive header
1732
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1733

    
1734
	BOOL success = ([request persistentConnectionTimeoutSeconds] == 60);
1735
	GHAssertTrue(success,@"Request failed to default to 60 seconds for connection timeout");
1736

    
1737
	[request startSynchronous];
1738

    
1739
	NSNumber *connectionId = [request connectionID];
1740

    
1741
	success = ([request persistentConnectionTimeoutSeconds] == 2);
1742
	GHAssertTrue(success,@"Request failed to use time out set by server");
1743

    
1744
	// Wait 3 seconds - connection should have timed out
1745
	sleep(3);
1746

    
1747
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1748
	[request startSynchronous];
1749

    
1750
	success = ([[request connectionID] intValue] != [connectionId intValue]);
1751
	GHAssertTrue(success,@"Reused a connection that should have timed out");
1752

    
1753
	// Ensure persistent connections are turned off by default with POST/PUT and/or a request body
1754
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1755
	[request appendPostData:[@"Foo" dataUsingEncoding:NSUTF8StringEncoding]];
1756
	[request startSynchronous];
1757

    
1758
	success = ![request shouldAttemptPersistentConnection];
1759
	GHAssertTrue(success,@"Used a persistent connection with a body");
1760

    
1761
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1762
	[request setRequestMethod:@"PUT"];
1763
	[request startSynchronous];
1764

    
1765
	success = ![request shouldAttemptPersistentConnection];
1766
	GHAssertTrue(success,@"Used a persistent connection with PUT");
1767

    
1768
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1769
	[request setRequestMethod:@"POST"];
1770
	[request startSynchronous];
1771

    
1772
	success = ![request shouldAttemptPersistentConnection];
1773
	GHAssertTrue(success,@"Used a persistent connection with POST");
1774

    
1775
	// Ensure we can force a persistent connection
1776
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1777
	[request setRequestMethod:@"POST"];
1778
	[request setShouldAttemptPersistentConnection:YES];
1779
	[request startSynchronous];
1780

    
1781
	success = [request shouldAttemptPersistentConnection];
1782
	GHAssertTrue(success,@"Failed to use a persistent connection");
1783
}
1784

    
1785
- (void)testRemoveUploadProgress
1786
{
1787
	[self performSelectorOnMainThread:@selector(runRemoveUploadProgressTest) withObject:nil waitUntilDone:YES];
1788
}
1789

    
1790
- (void)runRemoveUploadProgressTest
1791
{
1792
	progress = 0;
1793
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1794
	NSData *data = [[[NSMutableData alloc] initWithLength:64*1024] autorelease];
1795
	[request appendPostData:data];
1796
	[request setRequestMethod:@"POST"];
1797
	[request setUploadProgressDelegate:self];
1798
	[request startSynchronous];
1799
	
1800
	BOOL success = (progress == 1.0);
1801
	GHAssertTrue(success,@"Failed to set upload progress, cannot proceed with test");
1802
	
1803
	[request removeUploadProgressSoFar];
1804
	success = (progress == 0);
1805
	GHAssertTrue(success,@"Failed to set upload progress, cannot proceed with test");
1806
}
1807

    
1808
- (void)testMimeType
1809
{
1810
	NSString *text = @"This is my content";
1811
	NSString *filePath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"testfile.txt"];
1812
	[[text dataUsingEncoding:NSUTF8StringEncoding] writeToFile:filePath atomically:NO];
1813
	
1814
	BOOL success = ([[ASIHTTPRequest mimeTypeForFileAtPath:filePath] isEqualToString:@"text/plain"]);
1815
	GHAssertTrue(success,@"Failed to detect the mime type for a file");
1816
	
1817
	filePath = @"/nowhere";
1818
	success = (![ASIHTTPRequest mimeTypeForFileAtPath:filePath]);
1819
	GHAssertTrue(success,@"Returned a mime type for a non-existent file");
1820
	
1821
	filePath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"testfile"];
1822
	[[text dataUsingEncoding:NSUTF8StringEncoding] writeToFile:filePath atomically:NO];
1823
	success = ([[ASIHTTPRequest mimeTypeForFileAtPath:filePath] isEqualToString:@"application/octet-stream"]);
1824
	GHAssertTrue(success,@"Failed to return the default mime type when a file has no extension");
1825
}
1826

    
1827
- (void)testDelegateResponseDataHandling
1828
{
1829
	[self setResponseData:[NSMutableData dataWithLength:0]];
1830
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel_%28young_readers_edition%29.txt"]];
1831
	[request setDelegate:self];
1832
	[request setDidReceiveDataSelector:@selector(theTestRequest:didReceiveData:)];
1833
	[request setDidFinishSelector:@selector(theTestRequestFinished:)];
1834
	[request startAsynchronous];
1835
}
1836

    
1837
- (void)theTestRequestFinished:(ASIHTTPRequest *)request
1838
{
1839
	ASIHTTPRequest *request2 = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/the_great_american_novel_%28young_readers_edition%29.txt"]];
1840
	[request2 startSynchronous];
1841
	NSString *firstResponse = [[[NSString alloc] initWithBytes:[[self responseData] bytes] length:[[self responseData] length] encoding:[request responseEncoding]] autorelease];
1842
	BOOL success = [[request2 responseString] isEqualToString:firstResponse];
1843
	GHAssertTrue(success,@"Failed to correctly download and store the response using a delegate");
1844
}
1845

    
1846
- (void)theTestRequest:(ASIHTTPRequest *)request didReceiveData:(NSData *)data
1847
{
1848
	[[self responseData] appendData:data];
1849
}
1850

    
1851

    
1852
- (void)testNilPortCredentialsMatching
1853
{
1854
	// Test for http://github.com/pokeb/asi-http-request/issues#issue/39
1855
	[ASIHTTPRequest clearSession];
1856
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com:80/ASIHTTPRequest/tests/basic-authentication"]];
1857
	[request setUsername:@"secret_username"];
1858
	[request setPassword:@"secret_password"];
1859
	[request startSynchronous];
1860

    
1861
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/basic-authentication"]];
1862
	[request startSynchronous];
1863

    
1864
	// Now let's test the other way around
1865
	[ASIHTTPRequest clearSession];
1866

    
1867
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com:/ASIHTTPRequest/tests/basic-authentication"]];
1868
	[request setUsername:@"secret_username"];
1869
	[request setPassword:@"secret_password"];
1870
	[request startSynchronous];
1871

    
1872
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com:80/ASIHTTPRequest/tests/basic-authentication"]];
1873
	[request startSynchronous];
1874
}
1875

    
1876

    
1877
- (void)testRFC1123DateParsing
1878
{
1879
	unsigned dateUnits = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit;
1880
	NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
1881
	[calendar setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
1882
	NSString *dateString = @"Thu, 19 Nov 1981 08:52:01 GMT";
1883
	NSDate *date = [ASIHTTPRequest dateFromRFC1123String:dateString];
1884
	NSDateComponents *components = [calendar components:dateUnits fromDate:date];
1885
	BOOL success = ([components year] == 1981 && [components month] == 11 && [components day] == 19 && [components weekday] == 5 && [components hour] == 8 && [components minute] == 52 && [components second] == 1);
1886
	GHAssertTrue(success,@"Failed to parse an RFC1123 date correctly");
1887

    
1888
	dateString = @"4 May 2010 00:59 CET";
1889
	date = [ASIHTTPRequest dateFromRFC1123String:dateString];
1890
	components = [calendar components:dateUnits fromDate:date];
1891
	success = ([components year] == 2010 && [components month] == 5 && [components day] == 3 && [components hour] == 23 && [components minute] == 59);
1892
	GHAssertTrue(success,@"Failed to parse an RFC1123 date correctly");
1893

    
1894
}
1895

    
1896
- (void)testAccurateProgressFallback
1897
{
1898
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1899
	[request setAllowCompressedResponse:NO]; // A bit hacky - my server will send a chunked response (without content length) when we don't specify that we accept gzip
1900
	[request startSynchronous];
1901

    
1902
	BOOL success = ([request showAccurateProgress] == NO);
1903
	GHAssertTrue(success,@"Request failed to fall back to simple progress");
1904

    
1905
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect_resume"]];
1906
	[request startSynchronous];
1907

    
1908
	success = ([request showAccurateProgress] == YES);
1909
	GHAssertTrue(success,@"Request fell back to simple progress when redirecting");
1910
}
1911

    
1912
// Because of they way I implemented the server part of this test, I'm afraid you won't be able to run it yourself
1913

    
1914
- (void)testResumeWithAutomaticTimeoutRetry
1915
{
1916
	printf("\nSkipping testResumeWithAutomaticTimeoutRetry - ");
1917
	return;
1918
	// Get the first part of the response
1919
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/resume-with-timeout"]];
1920
	[request setAllowCompressedResponse:NO];
1921
	[request startSynchronous];
1922

    
1923
	NSString *partialPath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"partial.txt"];
1924
	[[request responseString] writeToFile:partialPath atomically:NO encoding:NSUTF8StringEncoding error:NULL];
1925

    
1926
	NSString *completePath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"complete.txt"];
1927

    
1928
	request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/resume-with-timeout-finish"]];
1929
	[request setAllowCompressedResponse:NO];
1930
	[request setAllowResumeForFileDownloads:YES];
1931
	[request setTemporaryFileDownloadPath:partialPath];
1932
	[request setDownloadDestinationPath:completePath];
1933
	[request setNumberOfTimesToRetryOnTimeout:1];
1934
	[request startSynchronous];
1935

    
1936
	NSString *expectedOutput = @"";
1937

    
1938
	char i;
1939
	for (i=0; i<3; i++) {
1940
		char *s;
1941
		s = (char *)malloc(1024*128);
1942
		memset(s, i+49, 1024*128);
1943
		expectedOutput = [expectedOutput stringByAppendingString:[[[NSString alloc] initWithBytes:s length:1024*128 encoding:NSUTF8StringEncoding] autorelease]];
1944
		expectedOutput = [expectedOutput stringByAppendingString:@"\r\n"];
1945
		free(s);
1946
	}
1947

    
1948
	BOOL success = [expectedOutput isEqualToString:[NSString stringWithContentsOfFile:completePath encoding:NSUTF8StringEncoding error:NULL]];
1949
	GHAssertTrue(success, @"Failed to send the correct Range headers to the server when resuming after a timeout");
1950
}
1951

    
1952
- (void)testChangeURLOnAuthenticationRetry
1953
{
1954
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/basic-authentication"]];
1955
	[request setDelegate:self];
1956
	[request setValidatesSecureCertificate:NO];
1957
	[request startAsynchronous];
1958
}
1959

    
1960
- (void)changeURLFailed:(ASIHTTPRequest *)request
1961
{
1962
	GHFail(@"Request failed when changing url");
1963
}
1964

    
1965
- (void)authenticationNeededForRequest:(ASIHTTPRequest *)request
1966
{
1967
	[request setUsername:@"foo"];
1968
	[request setPassword:@"foo"];
1969
	[request setDidFailSelector:@selector(changeURLFailed:)];
1970
	[request setURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1971
	[request retryUsingSuppliedCredentials];
1972
}
1973

    
1974
- (void)testDelegateRedirectHandling
1975
{
1976
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/redirect_to_ssl"]];
1977
	[request setDelegate:self];
1978
	[request setWillRedirectSelector:@selector(request:isGoingToRedirectToURL:)];
1979
	[request setDidFailSelector:@selector(redirectURLTestFailed:)];
1980
	[request setDidFinishSelector:@selector(redirectURLTestSucceeded:)];
1981
	[request startAsynchronous];
1982
}
1983

    
1984
- (void)redirectURLTestSucceeded:(ASIHTTPRequest *)request
1985
{
1986
	BOOL success = [[request url] isEqual:[NSURL URLWithString:@"http://allseeing-i.com"]];
1987
	GHAssertTrue(success,@"Request failed to redirect to url specified by delegate");
1988
}
1989

    
1990
- (void)redirectURLTestFailed:(ASIHTTPRequest *)request
1991
{
1992
	GHFail(@"Request failed, cannot proceed with test");
1993
}
1994

    
1995
- (void)request:(ASIHTTPRequest *)request isGoingToRedirectToURL:(NSURL *)url
1996
{
1997
	[request redirectToURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
1998
}
1999

    
2000
@synthesize responseData;
2001
@end