rpush 3.1.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: deccc35a73da0b426daeb20fdbbe287be5e9df9e4b8c8fcd5ef2b69c6663da68
4
- data.tar.gz: c7038ba47604bde8a322beff513ab999e1a2692e56bd83b983cb757301e7e590
3
+ metadata.gz: 2177b25e8710a0539b82b9bade18da563e0b1b1f5509da42be346969a909e83b
4
+ data.tar.gz: 2c46fec2c2c9858caf0447e2dc5843fae5249edc5b08604141ea3ecbaa95fb5f
5
5
  SHA512:
6
- metadata.gz: 2a405b20855ef2d3c77f33c842058f95da8c7436a911712e221d5d199af82708dc8b5757f11219d2e31787311f8ea8f25384f85821c806f5492998436770743e
7
- data.tar.gz: 4fdfe15b520768b4cbcc24c09c8859fa220fccfe18aed3a00680ff317d70ef95a4503f240262a1bdaf4aa0c4ea10be20478a4d1080e11b9b466458a8a68374c0
6
+ metadata.gz: c45d7e698704104dc19487636dba80a7278b739a6377d091b334ecedbe90c9b8475f08329e4a767e2ad45d7c3e9981d927558dd21c09e9de7c3cba20fb825993
7
+ data.tar.gz: 2ae04d72abc05c39c16605f545f78a2a8e829a60a1c6280b68df4e66d28d4c522e47b29ef9b259c18bf2e9b61c90955a686af07582d6426b679c2550851dc16e
data/CHANGELOG.md CHANGED
@@ -12,8 +12,22 @@
12
12
 
13
13
  - None
14
14
 
