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



NSHTTPURLResponse文档中,我没有找到获得HTTP版本(i.e. "HTTP/1.1" or "HTTP/1.0")的方法。

HTTP报头字段通过所有报头字段属性可用,但是HTTP协议版本没有在报头字段内给出,因为它不是HTTP报头。

注: init, NSHTTPURLResponse初始化器(initWithURL:statusCode:HTTPVersion:headerFields:)确实需要HTTPVersion作为输入,所以理论上它可能已经保存在那里了。

然而,我找不到一个属性或方法来从给定的响应中获得HTTPVersion,例如从NSURLSessionDataTask返回的响应。

没有公共方式访问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;

你可以在NSURLResponse实例上使用_CFURLResponse getter方法获得这个结构体:

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

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

建议使用URLSession:task:didFinishCollectingMetrics:委托方法查询HTTP版本

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

相关内容

  • 没有找到相关文章

最新更新