diff --git a/lib/pushmeup/apns/core.rb b/lib/pushmeup/apns/core.rb index 5d74778..99c08d6 100644 --- a/lib/pushmeup/apns/core.rb +++ b/lib/pushmeup/apns/core.rb @@ -1,85 +1,84 @@ require 'socket' require 'openssl' -require 'json' module APNS - @host = 'gateway.sandbox.push.apple.com' @port = 2195 - # 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 - - def self.send_notification(device_token, message) - n = APNS::Notification.new(device_token, message) - self.send_notifications([n]) - end - - def self.send_notifications(notifications) - sock, ssl = self.open_connection - - notifications.each do |n| - ssl.write(n.packaged_notification) - end - ssl.close - sock.close - end - - def self.feedback - sock, ssl = self.feedback_connection + # openssl pkcs12 -in mycert.p12 -out client-cert.pem -nodes -clcerts + def pem=(val) + @ssl_context = nil + @pem = val + end + + def pass=(val) + @ssl_context = nil + @pass = val + end + + def send_notification(device_token, message) + n = APNS::Notification.new(device_token, message) + send_notifications([n]) + end - apns_feedback = [] + def send_notifications(notifications) + open_connection do |ssl| + notifications.each do |n| + ssl.write(n.packaged_notification) + end + end + end - while line = ssl.read(38) # Read lines from the socket - line.strip! - f = line.unpack('N1n1H140') - apns_feedback << { :timestamp => Time.at(f[0]), :token => f[2] } + def feedback + feedback_connection do |ssl| + apns_feedback = [] + while line = ssl.read(38) # Read lines from the socket + line.strip! + f = line.unpack('N1n1H140') + apns_feedback << { :timestamp => Time.at(f[0]), :token => f[2] } + end + apns_feedback + end end - ssl.close - sock.close + protected + def open_connection(&block) + ssl_connection(&block) + end - return apns_feedback - end - - protected + def feedback_connection(&block) + fhost = host.gsub('gateway','feedback') + ssl_connection(fhost, 2196, &block) + end - def self.open_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) + def ssl_connection(host = nil, port = nil) + sock = TCPSocket.new(host || self.host, port || self.port) + ssl = OpenSSL::SSL::SSLSocket.new(sock, ssl_context) + ssl.connect - sock = TCPSocket.new(self.host, self.port) - ssl = OpenSSL::SSL::SSLSocket.new(sock,context) - ssl.connect + return sock, ssl unless block_given? + begin + yield ssl + ensure + ssl.close + sock.close + end + end - return sock, ssl - end - - 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 + def ssl_context + @ssl_context ||= begin + raise "The path to your pem file is not set. (APNS.pem = /path/to/cert.pem)" unless pem + raise "The path to your pem file does not exist!" unless File.exist?(pem) - return sock, ssl + pem_content = File.read(pem) + context = OpenSSL::SSL::SSLContext.new + context.cert = OpenSSL::X509::Certificate.new(pem_content) + context.key = OpenSSL::PKey::RSA.new(pem_content, pass) + context + end + end end - end