Как проверить целостность данных при использовании NSURLConnection sendSynchronousRequest?

Я использую метод sendSynchronousRequest:returningResponse:error класса NSURLConnection для получения NSData из сети.

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];

Что я хочу сделать, так это проверить, действительно ли возвращаемое значение или нет. Итак, что я сделал, так это сравнил длину данных с ожидаемой длиной в заголовке ответа, как показано ниже.

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]);

Однако я не знаю, достаточно ли этого для обеспечения целостности возвращаемых данных. Я не могу проверить контрольную сумму файла на удаленном сервере.

Можете ли вы поделиться своим опытом или другими советами?

Спасибо.


person kong    schedule 17.01.2012    source источник
comment
Вы проверяете длину данных, а не целостность. В зависимости от того, насколько важна для вас целостность, вы можете реализовать алгоритм на основе хэшей, более сложную подпись сообщений или использовать HTTPS. Но в любом случае это потребует некоторой работы на стороне сервера. Клиент хеширует или подписывает сообщение, затем сервер проверяет. Вы упомянули, что не можете сделать это на стороне сервера, поэтому целостность не может быть обеспечена.   -  person He Shiming    schedule 20.03.2012


Ответы (1)


Создайте две переменные в классе для хранения длины загруженных данных и ожидаемой длины данных (вы могли бы сделать более элегантно)

int downloadedLength;
int expectedLength;

Чтобы узнать длину ожидаемых данных, вы должны получить их от делегата didReceiveResponse.

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

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

чтобы обновить загруженную длину, вы должны увеличить ее в didReceiveData:

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

тогда можно выполнить любую логику, чтобы сравнить, соответствуют ли загруженные данные вашим требованиям в connectionDidFinishLoading

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

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

Мне пришлось сделать это, чтобы исправить проблемы библиотеки HJCache с большими изображениями, которые загружались не полностью (в HJMOHandler).

person Javier Giovannini    schedule 18.03.2012
comment
Я столкнулся с этой точной проблемой с этой точной библиотекой. Просто хотел сказать спасибо за явное изложение этого. - person mousebird; 14.04.2012