rapns 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|