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 |