rapns 1.0.0 → 1.0.1
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.
- data/lib/rapns/daemon.rb +1 -0
- data/lib/rapns/daemon/delivery_error.rb +4 -4
- data/lib/rapns/daemon/delivery_handler.rb +9 -11
- data/lib/rapns/daemon/disconnection_error.rb +14 -0
- data/lib/rapns/version.rb +1 -1
- data/spec/rapns/daemon/delivery_error_spec.rb +6 -4
- data/spec/rapns/daemon/delivery_handler_spec.rb +27 -46
- metadata +3 -2
data/lib/rapns/daemon.rb
CHANGED
@@ -6,6 +6,7 @@ require 'rapns/daemon/interruptible_sleep'
|
|
6
6
|
require 'rapns/daemon/configuration'
|
7
7
|
require 'rapns/daemon/certificate'
|
8
8
|
require 'rapns/daemon/delivery_error'
|
9
|
+
require 'rapns/daemon/disconnection_error'
|
9
10
|
require 'rapns/daemon/pool'
|
10
11
|
require 'rapns/daemon/connection'
|
11
12
|
require 'rapns/daemon/delivery_queue'
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module Rapns
|
2
2
|
class DeliveryError < StandardError
|
3
|
-
attr_reader :code, :description
|
3
|
+
attr_reader :code, :description
|
4
4
|
|
5
|
-
def initialize(code,
|
5
|
+
def initialize(code, notification_id, description)
|
6
6
|
@code = code
|
7
|
-
@description = description
|
8
7
|
@notification_id = notification_id
|
8
|
+
@description = description
|
9
9
|
end
|
10
10
|
|
11
11
|
def message
|
12
|
-
"Unable to deliver notification #{notification_id}, received APN error #{code} (#{description})"
|
12
|
+
"Unable to deliver notification #{@notification_id}, received APN error #{@code} (#{@description})"
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -2,8 +2,6 @@ module Rapns
|
|
2
2
|
module Daemon
|
3
3
|
class DeliveryHandler
|
4
4
|
STOP = 0x666
|
5
|
-
ERROR_CMD = 8
|
6
|
-
OK_STATUS = 0
|
7
5
|
SELECT_TIMEOUT = 0.5
|
8
6
|
ERROR_TUPLE_BYTES = 6
|
9
7
|
APN_ERRORS = {
|
@@ -53,7 +51,7 @@ module Rapns
|
|
53
51
|
notification.save!(:validate => false)
|
54
52
|
|
55
53
|
Rapns::Daemon.logger.info("Notification #{notification.id} delivered to #{notification.device_token}")
|
56
|
-
rescue Rapns::DeliveryError => error
|
54
|
+
rescue Rapns::DeliveryError, Rapns::DisconnectionError => error
|
57
55
|
handle_delivery_error(notification, error)
|
58
56
|
raise
|
59
57
|
end
|
@@ -71,22 +69,22 @@ module Rapns
|
|
71
69
|
|
72
70
|
def check_for_error
|
73
71
|
if @connection.select(SELECT_TIMEOUT)
|
74
|
-
|
72
|
+
error = nil
|
75
73
|
|
76
|
-
if
|
77
|
-
cmd,
|
74
|
+
if tuple = @connection.read(ERROR_TUPLE_BYTES)
|
75
|
+
cmd, code, notification_id = tuple.unpack("ccN")
|
78
76
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
77
|
+
description = APN_ERRORS[code.to_i] || "Unknown error. Possible rapns bug?"
|
78
|
+
error = Rapns::DeliveryError.new(code, notification_id, description)
|
79
|
+
else
|
80
|
+
error = Rapns::DisconnectionError.new
|
83
81
|
end
|
84
82
|
|
85
83
|
begin
|
86
84
|
Rapns::Daemon.logger.error("[#{@name}] Error received, reconnecting...")
|
87
85
|
@connection.reconnect
|
88
86
|
ensure
|
89
|
-
raise
|
87
|
+
raise error if error
|
90
88
|
end
|
91
89
|
end
|
92
90
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Rapns
|
2
|
+
class DisconnectionError < StandardError
|
3
|
+
attr_reader :code, :description
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@code = nil
|
7
|
+
@description = "APNs disconnected without returning an error."
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
"The APNs disconnected without returning an error. This may indicate you are using an invalid certificate for the host."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/rapns/version.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Rapns::DeliveryError do
|
4
|
-
|
5
|
-
|
4
|
+
let(:error) { Rapns::DeliveryError.new(4, 12, "Missing payload") }
|
5
|
+
|
6
|
+
it "returns an informative message" do
|
7
|
+
error.message.should == "Unable to deliver notification 12, received APN error 4 (Missing payload)"
|
6
8
|
end
|
7
9
|
|
8
|
-
it "
|
9
|
-
|
10
|
+
it "returns the error code" do
|
11
|
+
error.code.should == 4
|
10
12
|
end
|
11
13
|
end
|
@@ -90,8 +90,6 @@ describe Rapns::Daemon::DeliveryHandler do
|
|
90
90
|
describe "when delivery fails" do
|
91
91
|
before do
|
92
92
|
@connection.stub(:select => true, :read => [8, 4, 69].pack("ccN"), :reconnect => nil)
|
93
|
-
@error = Rapns::DeliveryError.new(4, "Missing payload", 69)
|
94
|
-
Rapns::DeliveryError.stub(:new => @error)
|
95
93
|
end
|
96
94
|
|
97
95
|
it "should set the notification as not delivered" do
|
@@ -122,7 +120,9 @@ describe Rapns::Daemon::DeliveryHandler do
|
|
122
120
|
end
|
123
121
|
|
124
122
|
it "should log the delivery error" do
|
125
|
-
Rapns::
|
123
|
+
error = Rapns::DeliveryError.new(4, 12, "Missing payload")
|
124
|
+
Rapns::DeliveryError.stub(:new => error)
|
125
|
+
Rapns::Daemon.logger.should_receive(:error).with(error)
|
126
126
|
delivery_handler.send(:handle_next_notification)
|
127
127
|
end
|
128
128
|
|
@@ -136,16 +136,6 @@ describe Rapns::Daemon::DeliveryHandler do
|
|
136
136
|
delivery_handler.send(:handle_next_notification)
|
137
137
|
end
|
138
138
|
|
139
|
-
it "should not raise a DeliveryError if the packet cmd value is not 8" do
|
140
|
-
@connection.stub(:read).and_return([6, 4, 12].pack("ccN"))
|
141
|
-
expect { delivery_handler.send(:handle_next_notification) }.should_not raise_error(Rapns::DeliveryError)
|
142
|
-
end
|
143
|
-
|
144
|
-
it "should not raise a DeliveryError if the status code is 0 (no error)" do
|
145
|
-
@connection.stub(:read).and_return([8, 0, 12].pack("ccN"))
|
146
|
-
expect { delivery_handler.send(:handle_next_notification) }.should_not raise_error(Rapns::DeliveryError)
|
147
|
-
end
|
148
|
-
|
149
139
|
it "should read 6 bytes from the socket" do
|
150
140
|
@connection.should_receive(:read).with(6).and_return(nil)
|
151
141
|
delivery_handler.send(:handle_next_notification)
|
@@ -157,46 +147,37 @@ describe Rapns::Daemon::DeliveryHandler do
|
|
157
147
|
delivery_handler.send(:handle_next_notification)
|
158
148
|
end
|
159
149
|
|
160
|
-
it "should not raise a DeliveryError if the socket read returns nothing" do
|
161
|
-
@connection.stub(:read).with(6).and_return(nil)
|
162
|
-
expect { delivery_handler.send(:handle_next_notification) }.should_not raise_error(Rapns::DeliveryError)
|
163
|
-
end
|
164
|
-
|
165
150
|
it "should reconnect the socket" do
|
166
151
|
@connection.should_receive(:reconnect)
|
167
|
-
|
168
|
-
delivery_handler.send(:handle_next_notification)
|
169
|
-
rescue Rapns::DeliveryError
|
170
|
-
end
|
152
|
+
delivery_handler.send(:handle_next_notification)
|
171
153
|
end
|
172
154
|
|
173
155
|
it "should log that the connection is being reconnected" do
|
174
156
|
Rapns::Daemon.logger.should_receive(:error).with("[DeliveryHandler 0] Error received, reconnecting...")
|
175
|
-
|
157
|
+
delivery_handler.send(:handle_next_notification)
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when the APNs disconnects without returning an error" do
|
161
|
+
before do
|
162
|
+
@connection.stub(:read => nil)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should raise a DisconnectError error if the connection is closed without an error being returned' do
|
166
|
+
error = Rapns::DisconnectionError.new
|
167
|
+
Rapns::DisconnectionError.should_receive(:new).and_return(error)
|
168
|
+
Rapns::Daemon.logger.should_receive(:error).with(error)
|
169
|
+
delivery_handler.send(:handle_next_notification)
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'does not set the error code on the notification' do
|
173
|
+
@notification.should_receive(:error_code=).with(nil)
|
174
|
+
delivery_handler.send(:handle_next_notification)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'sets the error descriptipon on the notification' do
|
178
|
+
@notification.should_receive(:error_description=).with("APNs disconnected without returning an error.")
|
176
179
|
delivery_handler.send(:handle_next_notification)
|
177
|
-
rescue Rapns::DeliveryError
|
178
180
|
end
|
179
181
|
end
|
180
182
|
end
|
181
|
-
end
|
182
|
-
|
183
|
-
# describe Rapns::Daemon::Connection, "when receiving an error packet" do
|
184
|
-
# before do
|
185
|
-
# @notification = Rapns::Notification.create!(:device_token => "a" * 64)
|
186
|
-
# @notification.stub(:save!)
|
187
|
-
# @connection = Rapns::Daemon::Connection.new('Connection 0', 'gateway.push.apple.com', 2195)
|
188
|
-
# @ssl_socket = mock("SSLSocket", :write => nil, :flush => nil, :close => nil, :read => [8, 4, @notification.id].pack("ccN"))
|
189
|
-
# @connection.stub(:setup_ssl_context)
|
190
|
-
# @connection.stub(:connect_socket).and_return([@tcp_socket, @ssl_socket])
|
191
|
-
# IO.stub(:select).and_return([@ssl_socket, [], []])
|
192
|
-
# logger = mock("Logger", :error => nil, :warn => nil)
|
193
|
-
# Rapns::Daemon.stub(:logger).and_return(logger)
|
194
|
-
# @connection.connect
|
195
|
-
# end
|
196
|
-
#
|
197
|
-
# it "should raise a DeliveryError when an error is received" do
|
198
|
-
# expect { @connection.write("msg with an error") }.should raise_error(Rapns::DeliveryError)
|
199
|
-
# end
|
200
|
-
#
|
201
|
-
|
202
|
-
# end
|
183
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rapns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-12 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Easy to use library for Apple's Push Notification Service with Rails
|
15
15
|
3
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- lib/rapns/daemon/delivery_handler.rb
|
35
35
|
- lib/rapns/daemon/delivery_handler_pool.rb
|
36
36
|
- lib/rapns/daemon/delivery_queue.rb
|
37
|
+
- lib/rapns/daemon/disconnection_error.rb
|
37
38
|
- lib/rapns/daemon/feedback_receiver.rb
|
38
39
|
- lib/rapns/daemon/feeder.rb
|
39
40
|
- lib/rapns/daemon/interruptible_sleep.rb
|