Как получить версию протокола HTTP из заданного NSHTTPURLResponse?

От NSHTTPURLResponse документации я не нашел способ получить HTTP версия (i.e. "HTTP/1.1" or "HTTP/1.0"),

HTTP поля заголовка доступны через все свойства полей заголовка, однако HTTP версия протокола не указана в полях заголовка, так как не HTTP заголовок.

Примечание: init, NSHTTPURLResponse инициализатор (initWithURL:statusCode:HTTPVersion:headerFields:) действительно требует HTTPVersion в качестве входных данных, так что теоретически он мог быть сохранен там.

Тем не менее, я не мог найти свойство или метод, чтобы получить HTTPVersion из данного ответа, например, ответа, возвращенного из NSURLSessionDataTask.

1 ответ

Решение

Нет общедоступного способа доступа к http-версии NSHTTPURLResponse экземпляр, и версия ответа зависит от версии запроса.

Ты можешь использовать CFNetworking если вы действительно хотите получить доступ к версии http.

CFN_EXPORT CFHTTPMessageRef 
CFHTTPMessageCreateResponse(
  CFAllocatorRef  __nullable alloc,
  CFIndex         statusCode,
  CFStringRef     __nullable statusDescription,
  CFStringRef     httpVersion)              CF_AVAILABLE(10_1, 2_0);

И CFHTTPMessageCopyVersion() возвращает версию HTTP.

На самом деле -[NSHTTPURLResponse initWithURL:(NSURL *)URL statusCode:(NSInteger)statusCode HTTPVersion:(NSString *)version headerFields:(NSDictionary *)fields] использования CFHTTPMessageCreateResponse создать ответ HTTP. см NSURLResponse.m

NSURLResponse опирается на _CFURLResponse структура.

typedef struct _CFURLResponse {
    CFRuntimeBase _base;
    CFAbsoluteTime creationTime;
    CFURLRef url;
    CFStringRef mimeType;
    int64_t expectedLength;
    CFStringRef textEncoding;
    CFIndex statusCode;
    CFStringRef httpVersion;
    CFDictionaryRef headerFields;
    Boolean isHTTPResponse;

    OSSpinLock parsedHeadersLock;
    ParsedHeaders* parsedHeaders;
} _CFURLResponse;

typedef const struct _CFURLResponse* CFURLResponseRef;

Вы можете получить эту структуру, используя _CFURLResponse метод получения на NSURLResponse пример:

CFTypeRef test = CFBridgingRetain([response performSelector:NSSelectorFromString(@"_CFURLResponse")]);
CFShow(test);

Пожалуйста, не используйте _CFURLResponse закрытый API, так как CFNetwork не предоставляет никаких гарантий формата возвращаемого значения.

Рекомендуемый способ запроса версии HTTP заключается в реализации URLSession:task:didFinishCollectingMetrics: метод делегата

https://developer.apple.com/documentation/foundation/nsurlsessiontasktransactionmetrics/1643141-networkprotocolname?language=objc

Другие вопросы по тегам