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

Fix undefined method 'close' for nil:NilClass #79

Open
wants to merge 2 commits 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
10 changes: 10 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
jobs:
build:
working_directory: /app
docker:
- image: ruby:2.1.2
steps:
- checkout
- run: bundle install
- run: rspec
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby-1.9.3
2.1.2
62 changes: 31 additions & 31 deletions lib/pushmeup/apns/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,34 @@ 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

@persistent = false
@mutex = Mutex.new
@retries = 3 # TODO: check if we really need this

@sock = nil
@ssl = nil

class << self
attr_accessor :host, :pem, :port, :pass
end

def self.start_persistence
@persistent = true
end

def self.stop_persistence
@persistent = false

@ssl.close
@sock.close
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)
@mutex.synchronize do
self.with_connection do
Expand All @@ -46,8 +46,9 @@ def self.send_notifications(notifications)
end
end
end

def self.feedback
assert_pem_setup!
sock, ssl = self.feedback_connection

apns_feedback = []
Expand All @@ -63,30 +64,31 @@ def self.feedback

return apns_feedback
end

protected

def self.with_connection
assert_pem_setup!
attempts = 1
begin

begin
# If no @ssl is created or if @ssl is closed we need to start it
if @ssl.nil? || @sock.nil? || @ssl.closed? || @sock.closed?
@sock, @ssl = self.open_connection
end

yield

rescue StandardError, Errno::EPIPE
raise unless attempts < @retries
@ssl.close
@sock.close

@ssl.close unless @ssl.nil?
@sock.close unless @ssl.nil?

attempts += 1
retry
end

# Only force close if not persistent
unless @persistent
@ssl.close
Expand All @@ -95,11 +97,8 @@ def self.with_connection
@sock = nil
end
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)
Expand All @@ -110,22 +109,23 @@ def self.open_connection

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')

sock = TCPSocket.new(fhost, 2196)
ssl = OpenSSL::SSL::SSLSocket.new(sock, context)
ssl.connect

return sock, ssl
end


def self.assert_pem_setup!
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)
end
end
32 changes: 32 additions & 0 deletions spec/lib/apns/core_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require 'spec_helper'

describe APNS do
describe '.send_notifications' do
let(:cert) { 'spec/support/dummy.pem' }
let(:tcp_socket) { instance_double(TCPSocket).as_null_object }
let(:ssl_socket) { instance_double(OpenSSL::SSL::SSLSocket).as_null_object }

before do
allow(APNS).to receive(:pem).and_return cert
allow(TCPSocket).to receive(:new).with(APNS.host, APNS.port).and_return(tcp_socket)
allow(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, an_instance_of(OpenSSL::SSL::SSLContext))
.and_return(ssl_socket)
end

let(:notification) { APNS::Notification.new '123', 'hi' }

subject { described_class.send_notifications [notification] }

it { expect { subject }.not_to raise_error }

context 'when there is connection error' do
let(:error) { StandardError.new }

before do
allow(ssl_socket).to receive(:connect).and_raise error
end

it { expect { subject }.to raise_error error }
end
end
end
18 changes: 9 additions & 9 deletions spec/lib/pushmeup_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
describe Pushmeup do
describe "APNS" do
it "should have a APNS object" do
defined?(APNS).should_not be_false
defined?(APNS).should_not be false
end

it "should not forget the APNS default parameters" do
Expand Down Expand Up @@ -31,7 +31,7 @@

describe "GCM" do
it "should have a GCM object" do
defined?(GCM).should_not be_false
defined?(GCM).should_not be false
end

describe "Notifications" do
Expand All @@ -42,27 +42,27 @@

it "should allow only notifications with device_tokens as array" do
n = GCM::Notification.new("id", @options)
n.device_tokens.is_a?(Array).should be_true
n.device_tokens.is_a?(Array).should be true

n.device_tokens = ["a" "b", "c"]
n.device_tokens.is_a?(Array).should be_true
n.device_tokens.is_a?(Array).should be true

n.device_tokens = "a"
n.device_tokens.is_a?(Array).should be_true
n.device_tokens.is_a?(Array).should be true
end

it "should allow only notifications with data as hash with :data root" do
n = GCM::Notification.new("id", { :data => "data" })

n.data.is_a?(Hash).should be_true
n.data.is_a?(Hash).should be true
n.data.should == {:data => "data"}

n.data = {:a => ["a", "b", "c"]}
n.data.is_a?(Hash).should be_true
n.data.is_a?(Hash).should be true
n.data.should == {:a => ["a", "b", "c"]}

n.data = {:a => "a"}
n.data.is_a?(Hash).should be_true
n.data.is_a?(Hash).should be true
n.data.should == {:a => "a"}
end

Expand All @@ -78,4 +78,4 @@

