Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

Split into high-level API and low-level connection-oriented API #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/apns.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
require 'apns/core'
require 'apns/connection'
require 'apns/notification'
52 changes: 52 additions & 0 deletions lib/apns/connection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
module APNS
class Connection
attr_accessor :socket, :ssl

def initialize(opts)
self.socket = TCPSocket.new(opts[:host], opts[:port])

configure_ssl opts[:pem], opts[:pass]
end

def close
ssl.close
socket.close
end

private

def configure_ssl(pem, pass)
raise "The path to your pem file does not exist!" unless File.exist?(pem)

context = OpenSSL::SSL::SSLContext.new
context.cert = OpenSSL::X509::Certificate.new(File.read(pem))
context.key = OpenSSL::PKey::RSA.new(File.read(pem), pass)

self.ssl = OpenSSL::SSL::SSLSocket.new(socket, context)
ssl.connect
end

end

class NotificationConnection < Connection
def send_notifications(notifications)
notifications.each do |n|
ssl.write n.packaged_notification
end
end
end

class FeedbackConnection < Connection
def feedback
apns_feedback = []

while line = socket.gets # Read lines from the socket
line.strip!
f = line.unpack('N1n1H140')
apns_feedback << [Time.at(f[0]), f[2]]
end

apns_feedback
end
end
end
62 changes: 13 additions & 49 deletions lib/apns/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module APNS
# openssl pkcs12 -in mycert.p12 -out client-cert.pem -nodes -clcerts
@pem = nil # this should be the path of the pem file not the contentes
@pass = nil

class << self
attr_accessor :host, :pem, :port, :pass
end
Expand All @@ -19,66 +19,30 @@ def self.send_notification(device_token, message)
end

def self.send_notifications(notifications)
sock, ssl = self.open_connection

notifications.each do |n|
ssl.write(n.packaged_notification)
with_connection(NotificationConnection) do |conn|
conn.send_notifications(notifications)
end

ssl.close
sock.close
end

def self.feedback
sock, ssl = self.feedback_connection

apns_feedback = []

while line = sock.gets # Read lines from the socket
line.strip!
f = line.unpack('N1n1H140')
apns_feedback << [Time.at(f[0]), f[2]]
with_connection(FeedbackConnection) do |conn|
conn.feedback
end

ssl.close
sock.close

return apns_feedback
end

protected

def self.open_connection
def self.with_connection(type)
raise "The path to your pem file is not set. (APNS.pem = /path/to/cert.pem)" unless self.pem
raise "The path to your pem file does not exist!" unless File.exist?(self.pem)

context = OpenSSL::SSL::SSLContext.new
context.cert = OpenSSL::X509::Certificate.new(File.read(self.pem))
context.key = OpenSSL::PKey::RSA.new(File.read(self.pem), self.pass)

sock = TCPSocket.new(self.host, self.port)
ssl = OpenSSL::SSL::SSLSocket.new(sock,context)
ssl.connect

return sock, ssl
end
connection = type.new(:host => self.host, :port => self.port, :pem => self.pem, :pass => self.pass)
yield connection

def self.feedback_connection
raise "The path to your pem file is not set. (APNS.pem = /path/to/cert.pem)" unless self.pem
raise "The path to your pem file does not exist!" unless File.exist?(self.pem)

context = OpenSSL::SSL::SSLContext.new
context.cert = OpenSSL::X509::Certificate.new(File.read(self.pem))
context.key = OpenSSL::PKey::RSA.new(File.read(self.pem), self.pass)

fhost = self.host.gsub('gateway','feedback')
puts fhost

sock = TCPSocket.new(fhost, 2196)
ssl = OpenSSL::SSL::SSLSocket.new(sock,context)
ssl.connect
ensure
connection.close if connection
end

return sock, ssl
def self.feedback_host
self.host.gsub('gateway','feedback')
end

end