Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cached SSLContext for APNS #23

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
129 changes: 64 additions & 65 deletions lib/pushmeup/apns/core.rb
Original file line number Diff line number Diff line change
@@ -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