rpush 8.0.0 → 9.0.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -6
  3. data/README.md +8 -65
  4. data/lib/generators/templates/rpush.rb +9 -16
  5. data/lib/rpush/client/active_model.rb +0 -4
  6. data/lib/rpush/client/active_record.rb +0 -3
  7. data/lib/rpush/client/redis.rb +0 -3
  8. data/lib/rpush/configuration.rb +2 -19
  9. data/lib/rpush/daemon/service_config_methods.rb +0 -2
  10. data/lib/rpush/daemon/store/active_record.rb +2 -14
  11. data/lib/rpush/daemon/store/interface.rb +2 -2
  12. data/lib/rpush/daemon/store/redis.rb +2 -11
  13. data/lib/rpush/daemon.rb +0 -10
  14. data/lib/rpush/reflection_collection.rb +1 -2
  15. data/lib/rpush/version.rb +1 -1
  16. data/lib/rpush.rb +0 -1
  17. data/spec/functional/cli_spec.rb +41 -15
  18. data/spec/functional/embed_spec.rb +57 -26
  19. data/spec/functional/retry_spec.rb +21 -4
  20. data/spec/functional/synchronization_spec.rb +1 -1
  21. data/spec/functional_spec_helper.rb +0 -6
  22. data/spec/spec_helper.rb +2 -0
  23. data/spec/unit/client/active_record/shared/app.rb +1 -1
  24. data/spec/unit/daemon/shared/store.rb +0 -42
  25. metadata +49 -55
  26. data/lib/rpush/apns_feedback.rb +0 -18
  27. data/lib/rpush/client/active_model/gcm/app.rb +0 -19
  28. data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +0 -14
  29. data/lib/rpush/client/active_model/gcm/notification.rb +0 -62
  30. data/lib/rpush/client/active_record/gcm/app.rb +0 -11
  31. data/lib/rpush/client/active_record/gcm/notification.rb +0 -11
  32. data/lib/rpush/client/redis/gcm/app.rb +0 -11
  33. data/lib/rpush/client/redis/gcm/notification.rb +0 -11
  34. data/lib/rpush/daemon/apns/delivery.rb +0 -43
  35. data/lib/rpush/daemon/apns/feedback_receiver.rb +0 -91
  36. data/lib/rpush/daemon/apns.rb +0 -17
  37. data/lib/rpush/daemon/dispatcher/apns_tcp.rb +0 -152
  38. data/lib/rpush/daemon/dispatcher/tcp.rb +0 -22
  39. data/lib/rpush/daemon/gcm/delivery.rb +0 -241
  40. data/lib/rpush/daemon/gcm.rb +0 -9
  41. data/lib/rpush/daemon/tcp_connection.rb +0 -190
  42. data/spec/functional/apns_spec.rb +0 -162
  43. data/spec/functional/gcm_priority_spec.rb +0 -40
  44. data/spec/functional/gcm_spec.rb +0 -46
  45. data/spec/functional/new_app_spec.rb +0 -44
  46. data/spec/unit/apns_feedback_spec.rb +0 -39
  47. data/spec/unit/client/active_record/gcm/app_spec.rb +0 -6
  48. data/spec/unit/client/active_record/gcm/notification_spec.rb +0 -14
  49. data/spec/unit/client/redis/gcm/app_spec.rb +0 -5
  50. data/spec/unit/client/redis/gcm/notification_spec.rb +0 -5
  51. data/spec/unit/client/shared/gcm/app.rb +0 -4
  52. data/spec/unit/client/shared/gcm/notification.rb +0 -77
  53. data/spec/unit/daemon/apns/delivery_spec.rb +0 -108
  54. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +0 -137
  55. data/spec/unit/daemon/dispatcher/tcp_spec.rb +0 -32
  56. data/spec/unit/daemon/gcm/delivery_spec.rb +0 -387
  57. data/spec/unit/daemon/tcp_connection_spec.rb +0 -293
