Skip to content

Commit ed55271

Browse files
authored
Fix reference cycle created by listeners that reference the client (#129)
* Call shutdown listener once * Clear listeners in shutdown This will remove any reference cycle where the listener references the client * Rebuild test certificates * Build CI docker image for linux/amd64 * Add comment
1 parent 2408412 commit ed55271

File tree

16 files changed

+179
-153
lines changed

16 files changed

+179
-153
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ jobs:
5555
container:
5656
image: ${{ matrix.tag }}
5757
services:
58+
# need to update docker image if you update the certificates
59+
# run `build-docker-ci-image.sh`
5860
mosquitto:
5961
image: adamfowlerphoto/mqttnio-mosquitto
6062
ports:

Sources/MQTTNIO/MQTTClient.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ public final class MQTTClient {
201201
}
202202
let eventLoop = self.eventLoopGroup.next()
203203
let closeFuture: EventLoopFuture<Void>
204-
self.shutdownListeners.notify(.success(()))
205204
if let connection = self.connection {
206205
closeFuture = connection.close()
207206
} else {
@@ -216,10 +215,17 @@ public final class MQTTClient {
216215
} else {
217216
closeError = error
218217
}
218+
self.shutdownListeners.notify(.failure(error))
219219
case .success:
220220
closeError = nil
221+
self.shutdownListeners.notify(.success(()))
221222
}
222-
self.shutdownListeners.notify(.success(()))
223+
// remove all listeners as they may contain references to the client and cause
224+
// a reference cycle
225+
self.publishListeners.removeAll()
226+
self.closeListeners.removeAll()
227+
self.shutdownListeners.removeAll()
228+
223229
self.shutdownEventLoopGroup(queue: queue) { error in
224230
callback(closeError ?? error)
225231
}

Sources/MQTTNIO/MQTTListeners.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ struct MQTTListeners<ReturnType> {
3737
}
3838
}
3939

40+
mutating func removeAll() {
41+
self.listeners = [:]
42+
}
43+
4044
private let lock = NIOLock()
4145
private var listeners: [String: Listener] = [:]
4246
}

