rapns 3.0.1-java → 3.1.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
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
|
90
|
+
-----END RSA PRIVATE KEY-----
|