lead_zeppelin 0.1.3 → 0.1.4

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/README.md CHANGED
@@ -28,10 +28,14 @@ Require the gem, set threads to throw exceptions (optional, but recommended for
28
28
  Instantiate a new client and configure it by adding the block of code to handle error responses, and . Provide client.on\_error _before adding applications_.
29
29
 
30
30
  client = LeadZeppelin::APNS::Client.new do |c|
31
- c.on_error do |error_response|
31
+ c.on_notification_error do |error_response|
32
32
  puts "Apple sent back an error response: #{error_response.inspect}"
33
33
  end
34
34
 
35
+ c.on_certificate_error do |app|
36
+ puts "Certificate error failed for #{app}"
37
+ end
38
+
35
39
  # You can provide .p12 files too! p12: File.read('./yourapp.p12')
36
40
  c.add_application :your_app_identifier, pem: File.read('./yourapp.pem')
37
41
  end
@@ -10,4 +10,18 @@ require_relative './apns/client'
10
10
  require_relative './apns/gateway'
11
11
  require_relative './apns/logger'
12
12
  require_relative './apns/notification'
13
- require_relative './apns/error'
13
+ require_relative './apns/error_response'
14
+
15
+ module LeadZeppelin
16
+ module APNS
17
+ def self.client=(client)
18
+ Mutex.new.synchronize do
19
+ @client = client
20
+ end
21
+
22
+ def self.client
23
+ @client
24
+ end
25
+ end
26
+ end
27
+ end
@@ -4,10 +4,10 @@ module LeadZeppelin
4
4
  CONNECTION_POOL_SIZE = 5
5
5
  CONNECTION_POOL_TIMEOUT = 5
6
6
 
7
- attr_reader :name
7
+ attr_reader :identifier
8
8
 
9
- def initialize(name, opts={})
10
- @name = name
9
+ def initialize(identifier, opts={})
10
+ @identifier = identifier
11
11
  @opts = opts
12
12
 
13
13
  @ssl_context = OpenSSL::SSL::SSLContext.new
@@ -28,8 +28,24 @@ module LeadZeppelin
28
28
  cp_args = {size: (@opts[:connection_pool_size] || CONNECTION_POOL_SIZE),
29
29
  timeout: (@opts[:connection_pool_timeout] || CONNECTION_POOL_TIMEOUT)}
30
30
 
31
- @gateway_connection_pool = ConnectionPool.new(cp_args) do
32
- Gateway.new @ssl_context, (@opts[:gateway_opts] || {}).merge(error_block: @opts[:error_block], application_name: @name)
31
+ begin
32
+ @gateway_connection_pool = ConnectionPool.new(cp_args) do
33
+ Gateway.new @ssl_context, (@opts[:gateway_opts] || {}).merge(notification_error_block: @opts[:notification_error_block],
34
+ certificate_error_block: @opts[:certificate_error_block],
35
+ application_identifier: @identifier)
36
+ end
37
+
38
+ rescue OpenSSL::SSL::SSLError => e
39
+ if e.message =~ /alert certificate unknown/
40
+ Logger.warn "bad certificate for #{@identifier}, failed to connect"
41
+
42
+ if @opts[:certificate_error_block].nil?
43
+ Logger.warn "removing application #{@identifier} from the client due to bad certificate"
44
+ APNS.client.remove_application @identifier
45
+ else
46
+ @opts[:certificate_error_block].call @identifier
47
+ end
48
+ end
33
49
  end
34
50
  end
35
51
 
@@ -16,12 +16,18 @@ module LeadZeppelin
16
16
  # FIXME
17
17
  @thread_count = Queue.new
18
18
  (opts[:client_threads] || CLIENT_THREADS).times {|t| @thread_count << t}
19
+
20
+ APNS.client = self
19
21
  end
20
22
 
21
23
  attr_accessor :applications
22
24
 
23
- def on_error(&block)
24
- @error_block = block
25
+ def on_notification_error(&block)
26
+ @notification_error_block = block
27
+ end
28
+
29
+ def on_certificate_error(&block)
30
+ @certificate_error_block = block
25
31
  end
26
32
 
27
33
  def poll(frequency=DEFAULT_POLL_FREQUENCY, opts={}, &block)
@@ -47,9 +53,17 @@ module LeadZeppelin
47
53
  def add_application(name, opts={})
48
54
  Logger.info "adding application \"#{name}\""
49
55
  Logger.thread 'a'
56
+
57
+ begin
58
+ application = Application.new name, opts.merge(notification_error_block: @notification_error_block,
59
+ certificate_error_block: @certificate_error_block)
60
+ rescue OpenSSL::X509::CertificateError => e
61
+ Logger.error "received a bad certificate for #{name}, not adding application"
62
+ end
63
+
50
64
  @semaphore.synchronize do
51
65
  @applications ||= {}
52
- @applications[name] = Application.new name, opts.merge(error_block: @error_block)
66
+ @applications[name] = application
53
67
  end
54
68
  end
55
69
 
@@ -23,14 +23,13 @@ module LeadZeppelin
23
23
  ssl_socket = OpenSSL::SSL::SSLSocket.new socket, @ssl_context
24
24
 
25
25
  ssl_socket.sync_close = true # when ssl_socket is closed, make sure the regular socket closes too.
26
+
26
27
  ssl_socket.connect
27
28
 
28
29
  # FIXME TODO CHECK FOR EOFError HERE instead of in process_error
29
30
 
30
- @semaphore.synchronize do
31
- @socket = socket
32
- @ssl_socket = ssl_socket
33
- end
31
+ @socket = socket
32
+ @ssl_socket = ssl_socket
34
33
  end
35
34
 
36
35
  Logger.debug "gateway connection established"
@@ -64,8 +63,8 @@ module LeadZeppelin
64
63
 
65
64
  reconnect
66
65
 
67
- if @opts[:error_block].nil? || !@opts[:error_block].respond_to?(:call)
68
- Logger.error "You have not implemented an on_error block. This could lead to your account being banned from APNS. See the APNS docs"
66
+ if @opts[:error_block].nil? || !@opts[:notification_error_block].respond_to?(:call)
67
+ Logger.warn "You have not implemented an on_notification_error block. This could lead to your account being banned from APNS. See the APNS docs"
69
68
  else
70
69
  @opts[:error_block].call(error)
71
70
  end
@@ -73,7 +72,9 @@ module LeadZeppelin
73
72
  rescue EOFError
74
73
  # FIXME put in a certificate error pre-check and perhaps an error block for handling this.
75
74
  # A better solution is the remove the application altogether from the client..
76
- Logger.error "Invalid certificate for #{@opts[:application_name]}, reconnecting for now.."
75
+ # Sometimes this just means that the socket has disconnected. Apparently Apple does that too.
76
+ #
77
+ Logger.info "socket has closed for #{@opts[:application_identifier]}, reconnecting"
77
78
  reconnect
78
79
  rescue IO::WaitReadable
79
80
  # No data to read, continue
@@ -1,3 +1,3 @@
1
1
  module LeadZeppelin
2
- VERSION = '0.1.3'
2
+ VERSION = '0.1.4'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lead_zeppelin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
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: 2012-06-08 00:00:00.000000000 Z
12
+ date: 2012-06-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
@@ -76,7 +76,6 @@ files:
76
76
  - lib/lead_zeppelin/apns.rb
77
77
  - lib/lead_zeppelin/apns/application.rb
78
78
  - lib/lead_zeppelin/apns/client.rb
79
- - lib/lead_zeppelin/apns/error.rb
80
79
  - lib/lead_zeppelin/apns/gateway.rb
81
80
  - lib/lead_zeppelin/apns/logger.rb
82
81
  - lib/lead_zeppelin/apns/notification.rb
@@ -1,26 +0,0 @@
1
- module LeadZeppelin
2
- module APNS
3
- class ErrorResponse
4
- CODES = {
5
- 0 => 'No errors encountered',
6
- 1 => 'Processing error',
7
- 2 => 'Missing device token',
8
- 3 => 'Missing topic',
9
- 4 => 'Missing payload',
10
- 5 => 'Invalid token size',
11
- 6 => 'Invalid topic size',
12
- 7 => 'Invalid payload size',
13
- 8 => 'Invalid token',
14
- 255 => 'None (unknown)'
15
- }
16
-
17
- attr_reader :code, :identifier, :message, :notification
18
-
19
- def initialize(packet, notification=nil)
20
- command, @code, @identifier = packet.unpack 'ccA4'
21
- @message = CODES[@code]
22
- @notification = notification
23
- end
24
- end
25
- end
26
- end