2

From NSHTTPURLResponse documentation, I did not find a way to get the HTTP version (i.e. "HTTP/1.1" or "HTTP/1.0").

HTTP header fields are available through all Header Fields property, however the HTTP protocol version is not given inside the header fields as it is not an HTTP header.

Note: init, NSHTTPURLResponse initializer (initWithURL:statusCode:HTTPVersion:headerFields:) does require the HTTPVersion as an input, so theoretically it may have been saved there.

However, I couldn't find a property or method to get the HTTPVersion from a given response, for example a response returned from an NSURLSessionDataTask.

vaibhav
  • 4,038
  • 1
  • 21
  • 51
AmitW
  • 798
  • 8
  • 11

2 Answers2

3

There's no public way to access the http version of an NSHTTPURLResponse instance, and the version of response is depended on the request version.

You can use CFNetworking if you really want to access the http version.

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

And the CFHTTPMessageCopyVersion() returns the HTTP version.

Actually the -[NSHTTPURLResponse initWithURL:(NSURL *)URL statusCode:(NSInteger)statusCode HTTPVersion:(NSString *)version headerFields:(NSDictionary *)fields] uses CFHTTPMessageCreateResponse to create a HTTP response. see NSURLResponse.m

The NSURLResponse is backed upon the _CFURLResponse struct.

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;

You can get this struct using _CFURLResponse getter method on a NSURLResponse instance:

CFTypeRef test = CFBridgingRetain([response performSelector:NSSelectorFromString(@"_CFURLResponse")]);
CFShow(test);
Elf Sundae
  • 1,575
  • 16
  • 23
1

Please don’t use _CFURLResponse private API, as CFNetwork doesn’t provide any guarantee of the format of its return value.

The recommended way to query HTTP version is to implement URLSession:task:didFinishCollectingMetrics: delegate method

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

Guoye Zhang
  • 499
  • 4
  • 9