Tests/MQTTNIOTests/MQTTNIOTests.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ final class MQTTNIOTests: XCTestCase {
9494
func testSSLConnect() throws {
9595
#if os(macOS)
9696
// p12 loading crashes when debugger other than Xcode is attached
97-
guard !self.isVSCodeDebugging() else { throw XCTSkip() }
97+
// guard !self.isVSCodeDebugging() else { throw XCTSkip() }
9898
#endif
9999

100100
let client = try createSSLClient(identifier: "testSSLConnect")
@@ -107,7 +107,7 @@ final class MQTTNIOTests: XCTestCase {
107107
func testWebsocketAndSSLConnect() throws {
108108
#if os(macOS)
109109
// p12 loading crashes when debugger other than Xcode is attached
110-
guard !self.isVSCodeDebugging() else { throw XCTSkip() }
110+
// guard !self.isVSCodeDebugging() else { throw XCTSkip() }
111111
#endif
112112

113113
let client = try createWebSocketAndSSLClient(identifier: "testWebsocketAndSSLConnect")
@@ -121,7 +121,7 @@ final class MQTTNIOTests: XCTestCase {
121121
func testSSLConnectFromP12() throws {
122122
#if os(macOS)
123123
// p12 loading crashes when debugger other than Xcode is attached
124-
guard !self.isVSCodeDebugging() else { throw XCTSkip() }
124+
// guard !self.isVSCodeDebugging() else { throw XCTSkip() }
125125
#endif
126126

127127
let client = try MQTTClient(
@@ -506,6 +506,20 @@ final class MQTTNIOTests: XCTestCase {
506506
try client2.disconnect().wait()
507507
}
508508

509+
/// Check listeners don't create a reference cycle if they reference the client
510+
func testListenerReferenceCycle() throws {
511+
func createClient() throws -> MQTTClient? {
512+
let client = self.createClient(identifier: "testListenerReferenceCycle")
513+
client.addPublishListener(named: "refcycle") { _ in
514+
print(client)
515+
}
516+
try client.syncShutdownGracefully()
517+
return client
518+
}
519+
weak var client = try createClient()
520+
XCTAssertNil(client)
521+
}
522+
509523
func testSubscribeAll() throws {
510524
if ProcessInfo.processInfo.environment["CI"] != nil {
511525
return

mosquitto/certs/ca.der

0 Bytes
Binary file not shown.

mosquitto/certs/ca.key

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
-----BEGIN PRIVATE KEY-----
2-
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDDDxlrL/whSh48
3-
DFZhrlfAhx5ifd0v1RqBYFLF/DiA9//XPsD4RRUb8oZOqblFMDWWdERnvXRT+dlB
4-
IPoA+5ilN3bViTfnhusCxS5NA4WaK7RIbzkzf/OPMsrkaoLGFWymBNlMvpUpPAjD
5-
SALahfpNsD55pPxADP+N/wf01l/uv7xPisOSqDYMFMm5MvfK8o+LK7pfSAhZtLSo
6-
5quRnAvDqSD2//B8J1aaZO/X8bFLj24QbmgNxETTGx/XOosqKYXeG8/aLqHi+2h1
7-
o0tK+Qfd/Y/YPXmqYQxvgkWQ+rJ/Ca3UIafso7NKbE/Vl4WgJqNl4WD6NAFobTEq
8-
1zt2C6BvAgMBAAECggEBAKexFXM2/5VG+RM6sBCuJ7bW8uJNvpheprjPLJoVKiaG
9-
DqbnxlIqYely6NA7zZGTzp4YOq7NC3Meew4o4YVyx1pSgpE1tKARN31cM1/2RSez
10-
pvwW0qBZwfQ8AH26q87LoGpiBMabmfSnLglkoT9oqzWa7Tr7Afm2swVKWXa9zh+b
11-
p9/jUJYXpO+nrcfkMwJt2aPMynjTiDs/4s06Tk5vroEk4Kwyff0xQSGK8v+BSs8v
12-
pBhEB9YxyVf7ymwGxEPNV8HGKpWoBxJlteeCh4CbazAZ9mQtXzRDx5DXPWOCqe1b
13-
hFIy8TwZzO5lzbWbKC26GqOexCSZz2BrNbj+b71TyXECgYEA+wLfq3gRQthobbZL
14-
0nNlIUlyftFad+5klQNXoYG0i4xN88/WCyykV3IoHFxFgwjxKk4JOgv7ks4Ki/y1
15-
PQ8n03TGKjJM4HXnCvC0NmCCggGrzRWa6nj9LFfJYImHohpOgTgV+eavHikd4mzH
16-
2jerHwUY2K9lZzRKEz/h8TBT33UCgYEAxu+LdXqrVAo5GREUS/8sinvRLTULZKRO
17-
8SjpV67XnvbPu0+NOpQm52iFboCWZ+0q8LXc+lgkkhjQxfr1Cr0CPoGWzUS1bubf
18-
tjcnOldvNWBFjeFcRXysqCOT3NQyT2C8OIPptru5oyIAs+TG6166/+5ZUoZylXfV
19-
2K4nZ1ENR9MCgYEA1fOUHL6hz91P3bwVktNDLwVAr3HY8ALl/tGzfvlkn9G+nAPa
20-
SPoLNnIaWFoZ8d/MWCfd23ldPLuc58dF4D6rzqRpSIxJVMWKYpvar8LBWvj7rDov
21-
Ko5oFcTZ5Aw17OkJY0EgEjsbptSbIWVhT9JFbJJWpFOUVkyOmyvHdWKhCwUCgYAN
22-
DXKNBrtvDCyq5F/8jIWToIQc/zn8JHu5fwGwaxxipbcDhziw+z+CN21pzq4Pq5QB
23-
ry0Mj/P2UgKAuvKQ/c3D5CTM2xE8cZGEFyJPxaTaT7LAmGTBemipr4voFVQnuSUg
24-
YCdZgf+wIG8DXqNelhyW5kCeFYw3GmHBkcusD7lbWQKBgFv7OWDcILqncpvbtNco
25-
Ejpi6yMt1p7t0O+MvbOubg8JIk9d6YvEYhfdzaO3K/g8Wi78dBV02p7S+//HWB+j
26-
RA/dXCSJ9KnQSo8LGk8j7Hqm4cIhWbGHJw6nnDA3iMfCBdS7cXbnOBPGW0XniDdE
27-
fGgzS4qmoY9Csb6u+fVJWOzc
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCoQMyD2Dqi+rBn
3+
+G4KTySuwVGyafAXfnGCmUdyO7Rz3ACthWnh9Wij7pTvwump7U4CNEDiYa6V8P3l
4+
8w5AInlOIwMhG9o1oq03CUHniHmDzzpk47h0d+oF/Z8aRTe7iNfYwfcPvZjFVBvI
5+
nuJqgC2aEk81zBo4pUixbWHXVOXmWct2BU90qb4ZceCi6c9AF58on8gr7S8hwx6r
6+
CFdrb713rNCLYvUwTClq40DpYvKoCRnOr+/KjoYECzqi+dCcEBFL3KsnoaPTtxRx
7+
DLaRUH01rf0OF3NYYPAfHISZdcbN4qNtKrg7m3p5Pzb3O9ZFwrPxAmtSLpGiVyDF
8+
s1PGFYO7AgMBAAECggEBAIQoKbwh2qTrjiaMbzqvwZt2g4pFRe3eRqCTbxgeJ3ad
9+
xvaFBY8TqTaijt/o1IrBt/VpP9HRckWaPoQhLv9XVLr4K1wVOYfJmI7TOa34d6H9
10+
4tseN2NcUTiVZyRGXCl0qj461KnLfbT5hL1Hd4a52Zfca9VQ1QPLZ9bdmO1/ZPlS
11+
JdJ+ES6ObrFRrAoymVsYuyFV8DzpmOPNxDVjQ/MiN01T6sddvSV22UOurgd6llFJ
12+
i2OMXbFrXEWftbwx9+qID9ycH2VA+PYlIDWwLi5q9xOPOW5a6DvmvD083vX765uE
13+
eu4l2+8SvY4mT3cONovntLGsLu+v1SAbq6uQh++XGAECgYEA39+y/MUrZuW7curf
14+
NEIlfk8sx2gDpKQeuea4Ff1LnQE6UKSFAZf1CbRrfef1zgjjw5zAWpXEHdItwvFw
15+
I6vvDjvf+ptTa/ZNdQfvfbK1YZwTo6GX1viIc/yiWaRHSHjSMwP2d00P8dKHq+nt
16+
uHBN0G+lfUsvMbdy1rZLB0bijAECgYEAwGXMtR6vE2KY3eH7OI0Tdjttxf52GfzJ
17+
OCXBA4xMEYuw9Mh2wdz1iIDQOX5lq2Sl5I8z16NMKqIHQ766WL75mSWo7sjThqNc
18+
eNmjb8oYmztcfTFB3e+HSJQoGc5m6k+X52tBC0W/+NHna8tUJVpAe/VpKRu8jBLu
19+
YDbSuwIlP7sCgYAD360LLqY3m5YIwQOntdVMQDZ4JNabTLOzZ8ibqMxcJR9LMe2T
20+
P3vf9R0/Cnp4XDMEuXuilaDVG0PrcZ4NH/Z8+pA/l9xzq8lfUwnT1PnKfJbiZ/Nm
21+
ptpFl4N/pZYOLPkGJPVozw6NkqUCVoPkgxz1lFj6uAhTBeeYy4K014coAQKBgE/H
22+
Jn4HziLkpGyE8u29Gc/Rzq/l1sTp2+oLRaCaAUTZPrQRl6TFYY6Lk0vzzGaoYl2G
23+
v8FvtfqLmyWNJan87nSBeC4jWgqfHI4D+NA25cMgdzZ2QVCsrNT8kjA5NNV90Ygl
24+
IiBxeKvNJf+9nROr+8cquMNR+/m9M9jzgqgGuLlXAoGAByAFK57hBTUiTNxXz0oF
25+
VzgU4WD/6Kx8lyXHT3XXUeN6OYn4Xfhulow2PDWeW0T/iGUOXSvlUB3lr/wtxk4y
26+
q51G8HfoVwnPvZGOM6n1UUo4gjJbhP29J7NQW1gJ0514e+qHae6AtWqI/DaLbdGu
27+
EfQ1KLUe6ocgWChCit3Ty08=
2828
-----END PRIVATE KEY-----

mosquitto/certs/ca.pem

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
-----BEGIN CERTIFICATE-----
2-
MIIDTjCCAjYCCQCPElN3YLaKpDANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJV
2+
MIIDTjCCAjYCCQDryv0dPuX+xTANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJV
33
SzESMBAGA1UECAwJRWRpbmJ1cmdoMRIwEAYDVQQHDAlFZGluYnVyZ2gxEDAOBgNV
44
BAoMB01RVFROSU8xCzAJBgNVBAsMAkNBMRMwEQYDVQQDDApzb3RvLmNvZGVzMB4X
5-
DTIxMTEwNDExMDkyNFoXDTIyMTEwNDExMDkyNFowaTELMAkGA1UEBhMCVUsxEjAQ
5+
DTIyMTIwMzA3NTQ0N1oXDTIzMTIwMzA3NTQ0N1owaTELMAkGA1UEBhMCVUsxEjAQ
66
BgNVBAgMCUVkaW5idXJnaDESMBAGA1UEBwwJRWRpbmJ1cmdoMRAwDgYDVQQKDAdN
77
UVRUTklPMQswCQYDVQQLDAJDQTETMBEGA1UEAwwKc290by5jb2RlczCCASIwDQYJ
8-
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMMPGWsv/CFKHjwMVmGuV8CHHmJ93S/V
9-
GoFgUsX8OID3/9c+wPhFFRvyhk6puUUwNZZ0RGe9dFP52UEg+gD7mKU3dtWJN+eG
10-
6wLFLk0DhZortEhvOTN/848yyuRqgsYVbKYE2Uy+lSk8CMNIAtqF+k2wPnmk/EAM
11-
/43/B/TWX+6/vE+Kw5KoNgwUybky98ryj4srul9ICFm0tKjmq5GcC8OpIPb/8Hwn
12-
Vppk79fxsUuPbhBuaA3ERNMbH9c6iyophd4bz9ouoeL7aHWjS0r5B939j9g9eaph
13-
DG+CRZD6sn8JrdQhp+yjs0psT9WXhaAmo2XhYPo0AWhtMSrXO3YLoG8CAwEAATAN
14-
BgkqhkiG9w0BAQsFAAOCAQEAStVD06Pb0+NHS1gunO+bkmNjHttDXS12j1K2fGFI
15-
xSjPyNMxsPxvWh6mfzT1eRwiGz+b/+aFG7aZsl/o8ZBS6hfcuxG33ljcfljbhQgM
16-
0jLaRAwogcfO89Ktg822ZujbLFr3wxfqu/n4mlovZuZq6iLNKRqVot3ibXK+8XRL
17-
apAVVHeTHb2d25HCap/rHHCrMXenTnMyAj/uByc98zhWnn2KUfH58yXjztjnLQSO
18-
0CfTdkUspYqNI2oJ/mQM6jm9jpKHjYUQh9CkznXsMVXTSXK7nVNZo/1dDeHVXwUS
19-
oSChl2SendYSlxBO3dOwnXyxHWpYmqK1DqCdkqUJqFqB2A==
8+
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKhAzIPYOqL6sGf4bgpPJK7BUbJp8Bd+
9+
cYKZR3I7tHPcAK2FaeH1aKPulO/C6antTgI0QOJhrpXw/eXzDkAieU4jAyEb2jWi
10+
rTcJQeeIeYPPOmTjuHR36gX9nxpFN7uI19jB9w+9mMVUG8ie4mqALZoSTzXMGjil
11+
SLFtYddU5eZZy3YFT3Spvhlx4KLpz0AXnyifyCvtLyHDHqsIV2tvvXes0Iti9TBM
12+
KWrjQOli8qgJGc6v78qOhgQLOqL50JwQEUvcqyeho9O3FHEMtpFQfTWt/Q4Xc1hg
13+
8B8chJl1xs3io20quDubenk/Nvc71kXCs/ECa1IukaJXIMWzU8YVg7sCAwEAATAN
14+
BgkqhkiG9w0BAQsFAAOCAQEAUrdJEu8taDl/lLtm+jaj6WnIR9o4ir3tjmqFj5Tg
15+
1MKDuZa38MRO07f3tyued7FW5hFUooaHbieoRyYvkbLnQSszPreg9Gt9KolDTrKr
16+
ZZP0blEKi/fsWn9G2UwEZPvB+F/qNmo/KwkDoNl14sRpyujY0nrOSA49o4f8EYuH
17+
x4Qc9EEkJXpccj/KWT0wuNw+a10ASzuaCNWlHesDwFPutbNvl9Wu8fcyYfyZEdqc
18+
/jUJx4iUuoOEHFvo3PaAPjlxme2Go+3iAsXjmfx91bSup3NFkWuUUKJUaHVIJWsl
19+
TEYqcTtKdbG1fyUMVRcFc5ZBJ0/8pw2Q2kCmPSKhkAmlQA==
2020
-----END CERTIFICATE-----

mosquitto/certs/ca.srl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
C0BAD048C3DEF2BE
1+
C0BAD048C3DEF2C0

mosquitto/certs/client.csr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
MIICsjCCAZoCAQAwbTELMAkGA1UEBhMCVUsxEjAQBgNVBAgMCUVkaW5idXJnaDES
33
MBAGA1UEBwwJRWRpbmJ1cmdoMRAwDgYDVQQKDAdNUVRUTklPMQ8wDQYDVQQLDAZD
44
bGllbnQxEzARBgNVBAMMCnNvdG8uY29kZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IB
5-
DwAwggEKAoIBAQCkhVbHeMhe/hon1GfspFWTR8R0HGbuQceP0n043V3249Bvoxr7
6-
elNo7y7Z783dF0qV12mTnaZWgApEHYiN4aPODjU0ijlVskI3mQ7PmkJnO0DogpZd
7-
jT3dgWx6SBErnjbFhy4mxomB9bebqwkbJGjn37mt7n9ii5bWNyG1+MRR/Qod75as
8-
zpfhXkR+/lY3MhPSRCe/4BOltvuJzlPr3BJIKjCyf+OtJMelxyfWP5NGRQ0FUH+m
9-
RyD3TvXawtGdad8jHWkq+UAOcoPQOXnQNAxqPETzQb8cXbk51FTYuPs2YhxG/sNk
10-
1+kGWVBNS1Dutn8t7vij3E7ELFXf9P2B0v53AgMBAAGgADANBgkqhkiG9w0BAQsF
11-
AAOCAQEAlnictoayWZ6fD4TEuM+eMSw7ojiEU5MEc8KBDfB9sqtwuk/LL7peR604
12-
O4vgMehMj3uy+pZV3D+3f4zOm+BpDEdp0n+oyCrnsfqK4tfWciVDUJ6/WeaAei5l
13-
+80OftPveV22RCWnkmSnaOsUdaPLiQ9V/sZUR1dg2jWjMRTBr6QHc6sHUpF8mWWs
14-
5pOqiOkxBJq/vorjk40H99hiMMPPnhQ6xzr1JbWw9vkG7Ku/tbcV+bN2ML2qQ0nm
15-
nz8sBTKyex23gJ7Y5nYBE3w5wrOGG54IKMG1P+f1C+DiN8ZVrk9lWXzh9DRhJSFw
16-
nKO7PQU2mXZmKMYi89KcEbmALdUICg==
5+
DwAwggEKAoIBAQCsJzHV2ISidmxNeaopQp9lf0rDWhzo1Q7KqUt9U5mM7l43zlGL
6+
+jtSHwCD23LATsKB3lXCd4VKWc2dAlks2rN0p8KCSoSeWvxLyuiBEuW1yk7dKSfF
7+
RhBwZkP3qGo3Rk4yq9UrTvs5u4eP+kQXt4VfaF9eBIeVjWaZr4ec9o05XNZpmHX5
8+
IzZikDAoBtiSARUgZ293G3BYC1Xyqi9hMKJ7AvDd2+va0iTBnc58z/M2SkwMdr1H
9+
bJH7Nj1mqGnDImOKqmOJOahH2TFSJ56zFdPe2uicW7dUxWYbZl4PmBmeorrC4sYA
10+
4m3V4tlvXlQ/qeCmEjEGXGMhQ9wJ3L5XmBhVAgMBAAGgADANBgkqhkiG9w0BAQsF
11+
AAOCAQEAXV6zAMYanGT2JCa1PgXM4VV8Ycg5MlaF0fvCVP9lQhquPhegsoA2b4HX
12+
fftz8RUd7fevmjmrbyb4sn7ftPPBNbu4T/thvshtLyWU3h8wsRRbObVOKhXGW+dV
13+
pFOTkW8Ixxvd/FkETWG4DcS4wcUg90bTjidLgwVOLlFyA7Zw6HCeQ3So/RUGUWs9
14+
ZZe6jxW9B39I44RU0D70h63Ajozavkx3SEhBqIrePJxs0qHM+jwZEYH4FFhP/l/Z
15+
Y6Np/5qGc8iuIvESeUTcNtPOJNhDW12TCuMBYUq2UtEdemNigJ3ei5sWSlQozMU+
16+
AVmG7mV3nusIKxhI0Zr9yWdDB27Kew==
1717
-----END CERTIFICATE REQUEST-----

mosquitto/certs/client.key

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
-----BEGIN PRIVATE KEY-----
2-
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCkhVbHeMhe/hon
3-
1GfspFWTR8R0HGbuQceP0n043V3249Bvoxr7elNo7y7Z783dF0qV12mTnaZWgApE
4-
HYiN4aPODjU0ijlVskI3mQ7PmkJnO0DogpZdjT3dgWx6SBErnjbFhy4mxomB9beb
5-
qwkbJGjn37mt7n9ii5bWNyG1+MRR/Qod75aszpfhXkR+/lY3MhPSRCe/4BOltvuJ
6-
zlPr3BJIKjCyf+OtJMelxyfWP5NGRQ0FUH+mRyD3TvXawtGdad8jHWkq+UAOcoPQ
7-
OXnQNAxqPETzQb8cXbk51FTYuPs2YhxG/sNk1+kGWVBNS1Dutn8t7vij3E7ELFXf
8-
9P2B0v53AgMBAAECggEARwPrdoTzcNWccq7kASjaa42iBkCwSY4JV1KTjPU49zZV
9-
JasxHXYrBPOhtJ8nrJS+NDncr8RwJYx1YfuhkyTf8TT+0GQN5ajhnmAqHYDHwwm3
10-
teWQhGdQWgngylPLXZmYqOD2EfTHLFrlW4OTlay8v8I5wxNc1yvL+0GnAoaUL5Mp
11-
/iOahhKFlblAQgX6/5HwdCUq0KPdQk72brTO3v1clygA7+FZnTio8gUTUrOxGnkg
12-
QTyTs4Yghd0RjODkdc7S6WztmOES/fxOXv/k/zKxeGFgbSGhHpEB0HiayOJ9KOL7
13-
qMC8ANCuFQeXAaXKuDyB+nHou7DjeZ9sZnqa8umEyQKBgQDUvJhLyPY62DefC1Nu
14-
x/EV+jSmSPJBjHrFUQC1ZlDwgDsF7bKNveGGjFkEVDLhrvvIPFIxqqD+KuLnp7DM
15-
R0mULAvLImt19b0kxUYnzmtXLBpfFe5lIkpID4fG4kxjwnFEWqgmDIJaPrnVUIpk
16-
1h77vk4rkUBaGlCY+itbDaV+NQKBgQDF+o1I3an6oTgvLpmZ7hnDESgxZ+H1MNfd
17-
YJm7xXUp5xheTnNjgO3l+WduEYdOeIZoxYLHtyDIYrEk8PXK44MiLU27jfIfNMJT
18-
rIRbIMNajGS62RATWBbug5FvyYujz6Dp6nh4iTRBtU0A3N/LsJD6T2LNOJor5ZFL
19-
/1yA24lPewKBgEkESkmIumrMF5sxKfvWCHuAm12PoAa7js/204VvjsxdVuTcBvL7
20-
f1LNDSidNbGce7LocVW2uPdEBQl51wbmWOzQiWO5dqTQKZFbXI8BHHqZGpwUTPTN
21-
Zi2Blxq+RXXgITxS2W/lzz/mU6ZRtI6Tp6LEWNQ/UJUcfxlilEr2Th0ZAoGAC6z4
22-
EhkIgkBpyNaNtndFS6zCWw+OUuB7ipG830cI3tzDIiSsR2z+Grb3s5UTDryq6Jjl
23-
WpPhOhAf9FbFmB6MyEI1uF7prY91+mtNLvairr9i3WYZvZpPV+eodxhCxPlkuwbZ
24-
7fnhfBKOJQPhquiR1EFESWgSJ46VYA8CTJMl6OsCgYEAoaCmNbESBS9OyG0DnyW0
25-
bRhyg7I7UyoInZFWMrcqOLXHcdXK7UuF1fiPHJznyRcitdpRM96q7n3A3IWmkld5
26-
KmkBrwxnXDtzUdJeK4knfysLVhSYXKH3mfD1xhEZEn23VjcyDZeVAFfvEXnS5e3l
27-
pjA4+2WH5mqNO0lv5MeTePI=
2+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCsJzHV2ISidmxN
3+
eaopQp9lf0rDWhzo1Q7KqUt9U5mM7l43zlGL+jtSHwCD23LATsKB3lXCd4VKWc2d
4+
Alks2rN0p8KCSoSeWvxLyuiBEuW1yk7dKSfFRhBwZkP3qGo3Rk4yq9UrTvs5u4eP
5+
+kQXt4VfaF9eBIeVjWaZr4ec9o05XNZpmHX5IzZikDAoBtiSARUgZ293G3BYC1Xy
6+
qi9hMKJ7AvDd2+va0iTBnc58z/M2SkwMdr1HbJH7Nj1mqGnDImOKqmOJOahH2TFS
7+
J56zFdPe2uicW7dUxWYbZl4PmBmeorrC4sYA4m3V4tlvXlQ/qeCmEjEGXGMhQ9wJ
8+
3L5XmBhVAgMBAAECggEAda5VYtmf0W8imdORfqMMU1WwxdnT6VW7xs3zzLhZPv2z
9+
anKfTBDCfGC0+W4KA2vTivNxrH4Hn8vDwpDYZNEb26LSVD6caaPI1Abg6VsBrEOf
10+
pY98oF5E3pEJ5UI7WY215u2PywsysUSAZuutoIjTo2S1zI9MH++JM4XKLoJcB9lO
11+
yJuYDKzaUwqxw6oj/FvKQ/UL5ABk9KxV7JkMSMmn2qLi3Yp5hH0hX4eU6hZagsuG
12+
Jz3kjMq8WvKy8HdsWCVt/M1uFTKbbRH6MSTP6FiYJ+inpD3HO7TvKen8XEzjdHaq
13+
QZChvMrT0rJXcD/WNgphGDBsU+uoc4/UZgp2mqD0AQKBgQDjdKg7T7H9WeWAchmD
14+
k3h5pLR+6BBUUHfFInD1wvC2XDOIcY+Ok7qq/s52UxADnUhBoBV3syyuBImoEEsm
15+
xxsMtkAmHgwb3gX231P/YqN09AQzzW9WmEts7zU/VfRBz37Z7sLQszLir/vGv7Yg
16+
Mq36w6qTx8ZoKqcmesQ9Ah3T0wKBgQDBwdyo4KMaUIA8bbjO7D/K2DqHdKRK50t1
17+
m6hxYQzPYyMrtkd6cwfmNt+AeTpshzyA/YuglLX2w+/LoLpaqr0Qar/wDhmFpkY0
18+
NqwegfPUrKmicupNBl9lnQ3K8M9dSYFTV3IKzcv5bNDjrVRq9zh5b3hpSckzeHwd
19+
es4Z/ZJSNwKBgB2POpHCsKnxNd80dNZhouWEHyTi+cRLVNVcvXti4y9/2f6ga3ym
20+
/DpetOwxrUIa/ZnxuPh+Y48V7eHWhD284GoNgVayzvYMK5BCw8LLydxYHfexegex
21+
8RNuHuhlPkITOjQOUGkY8ML/BeR1Y7DZhTyykwdzjfhZmrFogPpAvSmbAoGAGcJ1
22+
XLpo1NHJCr+np1L/dC9lMKcQRKkVfjBQp6o4csYCYghc3mm2riOzeTgkzVL5d0i+
23+
LH445vLLya23uOAkPK+EjxzAxeUCRmTSY0fxq9+8uc0/WzgyrKbBs65qU0O3fuYM
24+
UmVj7ehKqUpdA8+UYYixYIYfyskE70JpbkkpD+cCgYAK/etRGMrH3GDdpu8Syc5J
25+
hIipR/jgWWMC+7JrlDMa86ngp0mv7bft1W7TzdNg5QntmhKSiWmm59R636kfE0At
26+
U22ettaxlAGsjM+6qR8QwTZqZYVR+z3PggZinjyXY3GClspOhR1Opu0vV1HvkyqX
27+
OhmWpBt7YpbBj0NQs02l9A==
2828
-----END PRIVATE KEY-----

0 commit comments

Comments
 (0)