URLSession for HTTP/2

I'm confused on how to initiate an HTTP/2 session. I keep seeing that URLSession supports it, but I don't know what that means. I'm on a mac (not iOS) and I've got all the code already to encode/decode the frames that the spec describes. Now I want to make a connection to the APNS server. I'm assuming I need to call the streamTask(withHostName:port:) method to get the bidirectional data stream?


Right after the streamTask constructor I called startSecureConnection() but it doesn't look like the session delegate's challenge method was ever called.


Let's assume that was working though. Would I then call captureStreams() at that point to get the InputStream and OutputStream items to then read and write to?

Replies

NSURLSession
will automatically use HTTP/2 for HTTPS requests if the server supports it. This isn’t something you have to configure. Rather, when you run an HTTPS task in the session it will, on opening the connection to the server, detect that it supports HTTP/2, set up an HTTP/2 connection, and then issue that task over that HTTP/2 connection.

Now I want to make a connection to the APNS server.

NSURLSession
is not a good match for APNS. APNS wants the push provider to open an HTTP/2 connection and keep it open indefinitely.
NSURLSession
was designed for typically client applications and doesn’t support that model. Specifically, it will automatically close the HTTP/2 connection after it’s been idle for a short period of time (last I checked that was one minute) and that’s exactly what you shouldn’t do in an APNS push provider because it can trigger the APNS denial of service attack checker.

I'm assuming I need to call the

streamTask(withHostName:port:)
method to get the bidirectional data stream?

You could do that, but then you’re just talking raw TCP with, optionally, TLS layered on top. You’d then have to implement HTTP/2 on top of that channel, which is a lot of work. You could use a third-party library to help with that, but at that point you might as well not use

NSURLSession
at all.

If you’d like

NSURLSession
to better support APNS, my recommendation is that you file an enhancement request along those lines (s. 637853075). Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the explanation, Quinn. Suggestions on what I should use instead then to make the connection to the APNS server?

Suggestions on what I should use instead then to make the connection to the APNS server?

You should use whatever HTTP/2 client is supported by the platform on which your push provider is running. On UNIX-y platforms a common choice is libcurl but I’ve not used it personally.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

NSURLSession uses HTTP/2 automatically for HTTP2 SSL server.

But NSURLSession uses HTTP/1.1 for HTTP/2 HTTP server(Not SSL).

Is there an option for NSURLSession to use HTTP/2 for HTTP/2 HTTP server?

Because it uses HTTP/1.1 and failed.