lead_zeppelin 0.1.3 → 0.1.4

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