Как заставить NSURLSession возвращать Content-Length (http-заголовок) с сервера. Objective-c, iOS

Я потратил много часов, пытаясь безуспешно пробовать различные идеи, найденные в сообщениях по этому вопросу. Когда я использую curl, я получаю желаемый заголовок: Content-Length.

Вот моя последняя попытка (найденная где-то на SO):

- (void) trythis {

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:myURL];
    request.HTTPMethod = @"HEAD";


    NSURLSessionDownloadTask *uploadTask
        = [session downloadTaskWithRequest:request
                 completionHandler:^(NSURL *url,NSURLResponse *response,NSError *error) {
                     NSLog(@"handler size: %lld", response.expectedContentLength);
                     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
                     NSDictionary* headers = [httpResponse allHeaderFields];
                     NSArray *keys = [headers allKeys];
                     for( NSString *key in keys){
                         NSLog(@"key: %@ : %@", key, [headers valueForKey:key]);
                     }
                     NSLog(@"");

                 }];

    // 5
    [uploadTask resume];
}

Он возвращает эти заголовки:

ключ: Vary: Accept-Encoding, ключ пользователя-агента: Сервер: Apache / 2.4.12 ключ: Подключение: Keep-Alive key: Последнее изменение: Сб, 13 июня 2015 г. 23:03:46 GMT ключ: Content-Type: ключ audio / mpeg: Accept-Ranges: ключ байтов: Дата: Вт, 12 апреля 2016 г. 17:59:21 GMT ключ: Content-Encoding: gzip

Используя curl (на MacBook), я получаю:

curl -I http://boulderhomegrown.com/fiddletunes/JerusalemRidge-100.mp3

HTTP / 1.1 200 OK Дата: Вт, 12 апреля 2016 г. 14:55:17 GMT Сервер: Apache / 2.4.12 Последнее изменение: Сб, 13 июня 2015 г. 23:03:46 GMT ETag: "2ec0bc0-1a172e-5186e3ca6b55f" Принять -Диапазоны: байты Content-Length: 1709870 Варьируются: Accept-Encoding, User-Agent Content-Type: audio / mpeg

ОБРАТИТЕ ВНИМАНИЕ, что Content-Length !! И, конечно же, URL в обоих случаях одинаковый. Это переменная экземпляра в моей objective-c.


person john ware    schedule 12.04.2016    source источник
comment
Что было не так с response.expectedContentLength, как вы это использовали?   -  person jtbandes    schedule 12.04.2016
comment
Похоже, ваша команда curl выполняет запрос GET, а ваш NSURLSession - запрос HEAD. Что будет, если удалить request.HTTPMethod = @"HEAD";?   -  person EricS    schedule 12.04.2016
comment
EricS, ответ действительно содержит правильное значение expectContentLength. NSURL * указывает на локальный временный файл; чего и следовало ожидать от GET. Похоже, это загрузка файла и сообщение о количестве переданных байтов. Моя цель заключалась в том, чтобы получить файл, чтобы инициализировать просмотр хода выполнения. Я не хочу загружать файл до получения удаленного размера файла. И чтобы быть придирчивым, заголовок Content-Length не включается в ответ. Спасибо за помощь.   -  person john ware    schedule 13.04.2016
comment
Исправление: Моя цель заключалась в том, чтобы получить размер файла только для того, чтобы инициализировать индикатор выполнения.   -  person john ware    schedule 13.04.2016


Ответы (1)


По умолчанию отправляемый вами запрос имеет заголовок - Accept-Encoding: gzip, deflate и серверный apache в этом случае не добавляют длину содержимого заголовка (по умолчанию для больших файлов). Итак, если вы замените этот заголовок на value: identity. Это обеспечит правильный размер файла.

Вот код:

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:myURL];
request.HTTPMethod = @"HEAD";
[request addValue:@"identity" forHTTPHeaderField:@"Accept-Encoding"];

Просто добавьте поле, и у вас будет правильный заголовок в ответе, например, curl -I.

person Kaloyan Dobrev    schedule 12.04.2016
comment
Калоян, это приводит к тому, что ответ содержит заголовок Content-Length; спасибо, дополнительный вопрос: NSURL * в завершенииHandler указывает на файл tmp на устройстве. Как вы думаете, файл загрузился? У меня нет инструмента для просмотра этого каталога. - person john ware; 13.04.2016
comment
@kaloyan, как получить его методом POST. заголовок идентификатора не работает для меня. - person Manish; 29.01.2020