rapns 3.0.1-java → 3.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +10 -2
- data/README.md +26 -3
- data/bin/rapns +2 -7
- data/lib/generators/templates/add_gcm.rb +3 -1
- data/lib/generators/templates/rapns.rb +42 -11
- data/lib/rapns.rb +11 -1
- data/lib/rapns/apns/notification.rb +8 -2
- data/lib/rapns/app.rb +3 -3
- data/lib/rapns/configuration.rb +46 -13
- data/lib/rapns/daemon.rb +33 -22
- data/lib/rapns/daemon/apns/connection.rb +12 -9
- data/lib/rapns/daemon/apns/delivery_handler.rb +1 -1
- data/lib/rapns/daemon/apns/feedback_receiver.rb +6 -2
- data/lib/rapns/daemon/app_runner.rb +23 -7
- data/lib/rapns/daemon/delivery.rb +5 -1
- data/lib/rapns/daemon/delivery_handler.rb +4 -0
- data/lib/rapns/daemon/feeder.rb +26 -5
- data/lib/rapns/daemon/reflectable.rb +13 -0
- data/lib/rapns/embed.rb +28 -0
- data/lib/rapns/gcm/notification.rb +7 -2
- data/lib/rapns/gcm/payload_data_size_validator.rb +13 -0
- data/lib/rapns/gcm/registration_ids_count_validator.rb +13 -0
- data/lib/rapns/push.rb +12 -0
- data/lib/rapns/reflection.rb +44 -0
- data/lib/rapns/version.rb +1 -1
- data/spec/support/cert_with_password.pem +90 -0
- data/spec/support/cert_without_password.pem +59 -0
- data/spec/unit/apns/app_spec.rb +15 -1
- data/spec/unit/apns/notification_spec.rb +16 -1
- data/spec/unit/configuration_spec.rb +10 -1
- data/spec/unit/daemon/apns/connection_spec.rb +11 -2
- data/spec/unit/daemon/apns/delivery_handler_spec.rb +1 -1
- data/spec/unit/daemon/apns/delivery_spec.rb +10 -0
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +16 -7
- data/spec/unit/daemon/delivery_handler_shared.rb +8 -0
- data/spec/unit/daemon/feeder_spec.rb +37 -6
- data/spec/unit/daemon/gcm/delivery_spec.rb +33 -1
- data/spec/unit/daemon/reflectable_spec.rb +27 -0
- data/spec/unit/daemon_spec.rb +55 -9
- data/spec/unit/embed_spec.rb +44 -0
- data/spec/unit/gcm/notification_spec.rb +9 -3
- data/spec/unit/push_spec.rb +28 -0
- data/spec/unit/reflection_spec.rb +34 -0
- data/spec/unit_spec_helper.rb +4 -62
- metadata +22 -5
- data/lib/rapns/gcm/payload_size_validator.rb +0 -13
@@ -4,18 +4,20 @@ module Rapns
|
|
4
4
|
class ConnectionError < StandardError; end
|
5
5
|
|
6
6
|
class Connection
|
7
|
+
include Reflectable
|
8
|
+
|
7
9
|
attr_accessor :last_write
|
8
10
|
|
9
11
|
def self.idle_period
|
10
12
|
30.minutes
|
11
13
|
end
|
12
14
|
|
13
|
-
def initialize(
|
14
|
-
@
|
15
|
+
def initialize(app, host, port)
|
16
|
+
@app = app
|
15
17
|
@host = host
|
16
18
|
@port = port
|
17
|
-
@certificate = certificate
|
18
|
-
@password = password
|
19
|
+
@certificate = app.certificate
|
20
|
+
@password = app.password
|
19
21
|
written
|
20
22
|
end
|
21
23
|
|
@@ -51,7 +53,8 @@ module Rapns
|
|
51
53
|
retry_count += 1;
|
52
54
|
|
53
55
|
if retry_count == 1
|
54
|
-
Rapns::Daemon.logger.error("[#{@name}] Lost connection to #{@host}:#{@port} (#{e.class.name}), reconnecting...")
|
56
|
+
Rapns::Daemon.logger.error("[#{@app.name}] Lost connection to #{@host}:#{@port} (#{e.class.name}), reconnecting...")
|
57
|
+
reflect(:apns_connection_lost, @app, e)
|
55
58
|
end
|
56
59
|
|
57
60
|
if retry_count <= 3
|
@@ -59,7 +62,7 @@ module Rapns
|
|
59
62
|
sleep 1
|
60
63
|
retry
|
61
64
|
else
|
62
|
-
raise ConnectionError, "#{@name} tried #{retry_count-1} times to reconnect but failed (#{e.class.name})."
|
65
|
+
raise ConnectionError, "#{@app.name} tried #{retry_count-1} times to reconnect but failed (#{e.class.name})."
|
63
66
|
end
|
64
67
|
end
|
65
68
|
end
|
@@ -72,7 +75,7 @@ module Rapns
|
|
72
75
|
protected
|
73
76
|
|
74
77
|
def reconnect_idle
|
75
|
-
Rapns::Daemon.logger.info("[#{@name}] Idle period exceeded, reconnecting...")
|
78
|
+
Rapns::Daemon.logger.info("[#{@app.name}] Idle period exceeded, reconnecting...")
|
76
79
|
reconnect
|
77
80
|
end
|
78
81
|
|
@@ -104,10 +107,10 @@ module Rapns
|
|
104
107
|
ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, @ssl_context)
|
105
108
|
ssl_socket.sync = true
|
106
109
|
ssl_socket.connect
|
107
|
-
Rapns::Daemon.logger.info("[#{@name}] Connected to #{@host}:#{@port}")
|
110
|
+
Rapns::Daemon.logger.info("[#{@app.name}] Connected to #{@host}:#{@port}")
|
108
111
|
[tcp_socket, ssl_socket]
|
109
112
|
end
|
110
113
|
end
|
111
114
|
end
|
112
115
|
end
|
113
|
-
end
|
116
|
+
end
|
@@ -4,7 +4,7 @@ module Rapns
|
|
4
4
|
class DeliveryHandler < Rapns::Daemon::DeliveryHandler
|
5
5
|
def initialize(app, host, port)
|
6
6
|
@app = app
|
7
|
-
@connection = Connection.new(@app
|
7
|
+
@connection = Connection.new(@app, host, port)
|
8
8
|
@connection.connect
|
9
9
|
end
|
10
10
|
|
@@ -2,6 +2,7 @@ module Rapns
|
|
2
2
|
module Daemon
|
3
3
|
module Apns
|
4
4
|
class FeedbackReceiver
|
5
|
+
include Reflectable
|
5
6
|
include InterruptibleSleep
|
6
7
|
include DatabaseReconnectable
|
7
8
|
|
@@ -35,7 +36,7 @@ module Rapns
|
|
35
36
|
def check_for_feedback
|
36
37
|
connection = nil
|
37
38
|
begin
|
38
|
-
connection = Connection.new(
|
39
|
+
connection = Connection.new(@app, @host, @port)
|
39
40
|
connection.connect
|
40
41
|
|
41
42
|
while tuple = connection.read(FEEDBACK_TUPLE_BYTES)
|
@@ -59,8 +60,11 @@ module Rapns
|
|
59
60
|
def create_feedback(failed_at, device_token)
|
60
61
|
formatted_failed_at = failed_at.strftime("%Y-%m-%d %H:%M:%S UTC")
|
61
62
|
with_database_reconnect_and_retry do
|
62
|
-
Rapns::Daemon.logger.info("[
|
63
|
+
Rapns::Daemon.logger.info("[#{@app.name}] [FeedbackReceiver] Delivery failed at #{formatted_failed_at} for #{device_token}.")
|
63
64
|
feedback = Rapns::Apns::Feedback.create!(:failed_at => failed_at, :device_token => device_token, :app => @app)
|
65
|
+
reflect(:apns_feedback, feedback)
|
66
|
+
|
67
|
+
# Deprecated.
|
64
68
|
begin
|
65
69
|
Rapns.config.apns_feedback_callback.call(feedback) if Rapns.config.apns_feedback_callback
|
66
70
|
rescue StandardError => e
|
@@ -2,7 +2,7 @@ module Rapns
|
|
2
2
|
module Daemon
|
3
3
|
class AppRunner
|
4
4
|
class << self
|
5
|
-
attr_reader :runners
|
5
|
+
attr_reader :runners
|
6
6
|
end
|
7
7
|
|
8
8
|
@runners = {}
|
@@ -86,20 +86,28 @@ module Rapns
|
|
86
86
|
diff = handlers.size - app.connections
|
87
87
|
return if diff == 0
|
88
88
|
if diff > 0
|
89
|
-
diff.times {
|
90
|
-
Rapns::Daemon.logger.info("[#{app.name}]
|
89
|
+
diff.times { decrement_handlers }
|
90
|
+
Rapns::Daemon.logger.info("[#{app.name}] Stopped #{handlers_str(diff)}. #{handlers_str} remaining.")
|
91
91
|
else
|
92
|
-
diff.abs.times {
|
93
|
-
Rapns::Daemon.logger.info("[#{app.name}]
|
92
|
+
diff.abs.times { increment_handlers }
|
93
|
+
Rapns::Daemon.logger.info("[#{app.name}] Started #{handlers_str(diff)}. #{handlers_str} remaining.")
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
+
def decrement_handlers
|
98
|
+
handlers.pop.stop
|
99
|
+
end
|
100
|
+
|
101
|
+
def increment_handlers
|
102
|
+
handlers << start_handler
|
103
|
+
end
|
104
|
+
|
97
105
|
def debug
|
98
106
|
Rapns::Daemon.logger.info <<-EOS
|
99
107
|
|
100
108
|
#{@app.name}:
|
101
|
-
handlers: #{
|
102
|
-
queued: #{
|
109
|
+
handlers: #{num_handlers}
|
110
|
+
queued: #{queue_size}
|
103
111
|
idle: #{idle?}
|
104
112
|
EOS
|
105
113
|
end
|
@@ -108,6 +116,14 @@ module Rapns
|
|
108
116
|
queue.notifications_processed?
|
109
117
|
end
|
110
118
|
|
119
|
+
def queue_size
|
120
|
+
queue.size
|
121
|
+
end
|
122
|
+
|
123
|
+
def num_handlers
|
124
|
+
handlers.size
|
125
|
+
end
|
126
|
+
|
111
127
|
protected
|
112
128
|
|
113
129
|
def start_handler
|
@@ -2,6 +2,7 @@ module Rapns
|
|
2
2
|
module Daemon
|
3
3
|
class Delivery
|
4
4
|
include DatabaseReconnectable
|
5
|
+
include Reflectable
|
5
6
|
|
6
7
|
def self.perform(*args)
|
7
8
|
new(*args).perform
|
@@ -13,6 +14,7 @@ module Rapns
|
|
13
14
|
notification.deliver_after = deliver_after
|
14
15
|
notification.save!(:validate => false)
|
15
16
|
end
|
17
|
+
reflect(:notification_will_retry, notification)
|
16
18
|
end
|
17
19
|
|
18
20
|
def retry_exponentially(notification)
|
@@ -25,6 +27,7 @@ module Rapns
|
|
25
27
|
@notification.delivered_at = Time.now
|
26
28
|
@notification.save!(:validate => false)
|
27
29
|
end
|
30
|
+
reflect(:notification_delivered, @notification)
|
28
31
|
end
|
29
32
|
|
30
33
|
def mark_failed(code, description)
|
@@ -37,7 +40,8 @@ module Rapns
|
|
37
40
|
@notification.error_description = description
|
38
41
|
@notification.save!(:validate => false)
|
39
42
|
end
|
43
|
+
reflect(:notification_failed, @notification)
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
43
|
-
end
|
47
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Rapns
|
2
2
|
module Daemon
|
3
3
|
class DeliveryHandler
|
4
|
+
include Reflectable
|
5
|
+
|
4
6
|
attr_accessor :queue
|
5
7
|
|
6
8
|
def start
|
@@ -35,8 +37,10 @@ module Rapns
|
|
35
37
|
|
36
38
|
begin
|
37
39
|
deliver(notification)
|
40
|
+
reflect(:notification_delivered, notification)
|
38
41
|
rescue StandardError => e
|
39
42
|
Rapns::Daemon.logger.error(e)
|
43
|
+
reflect(:error, e)
|
40
44
|
ensure
|
41
45
|
queue.notification_processed
|
42
46
|
end
|
data/lib/rapns/daemon/feeder.rb
CHANGED
@@ -3,12 +3,17 @@ module Rapns
|
|
3
3
|
class Feeder
|
4
4
|
extend InterruptibleSleep
|
5
5
|
extend DatabaseReconnectable
|
6
|
+
extend Reflectable
|
6
7
|
|
7
|
-
def self.start
|
8
|
-
|
8
|
+
def self.start
|
9
|
+
@stop = false
|
10
|
+
|
11
|
+
if Rapns.config.embedded
|
12
|
+
Thread.new { feed_forever }
|
13
|
+
elsif Rapns.config.push
|
9
14
|
enqueue_notifications
|
10
|
-
|
11
|
-
|
15
|
+
else
|
16
|
+
feed_forever
|
12
17
|
end
|
13
18
|
end
|
14
19
|
|
@@ -19,17 +24,33 @@ module Rapns
|
|
19
24
|
|
20
25
|
protected
|
21
26
|
|
27
|
+
def self.feed_forever
|
28
|
+
loop do
|
29
|
+
enqueue_notifications
|
30
|
+
interruptible_sleep(Rapns.config.push_poll)
|
31
|
+
break if stop?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.stop?
|
36
|
+
@stop
|
37
|
+
end
|
38
|
+
|
22
39
|
def self.enqueue_notifications
|
23
40
|
begin
|
24
41
|
with_database_reconnect_and_retry do
|
25
42
|
batch_size = Rapns.config.batch_size
|
26
43
|
idle = Rapns::Daemon::AppRunner.idle.map(&:app)
|
27
|
-
Rapns::Notification.ready_for_delivery.for_apps(idle)
|
44
|
+
relation = Rapns::Notification.ready_for_delivery.for_apps(idle)
|
45
|
+
relation = relation.limit(batch_size) unless Rapns.config.push
|
46
|
+
relation.each do |notification|
|
28
47
|
Rapns::Daemon::AppRunner.enqueue(notification)
|
48
|
+
reflect(:notification_enqueued, notification)
|
29
49
|
end
|
30
50
|
end
|
31
51
|
rescue StandardError => e
|
32
52
|
Rapns::Daemon.logger.error(e)
|
53
|
+
reflect(:error, e)
|
33
54
|
end
|
34
55
|
end
|
35
56
|
end
|
data/lib/rapns/embed.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Rapns
|
2
|
+
def self.embed(options = {})
|
3
|
+
Rapns.require_for_daemon
|
4
|
+
|
5
|
+
config = Rapns::ConfigurationWithoutDefaults.new
|
6
|
+
options.each { |k, v| config.send("#{k}=", v) }
|
7
|
+
config.embedded = true
|
8
|
+
Rapns.config.update(config)
|
9
|
+
Rapns::Daemon.start
|
10
|
+
|
11
|
+
Kernel.at_exit { shutdown }
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.shutdown
|
15
|
+
return unless Rapns.config.embedded
|
16
|
+
Rapns::Daemon.shutdown
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.sync
|
20
|
+
return unless Rapns.config.embedded
|
21
|
+
Rapns::Daemon::AppRunner.sync
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.debug
|
25
|
+
return unless Rapns.config.embedded
|
26
|
+
Rapns::Daemon::AppRunner.debug
|
27
|
+
end
|
28
|
+
end
|
@@ -3,7 +3,8 @@ module Rapns
|
|
3
3
|
class Notification < Rapns::Notification
|
4
4
|
validates :registration_ids, :presence => true
|
5
5
|
validates_with Rapns::Gcm::ExpiryCollapseKeyMutualInclusionValidator
|
6
|
-
validates_with Rapns::Gcm::
|
6
|
+
validates_with Rapns::Gcm::PayloadDataSizeValidator
|
7
|
+
validates_with Rapns::Gcm::RegistrationIdsCountValidator
|
7
8
|
|
8
9
|
def registration_ids=(ids)
|
9
10
|
ids = [ids] if ids && !ids.is_a?(Array)
|
@@ -26,6 +27,10 @@ module Rapns
|
|
26
27
|
|
27
28
|
json
|
28
29
|
end
|
30
|
+
|
31
|
+
def payload_data_size
|
32
|
+
multi_json_dump(as_json['data']).bytesize
|
33
|
+
end
|
29
34
|
end
|
30
35
|
end
|
31
|
-
end
|
36
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Rapns
|
2
|
+
module Gcm
|
3
|
+
class PayloadDataSizeValidator < ActiveModel::Validator
|
4
|
+
LIMIT = 4096
|
5
|
+
|
6
|
+
def validate(record)
|
7
|
+
if record.payload_data_size > LIMIT
|
8
|
+
record.errors[:base] << "GCM notification payload data cannot be larger than #{LIMIT} bytes."
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Rapns
|
2
|
+
module Gcm
|
3
|
+
class RegistrationIdsCountValidator < ActiveModel::Validator
|
4
|
+
LIMIT = 1000
|
5
|
+
|
6
|
+
def validate(record)
|
7
|
+
if record.registration_ids && record.registration_ids.size > LIMIT
|
8
|
+
record.errors[:base] << "GCM notification num of registration_ids cannot be larger than #{LIMIT}."
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/rapns/push.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Rapns
|
2
|
+
def self.push(options = {})
|
3
|
+
Rapns.require_for_daemon
|
4
|
+
|
5
|
+
config = Rapns::ConfigurationWithoutDefaults.new
|
6
|
+
options.each { |k, v| config.send("#{k}=", v) }
|
7
|
+
config.push = true
|
8
|
+
Rapns.config.update(config)
|
9
|
+
Rapns::Daemon.start
|
10
|
+
Rapns::Daemon.shutdown(true)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Rapns
|
2
|
+
def self.reflect
|
3
|
+
yield reflections if block_given?
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.reflections
|
7
|
+
@reflections ||= Reflections.new
|
8
|
+
end
|
9
|
+
|
10
|
+
class Reflections
|
11
|
+
class NoSuchReflectionError < StandardError; end
|
12
|
+
|
13
|
+
REFLECTIONS = [
|
14
|
+
:apns_feedback, :notification_enqueued, :notification_delivered,
|
15
|
+
:notification_failed, :notification_will_retry, :apns_connection_lost,
|
16
|
+
:error
|
17
|
+
]
|
18
|
+
|
19
|
+
REFLECTIONS.each do |reflection|
|
20
|
+
class_eval(<<-RUBY, __FILE__, __LINE__)
|
21
|
+
def #{reflection}(*args, &blk)
|
22
|
+
raise "block required" unless block_given?
|
23
|
+
reflections[:#{reflection}] = blk
|
24
|
+
end
|
25
|
+
RUBY
|
26
|
+
end
|
27
|
+
|
28
|
+
def __dispatch(reflection, *args)
|
29
|
+
unless REFLECTIONS.include?(reflection.to_sym)
|
30
|
+
raise NoSuchReflectionError, reflection
|
31
|
+
end
|
32
|
+
|
33
|
+
if reflections[reflection]
|
34
|
+
reflections[reflection].call(*args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def reflections
|
41
|
+
@reflections ||= {}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/rapns/version.rb
CHANGED
@@ -0,0 +1,90 @@
|
|
1
|
+
Bag Attributes
|
2
|
+
localKeyID: A4 1A DB 3E 3E 45 D9 C7 51 1E E6 DC 4E BC 29 19 E4 22 95 35
|
3
|
+
subject=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd
|
4
|
+
issuer=/C=UK/ST=Some-State/O=Internet Widgits Pty Ltd
|
5
|
+
-----BEGIN CERTIFICATE-----
|
6
|
+
MIIE/jCCAuYCAQEwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCVUsxEzARBgNV
|
7
|
+
BAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
|
8
|
+
ZDAeFw0xMjEyMjgxMzU4NTdaFw0xNDEyMjgxMzU4NTdaMEUxCzAJBgNVBAYTAkFV
|
9
|
+
MRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRz
|
10
|
+
IFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDYCSfYP0P7
|
11
|
+
F+JbxUHYsl/9Plr2bFZGMBygqs5RWpw1X977p4FqcNtnRmGENQ/I5vE3KkAKCAlS
|
12
|
+
gmus7CjB9/FVzoJq65cT3wBkcqAAzPgIQuI0UjP+rLktV84eUup7Pt6f/Bmt/fBj
|
13
|
+
h3fvf80nBQcdK2ztu1xtTs7EsRgyudUDDEIUZw9ddK21RbCMYE0PFY0QapNVvevs
|
14
|
+
8lDVUJX60bZqVqzhvlTzmEaBF+E66J/DhHuhcWZV588hVKjHMNED9Aq4PxRy78vI
|
15
|
+
54v1buX2Y9C6dHfIzfu7zz0Zv5NAY1BZKpaglVGKArOrX+K6O7Bq+DwckTm1AbUf
|
16
|
+
pQqi10ghveOtVrm4GXJ4OYW8ohdYKMFjzwhgTTr/NQ+EVlcZ+8AOPVPPJk0HgPu/
|
17
|
+
eMNiLytvcSnB09OzIUAzcxOof2a1zfxn7aPzBTEC6kkoDJC/BDG8wxySUz0zRyyM
|
18
|
+
jUN2+J1mBJZX1h1sM/4ycAzsX1EYm2II5GGJaFngiV45Qv7wTC7W31kvih7FsdUX
|
19
|
+
rEYMkevB5AFPUtIvzevLUObLbPW4yWvU2CMcKLZdIaPTvtPMba91t1YOdufpPRDd
|
20
|
+
HTmT42h0aUWDSrcWDAuZPPPqEIQNjRVCudtHtobZDeaUfvbx05CvypyuNFaPonuQ
|
21
|
+
l5h0LpZWPetvfsrOlMxPm2kfVcxm8mWjzQIDAQABMA0GCSqGSIb3DQEBBQUAA4IC
|
22
|
+
AQBiwdPfLU0kjbU1hM6grUHduLqOPDqLT5gefGRrL5fDqb86G08+Wz+Tnn1YmH+7
|
23
|
+
rfiQhCrdi4zxRv6ZEaKZeEm/q1UMttuUdXuzd25BEEtav4R0POdR+H1q3trlS0ol
|
24
|
+
EcWlAbRgVaT2tTyKGAW54fH8vZPqS6IP+mXIzfaOFECPEgAO8BL8t7hBDpkL4ASO
|
25
|
+
HbU7ktYamsr6PAei3kXAnJ1thXyQqrhelwLrQJyM8RVOJYUgVbl6Fpdtgu7YQF5G
|
26
|
+
kxTAfshSmDCQkf+tbUEs44rZ6BZ2TWnbXjQGkRntHcMCP/1rjsPPdX3oeZ7P3jMQ
|
27
|
+
XER3drdm1mOiSdDUKbem9GzQ9Dx7WkwKNLYAZ+IWzVRACzGxnkxXyxOEFIgesDgg
|
28
|
+
RIhczN+eLIR8iwcUxEVKFmmsbEIve3Uh1/NE6xGudbfZDNfhyOhiNYIBnQqVkk8l
|
29
|
+
c3gw2UDR3lXTayiiXhK2l1etsyxtYncT3pgDsCe72RODrGKbASt3FzfBbalzN0GG
|
30
|
+
9tiPSNtGqCch9q4eHfViUh9s3+8n4bknAYcwzQ96+gMEn8PUVtDBv9F8Kxffn/Jt
|
31
|
+
XMWKX76nTVuAuCLkXxrKwc01lq8SeuvCH650xsv0LBvxj9h6vR34vHGrj0C3sH2E
|
32
|
+
VQpelKNv8IEwkSiQcwDtU8H0jaPJNqmYlkrxasSrSeg6PA==
|
33
|
+
-----END CERTIFICATE-----
|
34
|
+
Bag Attributes
|
35
|
+
localKeyID: A4 1A DB 3E 3E 45 D9 C7 51 1E E6 DC 4E BC 29 19 E4 22 95 35
|
36
|
+
Key Attributes: <No Attributes>
|
37
|
+
-----BEGIN RSA PRIVATE KEY-----
|
38
|
+
Proc-Type: 4,ENCRYPTED
|
39
|
+
DEK-Info: DES-EDE3-CBC,874F2C982467BF08
|
40
|
+
|
41
|
+
dwt8Z0+2alFCo/YDjyd2xDhVCpmmxn5BT2wVTZiCEJrlSIY99oQyQWDy/152X5ZE
|
42
|
+
dl3V014PtDjYyHeMh+V3Ws98hPxyTvymkQsDfQKhKHpg2IhEsubZi+crlKj2NQkm
|
43
|
+
i6+0t6v3sRLYbJnxbAKRa8rzLn2Q18vxflrWqO8WwDj+RuPevUBZEU5pceh3CyWu
|
44
|
+
qQ0MDcj1KSeM6SSJGnVw0Lk4p6HFzPU5xkgPO1lp5Abrm0G01F8xmS38sMjuMyfI
|
45
|
+
OZeuHfOX2VUTNPliRuAVa0SlioTIqsDFZCTTRLdjxNe8P1szJTXAhCn31TR2Z24m
|
46
|
+
iqEVDyxgR4M/qtR2QNkXdzAp7YlnrWlMp08vo+l7DyLYd+HOchN/VXk+3CU2B7w7
|
47
|
+
dUlqA8lwh/s5h7xiXZ35QR9PmF7Gih7Q2QrCpy3PhJt8V3/cSiNwg5wikBXP2Tep
|
48
|
+
28X7qgTWBulmkp/R9DO3rUSR4Boc+UfvswI7/FQczcaQGJpedDY5f/7lJPoIKJL2
|
49
|
+
5Ix9kr/inyUPnQZpNEmJmaKO0lyei6DawFozagT1XntYewzENFIYUqV6ZajLMuTe
|
50
|
+
VHkLUqK1M/yVgR2NCyKLFZHMAdTcYhdClSb0YvE++hevyWFxdD13TyWmHB9+UL3o
|
51
|
+
29dWhBEA9nk/mVTGIFVmk6fF+QaWlKMVFxgdlYThTmk/1ZUyH0BqPWYE56Ux7Tmp
|
52
|
+
hP5wZvRzaF5fV/dlfFRXZ0S0LFK11ld4Oaps18OuCzYKNTr9alaFfChqFtddVBcf
|
53
|
+
HY1DEeCF4p59ptsTalTqrO4ieDFkf5da3ZAyC32X8pzaD9+pPwm8vBBFtamXp70V
|
54
|
+
jJt2K8jlS5S7KL5ZliBMrGGJZF+jMQh1SBRdFn/h+VFulaH+qDyIAvkwyeWV4V0t
|
55
|
+
rO4HroZalJIlraqXGPLyX7/QWTetqSvCUR8mZcckUIIHseeP6xeLFvxs7Y58ns2Y
|
56
|
+
Rw+B7UI253YEwUF9N5vBddqN7fCQlbrxpjMOMT/p+DZzuS8evayevjbYwIS8vssQ
|
57
|
+
hMjm4iTB4daAjMzWCKaBTFXQTRV4OfzXRYZaM3zeNYzTxakX+BPUX4R5Sf6VpDP3
|
58
|
+
vYyXpoIIG/n+6B7qXUMoQXprj/T5XzJQpQK6B+ubmFmuEjbWrCy/MdLGceV6pxxW
|
59
|
+
OW1xtCUDLjrd2UAFIfJRJLtevr1Fvin3xZYhvtrhwMPhk9JKOr/6ubLvL+5oturN
|
60
|
+
YzaIDRjE33XSEcOPCSPCymNaDStzpxKNbsM8POEne8qVSRK+D+9YDbmqbSLQR1vN
|
61
|
+
07CTgbclTrvOUKZYL0nr9g99oFj/ldYPDrNzVd48MVmhvJZOuz1CApKZ4UcUO5EU
|
62
|
+
jfOqTtdFbZSbccOdGgQN39GmrQ/Ys0cj15VbymgNiOpk3dEMQli/iGBW9F+oBs4X
|
63
|
+
dRLvephnfOBRlB/4PVjrXuzLI1rQXhlGkEX4ik1HVQviti+7g2y+2IQvBu0C494n
|
64
|
+
g7PoAIoGQDPciCfBodxOWwg9dCXhmlcZZa3MDMEdFQ8dV5ZYdPBzbzqRhasbIZUR
|
65
|
+
K/b1qU6MUWoC7HfCXK8DUHZvvEi/uZT6zPQnukOPxf7jS6yMrmdFdT6v0qh3PYOt
|
66
|
+
LTjB1HMeDc2ku88y185yU8EFryV8B06WITHuhLZG1AqvS0KkD+vokcj5mXFFtPz0
|
67
|
+
FI5GcBQ/U7DF31BTRUhhOZV+MdCaRZMfhvQiEr+9axS04qO5okV6mvXknGJYN47m
|
68
|
+
4s0Z2kgtnIpwMMlDxeuBGa2Qt/FL5i6JIJ8df265CnPBf9lPloTwsHohMPrnSH1y
|
69
|
+
VXaobhYJogSXj4A0WW/Kb4aW64mCKpGrm05ed/cBQ5TM/DQssPYxD1sibXBBR0Yq
|
70
|
+
iMa5JhOripEo7EceX8btsGUUDRNwDUZcaeeqJ5VEKnYW86LKpubMViIJeKoPzAX7
|
71
|
+
4HsoR+g4G2nok1wntcGGszXk49iGuo59gDlnN6o6C3OY70L8AAN8DhxHQk3edzjV
|
72
|
+
ZIGm24y6Icz77qajgLGzhGHvZQ8f8910LNbyjGKrFKIA4m8PRvN/ZXjd2WWAB0Td
|
73
|
+
zbBGmYnonOQp7V9oD8bbUlofnSsav94QaeedI7W5is6cX01GPoHBnV85y9z44/+L
|
74
|
+
yDTt3ZIToMjq8gbWeEOoFI0sxf+uok5tDMnIFr4pAW0fitsRI0k/hUeUaGxuQnU1
|
75
|
+
zgLQia/+zWLAMgoaU+yGRvUW/SnBHR3EayNzKlLlVWK7cY4+TF0fYOYzebTsrfN0
|
76
|
+
w9KNjq3ahoofVcnj51euuvEpDXE2s9ZYsW7kYH475giYJxlJUNkq1nxqw5u1IZp3
|
77
|
+
/VmR7Vg/EzrN/vjvohn659fpYBBvPYcd0m+CFEzXdhJTBVY/AKK6BZTwiNUCoNPq
|
78
|
+
d0JsRdhrEmuVCk+LrEdkNFVXGOpCejsgRxHNVlnsO+V+imy+rrI/G1r7nNgA0QMp
|
79
|
+
R8sf26MpekASRQPmYmlP7Pq/kjIAdwfuEE4gNlec95/GoHnbHoHyyMHqxqudSJpA
|
80
|
+
mlbZs/uSiOU2uoPRRtVkZET82F7yz4zKLWNzYyAjCkVwXcHMOeZQMnh1SacR8YRM
|
81
|
+
Qqn/dd2TU5Xw3XBO/fplaznct9Svppx0e3XniLGkHN/rKN8Co6gH99GHOWQ/Mekx
|
82
|
+
MeMxxKbXQS2HGcPAkCGSa9PdD+/xuGWVdCOwPnLSRU+nLh+b3VoiLRPd+GE5MX6+
|
83
|
+
ClVANBp5Gi5Q21tDsGnIPJS8s6WCNa8jafBvAPi0J1w5eFfRIBXooFUfHMwXx+NF
|
84
|
+
udopf6S6OavheOLNstLUKlyn8tKgPcGide6Sl3fxHOULvGgLWM9IAM5ta0U6SkyX
|
85
|
+
mqW6pIVFc8OV73FEZXvUo3aztEhuB6wa7bC0xohbulDUHE56BfFt/OWLNhBDCkc6
|
86
|
+
RfbHBoPFv5oKz5zqcKw9tCx5pL33vLRhEsd11/0jDWJpPvp1pbHq3D75by7xmJt9
|
87
|
+
Vh+RRQgVfrF0Z6QD9hD/rBChmZLGEkmLNuLgP5DB14ebzdxL4NF1GdcIuXTWtv22
|
88
|
+
lA032Iv2YQQUA/2fvp2XzAmE9Uvma2cj50e65Ky9iJ5O6suDfBwc4UPYQ6gI8BxA
|
89
|
+
Hzd1Xl9Zs3f7b4eRKhu+V1kjloW4tfCurPme72cgvTtZacgUTRJmlcq1OtXxpt+V
|
90
|
+
-----END RSA PRIVATE KEY-----
|