Merge pull request #10545 from Mazyod/ios-http-request-leaks

Fix major memory leaks in iOS http request
This commit is contained in:
minggo 2015-02-26 15:41:10 +08:00
commit e37bbee1c2
3 changed files with 38 additions and 18 deletions

View File

@ -36,7 +36,7 @@
@property (strong) NSString *sslFile; @property (strong) NSString *sslFile;
@property (strong) NSDictionary *responseHeader; @property (copy) NSDictionary *responseHeader;
@property (strong) NSMutableData *responseData; @property (strong) NSMutableData *responseData;

View File

@ -24,6 +24,12 @@
#import "HttpAsynConnection.h" #import "HttpAsynConnection.h"
@interface HttpAsynConnection ()
@property (readwrite) NSString *statusString;
@end
@implementation HttpAsynConnection @implementation HttpAsynConnection
@synthesize srcURL; @synthesize srcURL;
@ -38,19 +44,33 @@
@synthesize finish; @synthesize finish;
@synthesize runLoop; @synthesize runLoop;
- (void)dealloc
{
[srcURL release];
[sslFile release];
[responseHeader release];
[responseData release];
[statusString release];
[responseError release];
[conn release];
[runLoop release];
[super dealloc];
}
- (void) startRequest:(NSURLRequest *)request - (void) startRequest:(NSURLRequest *)request
{ {
NSLog(@"Starting to load %@", srcURL); NSLog(@"Starting to load %@", srcURL);
finish = false; finish = false;
responseData = [NSMutableData new]; self.responseData = [NSMutableData data];
getDataTime = 0; getDataTime = 0;
responseError = nil; self.responseError = nil;
// create the connection with the target request and this class as the delegate // create the connection with the target request and this class as the delegate
self.conn = [[NSURLConnection alloc] initWithRequest:request self.conn = [[[NSURLConnection alloc] initWithRequest:request
delegate:self delegate:self
startImmediately:NO]; startImmediately:NO] autorelease];
[self.conn scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.conn scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
@ -71,12 +91,12 @@
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
//NSLog(@"All headers = %@", [httpResponse allHeaderFields]); //NSLog(@"All headers = %@", [httpResponse allHeaderFields]);
responseHeader = [[httpResponse allHeaderFields] copy]; self.responseHeader = [httpResponse allHeaderFields];
responseCode = httpResponse.statusCode; responseCode = httpResponse.statusCode;
statusString = [[NSHTTPURLResponse localizedStringForStatusCode:responseCode] copy]; self.statusString = [NSHTTPURLResponse localizedStringForStatusCode:responseCode];
if(responseCode == 200) if(responseCode == 200)
statusString = @"OK"; self.statusString = @"OK";
/*The individual values of the numeric status codes defined for HTTP/1.1 /*The individual values of the numeric status codes defined for HTTP/1.1
| 200 ; OK | 200 ; OK
@ -118,7 +138,7 @@
didFailWithError:(NSError *)error didFailWithError:(NSError *)error
{ {
//NSLog(@"Load failed with error %@", [error localizedDescription]); //NSLog(@"Load failed with error %@", [error localizedDescription]);
responseError = [error copy]; self.responseError = error;
finish = true; finish = true;
} }

View File

@ -77,8 +77,8 @@ void HttpClient::networkThread()
{ {
auto scheduler = Director::getInstance()->getScheduler(); auto scheduler = Director::getInstance()->getScheduler();
while (true) while (true) @autoreleasepool {
{
HttpRequest *request; HttpRequest *request;
// step 1: send http request if the requestQueue isn't empty // step 1: send http request if the requestQueue isn't empty
@ -224,16 +224,16 @@ static int processTask(HttpRequest *request, NSString* requestType, void *stream
} }
} }
HttpAsynConnection *httpAsynConn = [HttpAsynConnection new]; HttpAsynConnection *httpAsynConn = [[HttpAsynConnection new] autorelease];
httpAsynConn.srcURL = urlstring; httpAsynConn.srcURL = urlstring;
httpAsynConn.sslFile = nil; httpAsynConn.sslFile = nil;
NSString *sslFile = nil;
if(!s_sslCaFilename.empty()) if(!s_sslCaFilename.empty())
{ {
long len = s_sslCaFilename.length(); long len = s_sslCaFilename.length();
long pos = s_sslCaFilename.rfind('.', len-1); long pos = s_sslCaFilename.rfind('.', len-1);
[sslFile initWithUTF8String:s_sslCaFilename.substr(0, pos-1).c_str()];
httpAsynConn.sslFile = sslFile; httpAsynConn.sslFile = [NSString stringWithUTF8String:s_sslCaFilename.substr(0, pos-1).c_str()];
} }
[httpAsynConn startRequest:nsrequest]; [httpAsynConn startRequest:nsrequest];
@ -281,8 +281,8 @@ static int processTask(HttpRequest *request, NSString* requestType, void *stream
} }
//handle response header //handle response header
NSMutableString *header = [NSMutableString new]; NSMutableString *header = [NSMutableString string];
[header appendFormat:@"HTTP/1.1 %ld %@\n", httpAsynConn.responseCode, httpAsynConn.statusString]; [header appendFormat:@"HTTP/1.1 %ld %@\n", (long)httpAsynConn.responseCode, httpAsynConn.statusString];
for (id key in httpAsynConn.responseHeader) for (id key in httpAsynConn.responseHeader)
{ {
[header appendFormat:@"%@: %@\n", key, [httpAsynConn.responseHeader objectForKey:key]]; [header appendFormat:@"%@: %@\n", key, [httpAsynConn.responseHeader objectForKey:key]];