rapns 1.0.0 → 1.0.1

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