uniqush/uniqush-push

APNS HTTP (HTTP2) support

TysonAndre opened this issue · 2 comments

See Apple's documentation at https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html

http://gobiko.com/blog/token-based-authentication-http2-example-apns/ seems like it may help explain high level of setting this up?

Probably implement this with provider certificates if the main use case is self-service, not familiar with the use case for tokens. #149 is related to this.

Miscellaneous notes on how this should be implemented:

  • Apple has guidelines on how individual HTTP2 header names should be encoded. The last time I checked, golang didn't have an API to do that. I'm not sure if it's an issue in practice.
  • encode without escaping unicode, like the binary protocol
  • The api provider abstraction may or may not work (srv/apns/binary_api is one "api" implementing a golang interface, srv/apns/http2_api would be another)
  • Need to investigate if this will significantly change CPU load or network usage.
    For easy migration and testing, one possibility may be to allow adding an option to /push (uniqush.push.protocol=http2) to opt into the HTTP2 api. This gives you accurate results for the push, but increases latency somewhat.
  • Uniqush clients should not notice the effects of this change unless they're configured to, at least not until a major/minor version bump.
    Config file settings can be changed, etc.
  • Need a way to migrating without losing track of subscribers in a service. Unit test this. (See apns-test.sh, which still needs to support binary protocol v2
  • Be careful about connect/send/dns lookup timeouts
  • If you don't receive a response within some time limit (e.g. 1s), send a timeout response to the uniqush client?
  • Can the cert/key be reused from binary clients
  • Bump payload limit to from 2048 to 4096

golang/go#15592 - seems like header guidelines aren't important

To enable this,

  1. First, you must add bundleid=com.myapp to the query params in a call to /addpsp (Where your app build's bundleid for that environmentis com.myapp).
    (This can be used to modify a pre-existing PSP and keep existing subscriber. You have to provide every single field you used in the previous call to /addpsp, e.g. if it's a sandbox, you have to set sandbox=true)

    If there is no bundle id, then APNs can't accept the push over HTTP2.

  2. set uniqush.http2=1 in the query param in a call to /push to enable it for that push.

    (If the bundle id is somehow different for that app (e.g. build for QAing with a different app), the push will fail)