@@ -1,293 +0,0 @@
1
- require "unit_spec_helper"
2
-
3
- describe Rpush::Daemon::TcpConnection do
4
- let(:rsa_key) { double }
5
- let(:certificate) { double }
6
- let(:password) { double }
7
- let(:x509_certificate) { OpenSSL::X509::Certificate.new(TEST_CERT) }
8
- let(:ssl_context) { double(:key= => nil, :cert= => nil, cert: x509_certificate) }
9
- let(:host) { 'gateway.push.apple.com' }
10
- let(:port) { '2195' }
11
- let(:tcp_socket) { double(setsockopt: nil, close: nil) }
12
- let(:ssl_socket) { double(:sync= => nil, connect: nil, close: nil, write: nil, flush: nil) }
13
- let(:logger) { double(info: nil, error: nil, warn: nil) }
14
- let(:app) { double(name: 'Connection 0', certificate: certificate, password: password) }
15
- let(:connection) { Rpush::Daemon::TcpConnection.new(app, host, port) }
16
-
17
- before do
18
- allow(x509_certificate).to receive(:not_after).and_return(Time.now + 1.year)
19
- allow(OpenSSL::SSL::SSLContext).to receive_messages(new: ssl_context)
20
- allow(OpenSSL::PKey::RSA).to receive_messages(new: rsa_key)
21
- allow(OpenSSL::X509::Certificate).to receive_messages(new: x509_certificate)
22
- allow(TCPSocket).to receive_messages(new: tcp_socket)
23
- allow(OpenSSL::SSL::SSLSocket).to receive_messages(new: ssl_socket)
24
- allow(Rpush).to receive_messages(logger: logger)
25
- allow(connection).to receive(:reflect)
26
- end
27
-
28
- it "reads the number of bytes from the SSL socket" do
29
- expect(ssl_socket).to receive(:read).with(123)
30
- connection.connect
31
- connection.read(123)
32
- end
33
-
34
- it "selects on the SSL socket until the given timeout" do
35
- expect(IO).to receive(:select).with([ssl_socket], nil, nil, 10)
36
- connection.connect
37
- connection.select(10)
38
- end
39
-
40
- describe "when setting up the SSL context" do
41
- it "sets the key on the context" do
42
- expect(OpenSSL::PKey::RSA).to receive(:new).with(certificate, password).and_return(rsa_key)
43
- expect(ssl_context).to receive(:key=).with(rsa_key)
44
- connection.connect
45
- end
46
-
47
- it "sets the cert on the context" do
48
- expect(OpenSSL::X509::Certificate).to receive(:new).with(certificate).and_return(x509_certificate)
49
- expect(ssl_context).to receive(:cert=).with(x509_certificate)
50
- connection.connect
51
- end
52
- end
53
-
54
- describe "when connecting the socket" do
55
- it "creates a TCP socket using the configured host and port" do
56
- expect(TCPSocket).to receive(:new).with(host, port).and_return(tcp_socket)
57
- connection.connect
58
- end
59
-
60
- it "creates a new SSL socket using the TCP socket and SSL context" do
61
- expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, ssl_context).and_return(ssl_socket)
62
- connection.connect
63
- end
64
-
65
- it "sets the sync option on the SSL socket" do
66
- expect(ssl_socket).to receive(:sync=).with(true)
67
- connection.connect
68
- end
69
-
70
- it "connects the SSL socket" do
71
- expect(ssl_socket).to receive(:connect)
72
- connection.connect
73
- end
74
-
75
- it "sets the socket option TCP_NODELAY" do
76
- expect(tcp_socket).to receive(:setsockopt).with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
77
- connection.connect
78
- end
79
-
80
- it "sets the socket option SO_KEEPALIVE" do
81
- expect(tcp_socket).to receive(:setsockopt).with(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
82
- connection.connect
83
- end
84
-
85
- describe 'certificate expiry' do
86
- it 'reflects if the certificate will expire soon' do
87
- cert = x509_certificate
88
- expect(connection).to receive(:reflect).with(:ssl_certificate_will_expire, app, cert.not_after)
89
- Timecop.freeze(cert.not_after - 3.days) { connection.connect }
90
- end
91
-
92
- it 'logs that the certificate will expire soon' do
93
- cert = x509_certificate
94
- expect(logger).to receive(:warn).with("[#{app.name}] Certificate will expire at #{cert.not_after.utc}.")
95
- Timecop.freeze(cert.not_after - 3.days) { connection.connect }
96
- end
97
-
98
- it 'does not reflect if the certificate will not expire soon' do
99
- cert = x509_certificate
100
- expect(connection).not_to receive(:reflect).with(:ssl_certificate_will_expire, app, kind_of(Time))
101
- Timecop.freeze(cert.not_after - 2.months) { connection.connect }
102
- end
103
-
104
- it 'logs that the certificate has expired' do
105
- cert = x509_certificate
106
- expect(logger).to receive(:error).with("[#{app.name}] Certificate expired at #{cert.not_after.utc}.")
107
- Timecop.freeze(cert.not_after + 1.day) { connection.connect rescue Rpush::CertificateExpiredError }
108
- end
109
-
110
- it 'raises an error if the certificate has expired' do
111
- cert = x509_certificate
112
- Timecop.freeze(cert.not_after + 1.day) do
113
- expect { connection.connect }.to raise_error(Rpush::CertificateExpiredError)
114
- end
115
- end
116
- end
117
-
118
- describe 'certificate revocation' do
119
- let(:cert_revoked_error) { OpenSSL::SSL::SSLError.new('certificate revoked') }
120
- before do
121
- allow(ssl_socket).to receive(:connect).and_raise(cert_revoked_error)
122
- end
123
-
124
- it 'reflects that the certificate has been revoked' do
125
- expect(connection).to receive(:reflect).with(:ssl_certificate_revoked, app, cert_revoked_error)
126
- expect { connection.connect }.to raise_error(Rpush::Daemon::TcpConnectionError, 'OpenSSL::SSL::SSLError, certificate revoked')
127
- end
128
-
129
- it 'logs that the certificate has been revoked' do
130
- expect(logger).to receive(:error).with('[Connection 0] Certificate has been revoked.')
131
- expect { connection.connect }.to raise_error(Rpush::Daemon::TcpConnectionError, 'OpenSSL::SSL::SSLError, certificate revoked')
132
- end
133
- end
134
- end
135
-
136
- describe "when shuting down the connection" do
137
- it "closes the TCP socket" do
138
- connection.connect
139
- expect(tcp_socket).to receive(:close)
140
- connection.close
141
- end
142
-
143
- it "does not attempt to close the TCP socket if it is not connected" do
144
- connection.connect
145
- expect(tcp_socket).not_to receive(:close)
146
- connection.instance_variable_set("@tcp_socket", nil)
147
- connection.close
148
- end
149
-
150
- it "closes the SSL socket" do
151
- connection.connect
152
- expect(ssl_socket).to receive(:close)
153
- connection.close
154
- end
155
-
156
- it "does not attempt to close the SSL socket if it is not connected" do
157
- connection.connect
158
- expect(ssl_socket).not_to receive(:close)
159
- connection.instance_variable_set("@ssl_socket", nil)
160
- connection.close
161
- end
162
-
163
- it "ignores IOError when the socket is already closed" do
164
- allow(tcp_socket).to receive(:close).and_raise(IOError)
165
- connection.connect
166
- connection.close
167
- end
168
- end
169
-
170
- shared_examples_for "when the write fails" do
171
- before do
172
- allow(connection).to receive(:sleep)
173
- connection.connect
174
- allow(ssl_socket).to receive(:write).and_raise(error)
175
- end
176
-
177
- it 'reflects the connection has been lost' do
178
- expect(connection).to receive(:reflect).with(:tcp_connection_lost, app, kind_of(error.class))
179
- expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
180
- end
181
-
182
- it "logs that the connection has been lost once only" do
183
- expect(logger).to receive(:error).with("[Connection 0] Lost connection to gateway.push.apple.com:2195 (#{error.class.name}, #{error.message}), reconnecting...").once
184
- expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
185
- end
186
-
187
- it "retries to make a connection 3 times" do
188
- expect(connection).to receive(:reconnect).exactly(3).times
189
- expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
190
- end
191
-
192
- it "raises a TcpConnectionError after 3 attempts at reconnecting" do
193
- expect do
194
- connection.write(nil)
195
- end.to raise_error(Rpush::Daemon::TcpConnectionError, "Connection 0 tried 3 times to reconnect but failed (#{error.class.name}, #{error.message}).")
196
- end
197
-
198
- it "sleeps 1 second before retrying the connection" do
199
- expect(connection).to receive(:sleep).with(1)
200
- expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
201
- end
202
- end
203
-
204
- describe "when write raises an Errno::EPIPE" do
205
- it_should_behave_like "when the write fails"
206
-
207
- def error
208
- Errno::EPIPE.new('an message')
209
- end
210
- end
211
-
212
- describe "when write raises an Errno::ETIMEDOUT" do
213
- it_should_behave_like "when the write fails"
214
-
215
- def error
216
- Errno::ETIMEDOUT.new('an message')
217
- end
218
- end
219
-
220
- describe "when write raises an OpenSSL::SSL::SSLError" do
221
- it_should_behave_like "when the write fails"
222
-
223
- def error
224
- OpenSSL::SSL::SSLError.new('an message')
225
- end
226
- end
227
-
228
- describe "when write raises an IOError" do
229
- it_should_behave_like "when the write fails"
230
-
231
- def error
232
- IOError.new('an message')
233
- end
234
- end
235
-
236
- describe "when reconnecting" do
237
- before { connection.connect }
238
-
239
- it 'closes the socket' do
240
- expect(connection).to receive(:close)
241
- connection.send(:reconnect)
242
- end
243
-
244
- it 'connects the socket' do
245
- expect(connection).to receive(:connect_socket)
246
- connection.send(:reconnect)
247
- end
248
- end
249
-
250
- describe "when sending a notification" do
251
- before { connection.connect }
252
-
253
- it "writes the data to the SSL socket" do
254
- expect(ssl_socket).to receive(:write).with("blah")
255
- connection.write("blah")
256
- end
257
-
258
- it "flushes the SSL socket" do
259
- expect(ssl_socket).to receive(:flush)
260
- connection.write("blah")
261
- end
262
- end
263
-
264
- describe 'idle period' do
265
- before { connection.connect }
266
-
267
- it 'reconnects if the connection has been idle for more than the defined period' do
268
- allow(Rpush::Daemon::TcpConnection).to receive_messages(idle_period: 60)
269
- allow(Time).to receive_messages(now: Time.now + 61)
270
- expect(connection).to receive(:reconnect)
271
- connection.write('blah')
272
- end
273
-
274
- it 'resets the last touch time' do
275
- now = Time.now
276
- allow(Time).to receive_messages(now: now)
277
- connection.write('blah')
278
- expect(connection.last_touch).to eq now
279
- end
280
-
281
- it 'does not reconnect if the connection has not been idle for more than the defined period' do
282
- expect(connection).not_to receive(:reconnect)
283
- connection.write('blah')
284
- end
285
-
286
- it 'logs the the connection is idle' do
287
- allow(Rpush::Daemon::TcpConnection).to receive_messages(idle_period: 60)
288
- allow(Time).to receive_messages(now: Time.now + 61)
289
- expect(Rpush.logger).to receive(:info).with('[Connection 0] Idle period exceeded, reconnecting...')
290
- connection.write('blah')
291
- end
292
- end
293
- end