We now dump all cookies on redirection (cookies stored in the peristent store will be re-applied)
Fix memory leak on redirection Thanks to Austin France for highlighting these issues!
Showing
3 changed files
with
24 additions
and
12 deletions
@@ -319,13 +319,15 @@ extern NSString* const NetworkRequestErrorDomain; | @@ -319,13 +319,15 @@ extern NSString* const NetworkRequestErrorDomain; | ||
319 | // Called when a request fails, and lets the delegate now via didFailSelector | 319 | // Called when a request fails, and lets the delegate now via didFailSelector |
320 | - (void)failWithError:(NSError *)theError; | 320 | - (void)failWithError:(NSError *)theError; |
321 | 321 | ||
322 | -#pragma mark http authentication stuff | 322 | +#pragma mark parsing HTTP response headers |
323 | 323 | ||
324 | // Reads the response headers to find the content length, encoding, cookies for the session | 324 | // Reads the response headers to find the content length, encoding, cookies for the session |
325 | // Also initiates request redirection when shouldRedirect is true | 325 | // Also initiates request redirection when shouldRedirect is true |
326 | // Returns true if the request needs a username and password (or if those supplied were incorrect) | 326 | // Returns true if the request needs a username and password (or if those supplied were incorrect) |
327 | - (BOOL)readResponseHeadersReturningAuthenticationFailure; | 327 | - (BOOL)readResponseHeadersReturningAuthenticationFailure; |
328 | 328 | ||
329 | +#pragma mark http authentication stuff | ||
330 | + | ||
329 | // Apply credentials to this request | 331 | // Apply credentials to this request |
330 | - (BOOL)applyCredentials:(NSMutableDictionary *)newCredentials; | 332 | - (BOOL)applyCredentials:(NSMutableDictionary *)newCredentials; |
331 | 333 |
@@ -206,8 +206,7 @@ static NSError *ASITooMuchRedirectionError; | @@ -206,8 +206,7 @@ static NSError *ASITooMuchRedirectionError; | ||
206 | } | 206 | } |
207 | } | 207 | } |
208 | 208 | ||
209 | - if ([self postLength] > 0) | 209 | + if ([self postLength] > 0) { |
210 | - { | ||
211 | if (![requestMethod isEqualToString:@"POST"] && ![requestMethod isEqualToString:@"PUT"]) { | 210 | if (![requestMethod isEqualToString:@"POST"] && ![requestMethod isEqualToString:@"PUT"]) { |
212 | [self setRequestMethod:@"POST"]; | 211 | [self setRequestMethod:@"POST"]; |
213 | } | 212 | } |
@@ -339,8 +338,13 @@ static NSError *ASITooMuchRedirectionError; | @@ -339,8 +338,13 @@ static NSError *ASITooMuchRedirectionError; | ||
339 | [self buildPostBody]; | 338 | [self buildPostBody]; |
340 | } | 339 | } |
341 | 340 | ||
341 | + // If we're redirecting, we'll already have a CFHTTPMessageRef | ||
342 | + if (request) { | ||
343 | + CFRelease(request); | ||
344 | + } | ||
345 | + | ||
342 | // Create a new HTTP request. | 346 | // Create a new HTTP request. |
343 | - request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, (CFStringRef)requestMethod, (CFURLRef)url, [self useHTTPVersionOne] ? kCFHTTPVersion1_0 : kCFHTTPVersion1_1); | 347 | + request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, (CFStringRef)[self requestMethod], (CFURLRef)[self url], [self useHTTPVersionOne] ? kCFHTTPVersion1_0 : kCFHTTPVersion1_1); |
344 | if (!request) { | 348 | if (!request) { |
345 | [self failWithError:ASIUnableToCreateRequestError]; | 349 | [self failWithError:ASIUnableToCreateRequestError]; |
346 | return; | 350 | return; |
@@ -348,7 +352,7 @@ static NSError *ASITooMuchRedirectionError; | @@ -348,7 +352,7 @@ static NSError *ASITooMuchRedirectionError; | ||
348 | 352 | ||
349 | 353 | ||
350 | // If we've already talked to this server and have valid credentials, let's apply them to the request | 354 | // If we've already talked to this server and have valid credentials, let's apply them to the request |
351 | - if (useSessionPersistance && sessionCredentials && sessionAuthentication) { | 355 | + if ([self useSessionPersistance] && sessionCredentials && sessionAuthentication) { |
352 | if (!CFHTTPMessageApplyCredentialDictionary(request, sessionAuthentication, (CFMutableDictionaryRef)sessionCredentials, NULL)) { | 356 | if (!CFHTTPMessageApplyCredentialDictionary(request, sessionAuthentication, (CFMutableDictionaryRef)sessionCredentials, NULL)) { |
353 | [ASIHTTPRequest setSessionAuthentication:NULL]; | 357 | [ASIHTTPRequest setSessionAuthentication:NULL]; |
354 | [ASIHTTPRequest setSessionCredentials:nil]; | 358 | [ASIHTTPRequest setSessionCredentials:nil]; |
@@ -356,10 +360,10 @@ static NSError *ASITooMuchRedirectionError; | @@ -356,10 +360,10 @@ static NSError *ASITooMuchRedirectionError; | ||
356 | } | 360 | } |
357 | 361 | ||
358 | // Add cookies from the persistant (mac os global) store | 362 | // Add cookies from the persistant (mac os global) store |
359 | - if (useCookiePersistance) { | 363 | + if ([self useCookiePersistance] ) { |
360 | - NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:url]; | 364 | + NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[self url]]; |
361 | if (cookies) { | 365 | if (cookies) { |
362 | - [requestCookies addObjectsFromArray:cookies]; | 366 | + [[self requestCookies] addObjectsFromArray:cookies]; |
363 | } | 367 | } |
364 | } | 368 | } |
365 | 369 | ||
@@ -399,7 +403,7 @@ static NSError *ASITooMuchRedirectionError; | @@ -399,7 +403,7 @@ static NSError *ASITooMuchRedirectionError; | ||
399 | // Should this request resume an existing download? | 403 | // Should this request resume an existing download? |
400 | if ([self allowResumeForFileDownloads] && [self downloadDestinationPath] && [self temporaryFileDownloadPath] && [[NSFileManager defaultManager] fileExistsAtPath:[self temporaryFileDownloadPath]]) { | 404 | if ([self allowResumeForFileDownloads] && [self downloadDestinationPath] && [self temporaryFileDownloadPath] && [[NSFileManager defaultManager] fileExistsAtPath:[self temporaryFileDownloadPath]]) { |
401 | [self setPartialDownloadSize:[[[NSFileManager defaultManager] fileAttributesAtPath:[self temporaryFileDownloadPath] traverseLink:NO] fileSize]]; | 405 | [self setPartialDownloadSize:[[[NSFileManager defaultManager] fileAttributesAtPath:[self temporaryFileDownloadPath] traverseLink:NO] fileSize]]; |
402 | - [self addRequestHeader:@"Range" value:[NSString stringWithFormat:@"bytes=%llu-",partialDownloadSize]]; | 406 | + [self addRequestHeader:@"Range" value:[NSString stringWithFormat:@"bytes=%llu-",[self partialDownloadSize]]]; |
403 | } | 407 | } |
404 | 408 | ||
405 | // Add custom headers | 409 | // Add custom headers |
@@ -413,7 +417,7 @@ static NSError *ASITooMuchRedirectionError; | @@ -413,7 +417,7 @@ static NSError *ASITooMuchRedirectionError; | ||
413 | } | 417 | } |
414 | NSString *header; | 418 | NSString *header; |
415 | for (header in headers) { | 419 | for (header in headers) { |
416 | - CFHTTPMessageSetHeaderFieldValue(request, (CFStringRef)header, (CFStringRef)[requestHeaders objectForKey:header]); | 420 | + CFHTTPMessageSetHeaderFieldValue(request, (CFStringRef)header, (CFStringRef)[[self requestHeaders] objectForKey:header]); |
417 | } | 421 | } |
418 | 422 | ||
419 | // If this is a post/put request and we store the request body in memory, add it to the request | 423 | // If this is a post/put request and we store the request body in memory, add it to the request |
@@ -986,8 +990,7 @@ static NSError *ASITooMuchRedirectionError; | @@ -986,8 +990,7 @@ static NSError *ASITooMuchRedirectionError; | ||
986 | } | 990 | } |
987 | } | 991 | } |
988 | 992 | ||
989 | - | 993 | +#pragma mark parsing HTTP response headers |
990 | -#pragma mark http authentication | ||
991 | 994 | ||
992 | - (BOOL)readResponseHeadersReturningAuthenticationFailure | 995 | - (BOOL)readResponseHeadersReturningAuthenticationFailure |
993 | { | 996 | { |
@@ -1069,6 +1072,11 @@ static NSError *ASITooMuchRedirectionError; | @@ -1069,6 +1072,11 @@ static NSError *ASITooMuchRedirectionError; | ||
1069 | } | 1072 | } |
1070 | [self setURL:[[NSURL URLWithString:[responseHeaders valueForKey:@"Location"] relativeToURL:[self url]] absoluteURL]]; | 1073 | [self setURL:[[NSURL URLWithString:[responseHeaders valueForKey:@"Location"] relativeToURL:[self url]] absoluteURL]]; |
1071 | [self setNeedsRedirect:YES]; | 1074 | [self setNeedsRedirect:YES]; |
1075 | + | ||
1076 | + // Clear the request cookies | ||
1077 | + // This means manually added cookies will not be added to the redirect request - only those stored in the global persistent store | ||
1078 | + // But, this is probably the safest option - we might be redirecting to a different domain | ||
1079 | + [self setRequestCookies:[NSMutableArray array]]; | ||
1072 | } | 1080 | } |
1073 | } | 1081 | } |
1074 | 1082 | ||
@@ -1079,6 +1087,7 @@ static NSError *ASITooMuchRedirectionError; | @@ -1079,6 +1087,7 @@ static NSError *ASITooMuchRedirectionError; | ||
1079 | return isAuthenticationChallenge; | 1087 | return isAuthenticationChallenge; |
1080 | } | 1088 | } |
1081 | 1089 | ||
1090 | +#pragma mark http authentication | ||
1082 | 1091 | ||
1083 | - (void)saveCredentialsToKeychain:(NSMutableDictionary *)newCredentials | 1092 | - (void)saveCredentialsToKeychain:(NSMutableDictionary *)newCredentials |
1084 | { | 1093 | { |
@@ -744,6 +744,7 @@ | @@ -744,6 +744,7 @@ | ||
744 | GHAssertTrue(success,@"Convenience constructor failed to return an instance of the correct class"); | 744 | GHAssertTrue(success,@"Convenience constructor failed to return an instance of the correct class"); |
745 | } | 745 | } |
746 | 746 | ||
747 | + | ||
747 | @end | 748 | @end |
748 | 749 | ||
749 | 750 |
-
Please register or login to post a comment