end
end
end
end
44 changes: 44 additions & 0 deletions spec/support/dummy.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
-----BEGIN CERTIFICATE-----
MIICsDCCAhmgAwIBAgIJALwzrJEIBOaeMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTEwOTMwMTUyNjM2WhcNMjEwOTI3MTUyNjM2WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQC88Ckwru9VR2p2KJ1WQyqesLzr95taNbhkYfsd0j8Tl0MGY5h+dczCaMQz0YY3
xHXuU5yAQQTZjiks+D3KA3cx+iKDf2p1q77oXxQcx5CkrXBWTaX2oqVtHm3aX23B
AIORGuPk00b4rT3cld7VhcEFmzRNbyI0EqLMAxIwceUKSQIDAQABo4GnMIGkMB0G
A1UdDgQWBBSGmOdvSXKXclic5UOKPW35JLMEEjB1BgNVHSMEbjBsgBSGmOdvSXKX
clic5UOKPW35JLMEEqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJALwzrJEI
BOaeMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAcPfWn49pgAX54ji5
SiUPFFNCuQGSSTHh2I+TMrs1G1Mb3a0X1dV5CNLRyXyuVxsqhiM/H2veFnTz2Q4U
wdY/kPxE19Auwcz9AvCkw7ol1LIlLfJvBzjzOjEpZJNtkXTx8ROSooNrDeJl3HyN
cciS5hf80XzIFqwhzaVS9gmiyM8=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA6Lr0lAvQrywXhMnXpJaTBL6edduZUY20piiT82Vasere343B
wcQFUMwGV9CrjSeOMI9jN/0PEw5ZJ5s4AwqYePxy3K05t6MV5UrDx6na7POfUOmC
sfp+KgURY4jQUtOvbHeXr4CjXiMEOJcTTuRaiqy24tjcwkNsHW4/QRyZ1BdKI+8H
x9HqpdwaVn2rCx36ZVukMUqv6y7m8QkDog02oLrneYQy8oMaVwkIcxNxFJzVqobN
SDGXH2Wdh7usoF8P3PD+EuzCgCeP/kqLym4BYXp6tzJj3hT/85xxpsOjIulLuubK
wJz9hngJ/C14DBjXjUmkN38R7XEkR3jvp0K09wIDAQABAoIBAF0irEwu6kWf/I18
hRrt00obyqhZyGKVtgykwoiuJauCpSgY0q5rdsEd1RABhxXHFaUjTM6ULBsxK8ao
3GKDM/9+76yWejmeP13ybKUTuXQIDuK/gDkfiKviOVI+5zeuVU6wEXj/nuFGXCMV
enmg8wb6FXp01Ou9NaAVhaTWAE2afOQSZnI52NUNdV8qvic7+CXpq/W5A/eRIR9v
aGaEzglyXPq3N8LUEjqx5abFijCT3fcLwvO2yOs8gxVhwrS0cr30JXnRxqmEghk9
GsHyJvUyIEz2BFuzJ8sd0xVgej5wxPcdPcmVnGPGYZ/l+tSSw8XaXqmiBhPEElaa
wBET0qECgYEA/aJrYviMbKzS0FuTLNVjEM/Zj60xgVMSZZ9GOqrm4nyIkxFLHmGC
rnfeLiAnT0FlCZlO2vA71vXj8dNbhWSxD8EOCvu/oCcAJc0rmkmOgPIRrQMGcd7I
s3RbT0ZykuX+JW2SlnMWIPPW4QK5MXfqNux42J/6jC/q0iaeGNPBC9ECgYEA6uaf
+YdIHgEYkgn8WjY3i8rX98QmXL9565nFmQe7RmzBZrzFLyKd7FjxjYIz1hk+CfFS
jhMb4WNdeVvV8AVPTiTHomCxdVasfadfadsfdPFCHbkbizenFJf0DNx14qe7eSds
2gQSZ3eTD7XdFNxqwF1dvPXPtDbVBa8SHlijDkcCgYB1tX4e9Xi+Ksq/tfAsu295
auzuOBOkkDgWf3+pVI1IiUEc98aj998dNzYes/9qUdAhT0wAYcNztLQwE8YCt0NR
K2hoAoPhQJhZ8skMlpyTDUTUxXWlPR5p4lNKDEi6EhELr7l7Jzga3O9Zh9kIsz04
djBzYHN3wfk5xIBUx1ltMQKBgBMA8XRIg4cZ45j9AdNyi2/dyzcaQVhDjWOIHzpQ
K9B4v/TF1NYJYOlcEL64B+WMST6YrWsdFKZZWZiV22r9ovrZcuUqGXE7PMgpXGcE
jZZZTlYFQbszl2rNGEtqEodxtnMIw3+n0K1aOSWOOwKTCnfhldHRuSoFPZqmHTsj
RJ3FAoGAXpx+ulBu99kOxOWWofmP7ff9DF3doF+Jmjwo6KdOAIq++74hNRgYCIKM
X+4TSnmu8qBOt++r+EaBgxb+m+36iQxJRhU25ggzlA97v7n7KSxdyt7OLCe5zXP5
iiMWAO+qJD6ZyHlzVz0wwu3nAvkhjTxQ2c3+7xjUwCZK1lXjvvM=
-----END RSA PRIVATE KEY-----