kong
kong

Reputation: 453

How to check data integrity when using NSURLConnection sendSynchronousRequest?

I use sendSynchronousRequest:returningResponse:error method of NSURLConnection class to get NSData from network.

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html

NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

What I want to do is to check if returned value is valid or not. So, what I did was to compare the length of the data with expected length in response header as below.

NSData *urlData;
do {
    urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    if ([urlData length] != [response expectedContentLength]) {
        NSLog(@"WTF!!!!!!!!! NSURLConnection response[%@] length[%lld] [%d]", [[response URL] absoluteString], [response expectedContentLength], [urlData length]);
        NSHTTPURLResponse *httpresponse = (NSHTTPURLResponse *) response;
        NSDictionary *dic = [httpresponse allHeaderFields];
        NSLog(@"[%@]", [dic description]);
    }
} while ([urlData length] != [response expectedContentLength]);

However, I don't know if it is enough to ensure the integrity of returned data. I can't check checksum of the file on the remote server.

Can you share your experience or other tips?

Thanks.

Upvotes: 1

Views: 1202

Answers (1)

Javier Giovannini
Javier Giovannini

Reputation: 2352

Create two variables in the class to store the length of data currently downloaded and the length of data expected (you could do more elegant)

int downloadedLength;
int expectedLength;

To know the lenght of expected data you have to get it from didReceiveResponse delegate

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{

//    NSLog(@"expected: %lld",response.expectedContentLength);
    expectedLength = response.expectedContentLength;
    downloadedLength = 0;
}

to update the downloadedLenght, you have to increase it in didReceiveData:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
downloadedLength = downloadedLength + [data length];
//...some code
}

then it is possible to do any logic to compare if downloaded data fit your requirements in connectionDidFinishLoading

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

    if (downloadedLength == expectedLength) {
        NSLog(@"correctly downloaded");
    }
    else{
        NSLog(@"sizes don't match");
        return;
    }
}

I had to do this to fix HJCache library issues with big pictures that downloaded incomplete (in HJMOHandler).

Upvotes: 2

Related Questions