7

I've configured HTTP/2 on a Jetty 9.3 server, it has a valid certificate and SSLLabs.com given it a grade A security configuration.

Browsing using Chrome to https://example.com loads the correct response, it's also reporting that "h2" (HTTP/2") protocol was used.

But when trying to access the same URL from iOS 9 using NSURLConnection, I can see in the request log that it used HTTP 1.1 instead. If I disable HTTP 1.1 on my server, the request will fail on iOS 9 (but still succeed on Chrome).

NSURLConnection code -

let url = NSURL(string: "https://example.com")
request = NSURLRequest(URL: url, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 10)

connection = NSURLConnection(request: request, delegate: self, startImmediately: true)

Server's ALPN debug output -

[S] ALPN protocols [spdy/3.1, spdy/3, http/1.1] received from client for 1e5e2487[SSLEngine[hostname=3.4.5.6 port=52090] SSL_NULL_WITH_NULL_NULL]
[S] ALPN protocol 'http/1.1' selected for 1e5e2487[SSLEngine[hostname=3.4.5.6 port=52090] SSL_NULL_WITH_NULL_NULL]

In WWDC 2015 it was stated that NSURLRequest in iOS 9 supports HTTP/2, but the client app claims to support spdy/3.1, spdy/3, http/1.1, no http/2. There are no NSAppTransportSecurity exceptions set.

I tried connecting to the server using Safari on the same iPhone Simulator running the app, this time it worked and used HTTP/2, here's ALPN debug output -

[S] ALPN protocols [h2, h2-16, h2-15, h2-14, spdy/3.1, spdy/3, http/1.1] received from client for 7b50217d[SSLEngine[hostname=3.4.5.6 port=52247] SSL_NULL_WITH_NULL_NULL]
[S] ALPN protocol 'h2' selected for 7b50217d[SSLEngine[hostname=3.4.5.6 port=52247] SSL_NULL_WITH_NULL_NULL]

Any ideas why it doesn't use HTTP/2 from within the app?

Kof
  • 23,893
  • 9
  • 56
  • 81

2 Answers2

13

HTTP/2 is only supported by NSURLSession. NSURLConnection has been deprecated in iOS 9. Here is the reference from the header:

enter image description here

HAS
  • 19,140
  • 6
  • 31
  • 53
  • If you absolutely have to support existing client code that uses `NSURLConnection`, I'm pretty sure it is possible to swizzle the `NSURLConnection` class, replacing every `NSURLConnection` method with calls into the shared session, and then simulate all of the delegate calls. I wouldn't recommend it, though, unless you have no other choice. :-) – dgatwood Sep 16 '15 at 07:44
  • Yeah that should be possible but, as you said, I don't think it's a good choice and in most cases it's not needed - you can just go with `NSURLSession` instead. – HAS Sep 16 '15 at 08:07
0

NSURLConnection is deprecated in iOS9, use NSURLSession it supports HTTP/2 protocol. ;)

itsji10dra
  • 4,603
  • 3
  • 39
  • 59