15
+ ## 3.2.0 (2018-06-13)
16
+
17
+ When upgrading, don't forget to run `bundle exec rpush init` to get all the latest migrations.
18
+
19
+ ### Breaking Changes
20
+
21
+ - None
22
+
23
+ ### Added
24
+
25
+ - Added support for P8 certificate Apple push notifications [#386](https://github.com/rpush/rpush/pull/386) (by [@mariannegru](https://github.com/mariannegru)
26
+
15
27
  ## 3.1.1 (2018-04-16)
16
28
 
29
+ When upgrading, don't forget to run `bundle exec rpush init` to get all the latest migrations.
30
+
17
31
  ### Breaking Changes
18
32
 
19
33
  - None
data/README.md CHANGED
@@ -80,10 +80,34 @@ You should also implement the [ssl_certificate_will_expire](https://github.com/r
80
80
 
81
81
  To use the newer APNs Api replace `Rpush::Apns::App` with `Rpush::Apns2::App`.
82
82
 
83
+ To use the p8 APNs Api replace `Rpush::Apns::App` with `Rpush::Apnsp8::App`.
84
+
85
+ ```ruby
86
+ app = Rpush::Apnsp8::App.new
87
+ app.name = "ios_app"
88
+ app.apn_key = File.read("/path/to/sandbox.p8")
89
+ app.environment = "development" # APNs environment.
90
+ app.apn_key_id = "APN KEY ID"
91
+ app.team_id = "TEAM ID"
92
+ app.bundle_id = "BUNDLE ID"
93
+ app.connections = 1
94
+ app.save!
95
+ ```
96
+
97
+ ```ruby
98
+ n = Rpush::Apns::Notification.new
99
+ n.app = Rpush::Apnsp8::App.find_by_name("ios_app")
100
+ n.device_token = "..." # 64-character hex string
101
+ n.alert = "hi mom!"
102
+ n.data = { foo: :bar }
103
+ n.save!
104
+ ```
83
105
  #### Firebase Cloud Messaging
84
106
 
85
107
  FCM and GCM are – as of writing – compatible with each other. See also [this comment](https://github.com/rpush/rpush/issues/284#issuecomment-228330206) for further references.
86
108
 
109
+ Please refer to the Firebase Console on where to find your `auth_key` (probably called _Server Key_ there). To verify you have the right key, use tools like [Postman](https://www.getpostman.com/), [HTTPie](https://httpie.org/), `curl` or similar before reporting a new issue. See also [this comment](https://github.com/rpush/rpush/issues/346#issuecomment-289218776).
110
+
87
111
  ```ruby
88
112
  app = Rpush::Gcm::App.new
89
113
  app.name = "android_app"
@@ -46,6 +46,7 @@ class RpushMigrationGenerator < Rails::Generators::Base
46
46
  add_rpush_migration('rpush_3_0_1_updates')
47
47
  add_rpush_migration('rpush_3_1_0_add_pushy')
48
48
  add_rpush_migration('rpush_3_1_1_updates')
49
+ add_rpush_migration('rpush_3_2_0_add_apns_p8')
49
50
  end
50
51
 
51
52
  protected
@@ -0,0 +1,15 @@
1
+ class Rpush320AddApnsP8 < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
2
+ def self.up
3
+ add_column :rpush_apps, :apn_key, :string, null: true
4
+ add_column :rpush_apps, :apn_key_id, :string, null: true
5
+ add_column :rpush_apps, :team_id, :string, null: true
6
+ add_column :rpush_apps, :bundle_id, :string, null: true
7
+ end
8
+
9
+ def self.down
10
+ remove_column :rpush_apps, :apn_key
11
+ remove_column :rpush_apps, :apn_key_id
12
+ remove_column :rpush_apps, :team_id
13
+ remove_column :rpush_apps, :bundle_id
14
+ end
15
+ end
data/lib/rpush.rb CHANGED
@@ -2,6 +2,7 @@ require 'logger'
2
2
  require 'multi_json'
3
3
  require 'active_support/all'
4
4
  require 'net-http2'
5
+ require 'jwt'
5
6
 
6
7
  require 'rails'
7
8
 
@@ -12,6 +12,9 @@ require 'rpush/client/active_model/apns/notification'
12
12
  require 'rpush/client/active_model/apns2/app'
13
13
  require 'rpush/client/active_model/apns2/notification'
14
14
 
15
+ require 'rpush/client/active_model/apnsp8/app'
16
+ require 'rpush/client/active_model/apnsp8/notification'
17
+
15
18
  require 'rpush/client/active_model/adm/data_validator'
16
19
  require 'rpush/client/active_model/adm/app'
17
20
  require 'rpush/client/active_model/adm/notification'
@@ -0,0 +1,23 @@
1
+ module Rpush
2
+ module Client
3
+ module ActiveModel
4
+ module Apnsp8
5
+ module App
6
+ def self.included(base)
7
+ base.instance_eval do
8
+ validates :environment, presence: true, inclusion: { in: %w(development production sandbox) }
9
+ validates :apn_key, presence: true
10
+ validates :apn_key_id, presence: true
11
+ validates :team_id, presence: true
12
+ validates :bundle_id, presence: true
13
+ end
14
+ end
15
+
16
+ def service_name
17
+ 'apnsp8'
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ module Rpush
2
+ module Client
3
+ module ActiveModel
4
+ module Apnsp8
5
+ include Rpush::Client::ActiveModel::Apns
6
+ end
7
+ end
8
+ end
9
+ end
@@ -12,6 +12,9 @@ require 'rpush/client/active_record/apns/app'
12
12
  require 'rpush/client/active_record/apns2/notification'
13
13
  require 'rpush/client/active_record/apns2/app'
14
14
 
15
+ require 'rpush/client/active_record/apnsp8/notification'
16
+ require 'rpush/client/active_record/apnsp8/app'
17
+
15
18
  require 'rpush/client/active_record/gcm/notification'
16
19
  require 'rpush/client/active_record/gcm/app'
17
20
 
@@ -0,0 +1,11 @@
1
+ module Rpush
2
+ module Client
3
+ module ActiveRecord
4
+ module Apnsp8
5
+ class App < Rpush::Client::ActiveRecord::App
6
+ include Rpush::Client::ActiveModel::Apnsp8::App
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module Rpush
2
+ module Client
3
+ module ActiveRecord
4
+ module Apnsp8
5
+ class Notification < Rpush::Client::ActiveRecord::Apns::Notification
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -24,6 +24,9 @@ require 'rpush/client/redis/apns/feedback'
24
24
  require 'rpush/client/redis/apns2/app'
25
25
  require 'rpush/client/redis/apns2/notification'
26
26
 
27
+ require 'rpush/client/redis/apnsp8/app'
28
+ require 'rpush/client/redis/apnsp8/notification'
29
+
27
30
  require 'rpush/client/redis/gcm/app'
28
31
  require 'rpush/client/redis/gcm/notification'
29
32
 
@@ -0,0 +1,11 @@
1
+ module Rpush
2
+ module Client
3
+ module Redis
4
+ module Apnsp8
5
+ class App < Rpush::Client::Redis::App
6
+ include Rpush::Client::ActiveModel::Apnsp8::App
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Rpush
2
+ module Client
3
+ module Redis
4
+ module Apnsp8
5
+ class Notification < Rpush::Client::Redis::Notification
6
+ include Rpush::Client::ActiveModel::Apnsp8::Notification
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -14,7 +14,11 @@ module Rpush
14
14
  attribute :client_id, :string
15
15
  attribute :client_secret, :string
16
16
  attribute :api_key, :string
17
-
17
+ attribute :apn_key, :string
18
+ attribute :apn_key_id, :string
19
+ attribute :team_id, :string
20
+ attribute :bundle_id, :string
21
+
18
22
  index :name
19
23
 
20
24
  validates :name, presence: true
data/lib/rpush/daemon.rb CHANGED
@@ -25,6 +25,7 @@ require 'rpush/daemon/dispatcher/http'
25
25
  require 'rpush/daemon/dispatcher/tcp'
26
26
  require 'rpush/daemon/dispatcher/apns_tcp'
27
27
  require 'rpush/daemon/dispatcher/apns_http2'
28
+ require 'rpush/daemon/dispatcher/apnsp8_http2'
28
29
  require 'rpush/daemon/service_config_methods'
29
30
  require 'rpush/daemon/retry_header_parser'
30
31
  require 'rpush/daemon/ring_buffer'
@@ -44,6 +45,10 @@ require 'rpush/daemon/apns'
44
45
  require 'rpush/daemon/apns2/delivery'
45
46
  require 'rpush/daemon/apns2'
46
47
 
48
+ require 'rpush/daemon/apnsp8/delivery'
49
+ require 'rpush/daemon/apnsp8/token'
50
+ require 'rpush/daemon/apnsp8'
51
+
47
52
  require 'rpush/daemon/gcm/delivery'
48
53
  require 'rpush/daemon/gcm'
49
54
 
@@ -0,0 +1,10 @@
1
+ module Rpush
2
+ module Daemon
3
+ module Apnsp8
4
+ extend ServiceConfigMethods
5
+
6
+ batch_deliveries true
7
+ dispatcher :apnsp8_http2
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,166 @@
1
+ module Rpush
2
+ module Daemon
3
+ module Apnsp8
4
+ # https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html
5
+
6
+ HTTP2_HEADERS_KEY = 'headers'
7
+
8
+ class Delivery < Rpush::Daemon::Delivery
9
+ RETRYABLE_CODES = [ 429, 500, 503 ]
10
+
11
+ def initialize(app, http2_client, token_provider, batch)
12
+ @app = app
13
+ @client = http2_client
14
+ @batch = batch
15
+ @first_push = true
16
+ @token_provider = token_provider
17
+ end
18
+
19
+ def perform
20
+ @client.on(:error) { |err| mark_batch_retryable(Time.now + 10.seconds, err) }
21
+
22
+ @batch.each_notification do |notification|
23
+ prepare_async_post(notification)
24
+ end
25
+
26
+ # Send all preprocessed requests at once
27
+ @client.join
28
+ rescue Errno::ECONNREFUSED, SocketError, HTTP2::Error::StreamLimitExceeded => error
29
+ # TODO restart connection when StreamLimitExceeded
30
+ mark_batch_retryable(Time.now + 10.seconds, error)
31
+ raise
32
+ rescue StandardError => error
33
+ mark_batch_failed(error)
34
+ raise
35
+ ensure
36
+ @batch.all_processed
37
+ end
38
+
39
+ protected
40
+ ######################################################################
41
+
42
+ def prepare_async_post(notification)
43
+ response = {}
44
+
45
+ request = build_request(notification)
46
+ log_warn(request)
47
+ http_request = @client.prepare_request(:post, request[:path],
48
+ body: request[:body],
49
+ headers: request[:headers]
50
+ )
51
+
52
+ http_request.on(:headers) do |hdrs|
53
+ response[:code] = hdrs[':status'].to_i
54
+ end
55
+
56
+ http_request.on(:body_chunk) do |body_chunk|
57
+ next unless body_chunk.present?
58
+
59
+ response[:failure_reason] = JSON.parse(body_chunk)['reason']
60
+ end
61
+
62
+ http_request.on(:close) { handle_response(notification, response) }
63
+
64
+ if @first_push
65
+ @first_push = false
66
+ @client.call_async(http_request)
67
+ else
68
+ delayed_push_async(http_request)
69
+ end
70
+ end
71
+
72
+ def delayed_push_async(http_request)
73
+ until streams_available? do
74
+ sleep 0.001
75
+ end
76
+ @client.call_async(http_request)
77
+ end
78
+
79
+ def streams_available?
80
+ remote_max_concurrent_streams - @client.stream_count > 0
81
+ end
82
+
83
+ def remote_max_concurrent_streams
84
+ # 0x7fffffff is the default value from http-2 gem (2^31)
85
+ if @client.remote_settings[:settings_max_concurrent_streams] == 0x7fffffff
86
+ 0
87
+ else
88
+ @client.remote_settings[:settings_max_concurrent_streams]
89
+ end
90
+ end
91
+
92
+ def handle_response(notification, response)
93
+ code = response[:code]
94
+ case code
95
+ when 200
96
+ ok(notification)
97
+ when *RETRYABLE_CODES
98
+ service_unavailable(notification, response)
99
+ else
100
+ reflect(:notification_id_failed,
101
+ @app,
102
+ notification.id, code,
103
+ response[:failure_reason])
104
+ @batch.mark_failed(notification, response[:code], response[:failure_reason])
105
+ failed_message_to_log(notification, response)
106
+ end
107
+ end
108
+
109
+ def ok(notification)
110
+ log_info("#{notification.id} sent to #{notification.device_token}")
111
+ @batch.mark_delivered(notification)
112
+ end
113
+
114
+ def service_unavailable(notification, response)
115
+ @batch.mark_retryable(notification, Time.now + 10.seconds)
116
+ # Logs should go last as soon as we need to initialize
117
+ # retry time to display it in log
118
+ failed_message_to_log(notification, response)
119
+ retry_message_to_log(notification)
120
+ end
121
+
122
+ def build_request(notification)
123
+ {
124
+ path: "/3/device/#{notification.device_token}",
125
+ headers: prepare_headers(notification),
126
+ body: prepare_body(notification)
127
+ }
128
+ end
129
+
130
+ def prepare_body(notification)
131
+ hash = notification.as_json.except(HTTP2_HEADERS_KEY)
132
+ JSON.dump(hash).force_encoding(Encoding::BINARY)
133
+ end
134
+
135
+ def prepare_headers(notification)
136
+ jwt_token = @token_provider.token
137
+
138
+ headers = {}
139
+
140
+ headers['content-type'] = 'application/json'
141
+ headers['apns-expiration'] = '0'
142
+ headers['apns-priority'] = '10'
143
+ headers['apns-topic'] = @app.bundle_id
144
+ headers['authorization'] = "bearer #{jwt_token}"
145
+
146
+ headers.merge notification_data(notification)[HTTP2_HEADERS_KEY] || {}
147
+ end
148
+
149
+ def notification_data(notification)
150
+ notification.data || {}
151
+ end
152
+
153
+ def retry_message_to_log(notification)
154
+ log_warn("Notification #{notification.id} will be retried after "\
155
+ "#{notification.deliver_after.strftime('%Y-%m-%d %H:%M:%S')} "\
156
+ "(retry #{notification.retries}).")
157
+ end
158
+
159
+ def failed_message_to_log(notification, response)
160
+ log_error("Notification #{notification.id} failed, "\
161
+ "#{response[:code]}/#{response[:failure_reason]}")
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,33 @@
1
+ module Rpush
2
+ module Daemon
3
+ module Apnsp8
4
+ TOKEN_TTL = 30 * 60
5
+ class Token
6
+
7
+ def initialize(app)
8
+ @app = app
9
+ end
10
+
11
+ def token
12
+ if @cached_token && !expired_token?
13
+ @cached_token
14
+ else
15
+ new_token
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def new_token
22
+ @cached_token_at = Time.now
23
+ ec_key = OpenSSL::PKey::EC.new(@app.apn_key)
24
+ @cached_token = JWT.encode({iss: @app.team_id, iat: Time.now.to_i}, ec_key, 'ES256', {alg: 'ES256', kid: @app.apn_key_id})
25
+ end
26
+
27
+ def expired_token?
28
+ Time.now - @cached_token_at >= TOKEN_TTL
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ module Rpush
2
+ module Daemon
3
+ module Dispatcher
4
+ class Apnsp8Http2
5
+
6
+ URLS = {
7
+ production: 'https://api.push.apple.com',
8
+ development: 'https://api.development.push.apple.com'
9
+ }
10
+
11
+ DEFAULT_TIMEOUT = 60
12
+
13
+ def initialize(app, delivery_class, _options = {})
14
+ @app = app
15
+ @delivery_class = delivery_class
16
+
17
+ url = URLS[app.environment.to_sym]
18
+ @client = NetHttp2::Client.new(url, connect_timeout: DEFAULT_TIMEOUT)
19
+ @token_provider = Rpush::Daemon::Apnsp8::Token.new(@app)
20
+ end
21
+
22
+ def dispatch(payload)
23
+
24
+ @delivery_class.new(@app, @client, @token_provider, payload.batch).perform
25
+ end
26
+
27
+ def cleanup
28
+ @client.close
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -5,7 +5,8 @@ module Rpush
5
5
  http: Rpush::Daemon::Dispatcher::Http,
6
6
  tcp: Rpush::Daemon::Dispatcher::Tcp,
7
7
  apns_tcp: Rpush::Daemon::Dispatcher::ApnsTcp,
8
- apns_http2: Rpush::Daemon::Dispatcher::ApnsHttp2
8
+ apns_http2: Rpush::Daemon::Dispatcher::ApnsHttp2,
9
+ apnsp8_http2: Rpush::Daemon::Dispatcher::Apnsp8Http2
9
10
  }
10
11
 
11
12
  def batch_deliveries(value = nil)
data/lib/rpush/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Rpush
2
2
  module VERSION
3
3
  MAJOR = 3
4
- MINOR = 1
5
- TINY = 1
4
+ MINOR = 2
5
+ TINY = 0
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".").freeze
@@ -35,6 +35,7 @@ require 'generators/templates/rpush_3_0_0_updates'
35
35
  require 'generators/templates/rpush_3_0_1_updates'
36
36
  require 'generators/templates/rpush_3_1_0_add_pushy'
37
37
  require 'generators/templates/rpush_3_1_1_updates'
38
+ require 'generators/templates/rpush_3_2_0_add_apns_p8'
38
39
 
39
40
  migrations = [
40
41
  AddRpush,
@@ -45,7 +46,8 @@ migrations = [
45
46
  Rpush300Updates,
46
47
  Rpush301Updates,
47
48
  Rpush310AddPushy,
48
- Rpush311Updates
49
+ Rpush311Updates,
50
+ Rpush320AddApnsP8
49
51
  ]
50
52
 
51
53
  unless ENV['TRAVIS']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rpush
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Leitch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-16 00:00:00.000000000 Z
11
+ date: 2018-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: jwt
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.5.6
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.5.6
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: activesupport
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -372,6 +386,7 @@ files:
372
386
  - lib/generators/templates/rpush_3_0_1_updates.rb
373
387
  - lib/generators/templates/rpush_3_1_0_add_pushy.rb
374
388
  - lib/generators/templates/rpush_3_1_1_updates.rb
389
+ - lib/generators/templates/rpush_3_2_0_add_apns_p8.rb
375
390
  - lib/rpush.rb
376
391
  - lib/rpush/apns_feedback.rb
377
392
  - lib/rpush/cli.rb
@@ -385,6 +400,8 @@ files:
385
400
  - lib/rpush/client/active_model/apns/notification.rb
386
401
  - lib/rpush/client/active_model/apns2/app.rb
387
402
  - lib/rpush/client/active_model/apns2/notification.rb
403
+ - lib/rpush/client/active_model/apnsp8/app.rb
404
+ - lib/rpush/client/active_model/apnsp8/notification.rb
388
405
  - lib/rpush/client/active_model/gcm/app.rb
389
406
  - lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb
390
407
  - lib/rpush/client/active_model/gcm/notification.rb
@@ -406,6 +423,8 @@ files:
406
423
  - lib/rpush/client/active_record/apns/notification.rb
407
424
  - lib/rpush/client/active_record/apns2/app.rb
408
425
  - lib/rpush/client/active_record/apns2/notification.rb
426
+ - lib/rpush/client/active_record/apnsp8/app.rb
427
+ - lib/rpush/client/active_record/apnsp8/notification.rb
409
428
  - lib/rpush/client/active_record/app.rb
410
429
  - lib/rpush/client/active_record/gcm/app.rb
411
430
  - lib/rpush/client/active_record/gcm/notification.rb
@@ -426,6 +445,8 @@ files:
426
445
  - lib/rpush/client/redis/apns/notification.rb
427
446
  - lib/rpush/client/redis/apns2/app.rb
428
447
  - lib/rpush/client/redis/apns2/notification.rb
448
+ - lib/rpush/client/redis/apnsp8/app.rb
449
+ - lib/rpush/client/redis/apnsp8/notification.rb
429
450
  - lib/rpush/client/redis/app.rb
430
451
  - lib/rpush/client/redis/gcm/app.rb
431
452
  - lib/rpush/client/redis/gcm/notification.rb
@@ -447,6 +468,9 @@ files:
447
468
  - lib/rpush/daemon/apns/feedback_receiver.rb
448
469
  - lib/rpush/daemon/apns2.rb
449
470
  - lib/rpush/daemon/apns2/delivery.rb
471
+ - lib/rpush/daemon/apnsp8.rb
472
+ - lib/rpush/daemon/apnsp8/delivery.rb
473
+ - lib/rpush/daemon/apnsp8/token.rb
450
474
  - lib/rpush/daemon/app_runner.rb
451
475
  - lib/rpush/daemon/batch.rb
452
476
  - lib/rpush/daemon/constants.rb
@@ -454,6 +478,7 @@ files:
454
478
  - lib/rpush/daemon/delivery_error.rb
455
479
  - lib/rpush/daemon/dispatcher/apns_http2.rb
456
480
  - lib/rpush/daemon/dispatcher/apns_tcp.rb
481
+ - lib/rpush/daemon/dispatcher/apnsp8_http2.rb
457
482
  - lib/rpush/daemon/dispatcher/http.rb
458
483
  - lib/rpush/daemon/dispatcher/tcp.rb
459
484
  - lib/rpush/daemon/dispatcher_loop.rb