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