如何从给定的NSHTTPURLResponse获取HTTP协议版本?

时间:2016-09-06 08:06:16

标签: ios objective-c 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返回的响应。

2 个答案:

答案 0 :(得分:3)

没有公开的方式来访问NSHTTPURLResponse实例的http版本,并且响应的版本取决于请求版本。

如果您确实想要访问http版本,可以使用CFNetworking

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 getter方法获取此结构:

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

答案 1 :(得分:0)

请不要使用_CFURLResponse私有API,因为CFNetwork不能保证其返回值的格式。

查询HTTP版本的推荐方法是实现URLSession:task:didFinishCollectingMetrics:委托方法

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