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.
@@ -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, :notification_id
3
+ attr_reader :code, :description
4
4
 
5
- def initialize(code, description, notification_id)
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
- delivery_error = nil
72
+ error = nil
75
73
 
76
- if error = @connection.read(ERROR_TUPLE_BYTES)
77
- cmd, status, notification_id = error.unpack("ccN")
74
+ if tuple = @connection.read(ERROR_TUPLE_BYTES)
75
+ cmd, code, notification_id = tuple.unpack("ccN")
78
76
 
79
- if cmd == ERROR_CMD && status != OK_STATUS
80
- description = APN_ERRORS[status] || "Unknown error. Possible rapns bug?"
81
- delivery_error = Rapns::DeliveryError.new(status, description, notification_id)
82
- end
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 delivery_error if delivery_error
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
@@ -1,3 +1,3 @@
1
1
  module Rapns
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
@@ -1,11 +1,13 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Rapns::DeliveryError do
4
- before do
5
- @error = Rapns::DeliveryError.new(4, "Missing payload", 12)
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 "should give an informative message" do
9
- @error.message.should == "Unable to deliver notification 12, received APN error 4 (Missing payload)"
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::Daemon.logger.should_receive(:error).with(@error)
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
- begin
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
- begin
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.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-11 00:00:00.000000000 Z
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