Skip to content

Commit c5ac824

Browse files
Increase default multipart size to 128MiB (#1112)
1 parent da91b3b commit c5ac824

12 files changed

+114
-52
lines changed

.travis.yml

+13-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ os:
66

77
env:
88
- ARCH=x86_64
9-
- ARCH=i686
109

1110
go:
1211
- 1.12.x
@@ -22,7 +21,17 @@ addons:
2221
packages:
2322
- devscripts
2423

24+
before_install:
25+
- curl -O https://dl.minio.io/server/minio/release/linux-amd64/minio && chmod +x ./minio
26+
- sudo cp testcerts/public.crt /usr/local/share/ca-certificates/
27+
- sudo update-ca-certificates
28+
- MINIO_ACCESS_KEY=minio MINIO_SECRET_KEY=minio123 ./minio server --compat --quiet --certs-dir testcerts data 2>&1 > minio.log &
29+
2530
script:
26-
- diff -au <(gofmt -d .) <(printf "")
27-
- diff -au <(licensecheck --check '.go$' --recursive --lines 0 * | grep -v -w 'Apache (v2.0)') <(printf "")
28-
- make
31+
- diff -au <(gofmt -d .) <(printf "")
32+
- diff -au <(licensecheck --check '.go$' --recursive --lines 0 * | grep -v -w 'Apache (v2.0)') <(printf "")
33+
- make
34+
35+
addons:
36+
artifacts:
37+
- minio.log

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ vet:
88
@GO111MODULE=on go vet ./...
99

1010
test:
11-
@GO111MODULE=on SERVER_ENDPOINT=play.min.io:9000 ACCESS_KEY=Q3AM3UQ867SPQQA43P2F SECRET_KEY=zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG ENABLE_HTTPS=1 MINT_MODE=full go test -race -v ./...
11+
@GO111MODULE=on SERVER_ENDPOINT=localhost:9000 ACCESS_KEY=minio SECRET_KEY=minio123 ENABLE_HTTPS=1 MINT_MODE=full go test -race -v ./...
1212

1313
examples:
1414
@mkdir -p /tmp/examples && for i in $(echo examples/s3/*); do go build -o /tmp/examples/$(basename ${i:0:-3}) ${i}; done
@@ -17,4 +17,4 @@ docs:
1717
@(cd docs; GO111MODULE=on go build validator.go && ./validator -m ../docs/API.md -t checker.go.tpl)
1818

1919
functional-test:
20-
@GO111MODULE=on SERVER_ENDPOINT=play.min.io:9000 ACCESS_KEY=Q3AM3UQ867SPQQA43P2F SECRET_KEY=zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG ENABLE_HTTPS=1 MINT_MODE=full go run functional_tests.go
20+
@GO111MODULE=on SERVER_ENDPOINT=localhost:9000 ACCESS_KEY=minio SECRET_KEY=minio123 ENABLE_HTTPS=1 MINT_MODE=full go run functional_tests.go

api-put-object-common.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func isReadAt(reader io.Reader) (ok bool) {
6464
// object storage it will have the following parameters as constants.
6565
//
6666
// maxPartsCount - 10000
67-
// minPartSize - 64MiB
67+
// minPartSize - 128MiB
6868
// maxMultipartPutObjectSize - 5TiB
6969
//
7070
func optimalPartInfo(objectSize int64, configuredPartSize uint64) (totalPartsCount int, partSize int64, lastPartSize int64, err error) {

api-put-object-streaming.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ type uploadPartReq struct {
7575
Part *ObjectPart // Size of the part uploaded.
7676
}
7777

78-
// putObjectMultipartFromReadAt - Uploads files bigger than 64MiB.
78+
// putObjectMultipartFromReadAt - Uploads files bigger than 128MiB.
7979
// Supports all readers which implements io.ReaderAt interface
8080
// (ReadAt method).
8181
//

api-put-object.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ func (a completedParts) Less(i, j int) bool { return a[i].PartNumber < a[j].Part
124124
//
125125
// You must have WRITE permissions on a bucket to create an object.
126126
//
127-
// - For size smaller than 64MiB PutObject automatically does a
127+
// - For size smaller than 128MiB PutObject automatically does a
128128
// single atomic Put operation.
129-
// - For size larger than 64MiB PutObject automatically does a
129+
// - For size larger than 128MiB PutObject automatically does a
130130
// multipart Put operation.
131131
// - For size input as -1 PutObject does a multipart Put operation
132132
// until input stream reaches EOF. Maximum object size that can
@@ -167,7 +167,7 @@ func (c Client) putObjectCommon(ctx context.Context, bucketName, objectName stri
167167
return c.putObjectNoChecksum(ctx, bucketName, objectName, reader, size, opts)
168168
}
169169

170-
// For all sizes greater than 64MiB do multipart.
170+
// For all sizes greater than 128MiB do multipart.
171171
return c.putObjectMultipartStream(ctx, bucketName, objectName, reader, size, opts)
172172
}
173173

api_unit_test.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ func TestPartSize(t *testing.T) {
120120
if err != nil {
121121
t.Fatal("Error: ", err)
122122
}
123-
if totalPartsCount != 79 {
124-
t.Fatalf("Error: expecting total parts count of 79: got %v instead", totalPartsCount)
123+
if totalPartsCount != 40 {
124+
t.Fatalf("Error: expecting total parts count of 40: got %v instead", totalPartsCount)
125125
}
126-
if partSize != 67108864 {
127-
t.Fatalf("Error: expecting part size of 67108864: got %v instead", partSize)
126+
if partSize != 134217728 {
127+
t.Fatalf("Error: expecting part size of 134217728: got %v instead", partSize)
128128
}
129129
if lastPartSize != 9437184 {
130130
t.Fatalf("Error: expecting last part size of 9437184: got %v instead", lastPartSize)
@@ -146,14 +146,14 @@ func TestPartSize(t *testing.T) {
146146
if err != nil {
147147
t.Fatal("Error:", err)
148148
}
149-
if totalPartsCount != 9103 {
150-
t.Fatalf("Error: expecting total parts count of 9103: got %v instead", totalPartsCount)
149+
if totalPartsCount != 8192 {
150+
t.Fatalf("Error: expecting total parts count of 8192: got %v instead", totalPartsCount)
151151
}
152-
if partSize != 603979776 {
153-
t.Fatalf("Error: expecting part size of 603979776: got %v instead", partSize)
152+
if partSize != 671088640 {
153+
t.Fatalf("Error: expecting part size of 671088640: got %v instead", partSize)
154154
}
155-
if lastPartSize != 134217728 {
156-
t.Fatalf("Error: expecting last part size of 134217728: got %v instead", lastPartSize)
155+
if lastPartSize != 671088640 {
156+
t.Fatalf("Error: expecting last part size of 671088640: got %v instead", lastPartSize)
157157
}
158158
}
159159

constants.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ package minio
2323
// a part in a multipart upload may not be uploaded.
2424
const absMinPartSize = 1024 * 1024 * 5
2525

26-
// minPartSize - minimum part size 64MiB per object after which
26+
// minPartSize - minimum part size 128MiB per object after which
2727
// putObject behaves internally as multipart.
28-
const minPartSize = 1024 * 1024 * 64
28+
const minPartSize = 1024 * 1024 * 128
2929

3030
// maxPartsCount - maximum number of parts for a single multipart session.
3131
const maxPartsCount = 10000

docs/API.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ if err != nil {
528528

529529
<a name="PutObject"></a>
530530
### PutObject(bucketName, objectName string, reader io.Reader, objectSize int64,opts PutObjectOptions) (n int, err error)
531-
Uploads objects that are less than 64MiB in a single PUT operation. For objects that are greater than 64MiB in size, PutObject seamlessly uploads the object as parts of 64MiB or more depending on the actual file size. The max upload size for an object is 5TB.
531+
Uploads objects that are less than 128MiB in a single PUT operation. For objects that are greater than 128MiB in size, PutObject seamlessly uploads the object as parts of 128MiB or more depending on the actual file size. The max upload size for an object is 5TB.
532532

533533
__Parameters__
534534

@@ -869,7 +869,7 @@ if err != nil {
869869
### FPutObject(bucketName, objectName, filePath, opts PutObjectOptions) (length int64, err error)
870870
Uploads contents from a file to objectName.
871871

872-
FPutObject uploads objects that are less than 64MiB in a single PUT operation. For objects that are greater than the 64MiB in size, FPutObject seamlessly uploads the object in chunks of 64MiB or more depending on the actual file size. The max upload size for an object is 5TB.
872+
FPutObject uploads objects that are less than 128MiB in a single PUT operation. For objects that are greater than the 128MiB in size, FPutObject seamlessly uploads the object in chunks of 128MiB or more depending on the actual file size. The max upload size for an object is 5TB.
873873

874874
__Parameters__
875875

docs/zh_CN/API.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ if err != nil {
550550

551551
<a name="PutObject"></a>
552552
### PutObject(bucketName, objectName string, reader io.Reader, objectSize int64,opts PutObjectOptions) (n int, err error)
553-
当对象小于64MiB时,直接在一次PUT请求里进行上传。当大于64MiB时,根据文件的实际大小,PutObject会自动地将对象进行拆分成64MiB一块或更大一些进行上传。对象的最大大小是5TB。
553+
当对象小于128MiB时,直接在一次PUT请求里进行上传。当大于128MiB时,根据文件的实际大小,PutObject会自动地将对象进行拆分成128MiB一块或更大一些进行上传。对象的最大大小是5TB。
554554

555555
__参数__
556556

@@ -889,7 +889,7 @@ if err != nil {
889889
### FPutObject(bucketName, objectName, filePath, opts PutObjectOptions) (length int64, err error)
890890
将filePath对应的文件内容上传到一个对象中。
891891

892-
当对象小于64MiB时,FPutObject直接在一次PUT请求里进行上传。当大于64MiB时,根据文件的实际大小,FPutObject会自动地将对象进行拆分成64MiB一块或更大一些进行上传。对象的最大大小是5TB。
892+
当对象小于128MiB时,FPutObject直接在一次PUT请求里进行上传。当大于128MiB时,根据文件的实际大小,FPutObject会自动地将对象进行拆分成128MiB一块或更大一些进行上传。对象的最大大小是5TB。
893893

894894
__参数__
895895

functional_tests.go

+25-25
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ var dataFileMap = map[string]int{
264264
"datafile-5-MB": 5 * humanize.MiByte,
265265
"datafile-6-MB": 6 * humanize.MiByte,
266266
"datafile-11-MB": 11 * humanize.MiByte,
267-
"datafile-65-MB": 65 * humanize.MiByte,
267+
"datafile-129-MB": 129 * humanize.MiByte,
268268
}
269269

270270
func isFullMode() bool {
@@ -531,8 +531,8 @@ func testPutObjectReadAt() {
531531
return
532532
}
533533

534-
bufSize := dataFileMap["datafile-65-MB"]
535-
var reader = getDataReader("datafile-65-MB")
534+
bufSize := dataFileMap["datafile-129-MB"]
535+
var reader = getDataReader("datafile-129-MB")
536536
defer reader.Close()
537537

538538
// Save the data
@@ -641,8 +641,8 @@ func testPutObjectWithMetadata() {
641641
return
642642
}
643643

644-
bufSize := dataFileMap["datafile-65-MB"]
645-
var reader = getDataReader("datafile-65-MB")
644+
bufSize := dataFileMap["datafile-129-MB"]
645+
var reader = getDataReader("datafile-129-MB")
646646
defer reader.Close()
647647

648648
// Save the data
@@ -1308,7 +1308,7 @@ func testFPutObjectMultipart() {
13081308
}
13091309

13101310
// Upload 4 parts to utilize all 3 'workers' in multipart and still have a part to upload.
1311-
var fileName = getMintDataDirFilePath("datafile-65-MB")
1311+
var fileName = getMintDataDirFilePath("datafile-129-MB")
13121312
if fileName == "" {
13131313
// Make a temp file with minPartSize bytes of data.
13141314
file, err := ioutil.TempFile(os.TempDir(), "FPutObjectTest")
@@ -1317,7 +1317,7 @@ func testFPutObjectMultipart() {
13171317
return
13181318
}
13191319
// Upload 2 parts to utilize all 3 'workers' in multipart and still have a part to upload.
1320-
if _, err = io.Copy(file, getDataReader("datafile-65-MB")); err != nil {
1320+
if _, err = io.Copy(file, getDataReader("datafile-129-MB")); err != nil {
13211321
logError(testName, function, args, startTime, "", "Copy failed", err)
13221322
return
13231323
}
@@ -1328,7 +1328,7 @@ func testFPutObjectMultipart() {
13281328
fileName = file.Name()
13291329
args["fileName"] = fileName
13301330
}
1331-
totalSize := dataFileMap["datafile-65-MB"]
1331+
totalSize := dataFileMap["datafile-129-MB"]
13321332
// Set base object name
13331333
objectName := bucketName + "FPutObject" + "-standard"
13341334
args["objectName"] = objectName
@@ -1426,7 +1426,7 @@ func testFPutObject() {
14261426

14271427
// Upload 3 parts worth of data to use all 3 of multiparts 'workers' and have an extra part.
14281428
// Use different data in part for multipart tests to check parts are uploaded in correct order.
1429-
var fName = getMintDataDirFilePath("datafile-65-MB")
1429+
var fName = getMintDataDirFilePath("datafile-129-MB")
14301430
if fName == "" {
14311431
// Make a temp file with minPartSize bytes of data.
14321432
file, err := ioutil.TempFile(os.TempDir(), "FPutObjectTest")
@@ -1436,7 +1436,7 @@ func testFPutObject() {
14361436
}
14371437

14381438
// Upload 3 parts to utilize all 3 'workers' in multipart and still have a part to upload.
1439-
if _, err = io.Copy(file, getDataReader("datafile-65-MB")); err != nil {
1439+
if _, err = io.Copy(file, getDataReader("datafile-129-MB")); err != nil {
14401440
logError(testName, function, args, startTime, "", "File copy failed", err)
14411441
return
14421442
}
@@ -1448,7 +1448,7 @@ func testFPutObject() {
14481448
defer os.Remove(file.Name())
14491449
fName = file.Name()
14501450
}
1451-
totalSize := dataFileMap["datafile-65-MB"]
1451+
totalSize := dataFileMap["datafile-129-MB"]
14521452

14531453
// Set base object name
14541454
function = "FPutObject(bucketName, objectName, fileName, opts)"
@@ -2706,9 +2706,9 @@ func testSSECEncryptedGetObjectReadSeekFunctional() {
27062706
}
27072707
}()
27082708

2709-
// Generate 65MiB of data.
2710-
bufSize := dataFileMap["datafile-65-MB"]
2711-
var reader = getDataReader("datafile-65-MB")
2709+
// Generate 129MiB of data.
2710+
bufSize := dataFileMap["datafile-129-MB"]
2711+
var reader = getDataReader("datafile-129-MB")
27122712
defer reader.Close()
27132713

27142714
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@@ -2894,9 +2894,9 @@ func testSSES3EncryptedGetObjectReadSeekFunctional() {
28942894
}
28952895
}()
28962896

2897-
// Generate 65MiB of data.
2898-
bufSize := dataFileMap["datafile-65-MB"]
2899-
var reader = getDataReader("datafile-65-MB")
2897+
// Generate 129MiB of data.
2898+
bufSize := dataFileMap["datafile-129-MB"]
2899+
var reader = getDataReader("datafile-129-MB")
29002900
defer reader.Close()
29012901

29022902
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@@ -3072,9 +3072,9 @@ func testSSECEncryptedGetObjectReadAtFunctional() {
30723072
return
30733073
}
30743074

3075-
// Generate 65MiB of data.
3076-
bufSize := dataFileMap["datafile-65-MB"]
3077-
var reader = getDataReader("datafile-65-MB")
3075+
// Generate 129MiB of data.
3076+
bufSize := dataFileMap["datafile-129-MB"]
3077+
var reader = getDataReader("datafile-129-MB")
30783078
defer reader.Close()
30793079

30803080
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@@ -3263,9 +3263,9 @@ func testSSES3EncryptedGetObjectReadAtFunctional() {
32633263
return
32643264
}
32653265

3266-
// Generate 65MiB of data.
3267-
bufSize := dataFileMap["datafile-65-MB"]
3268-
var reader = getDataReader("datafile-65-MB")
3266+
// Generate 129MiB of data.
3267+
bufSize := dataFileMap["datafile-129-MB"]
3268+
var reader = getDataReader("datafile-129-MB")
32693269
defer reader.Close()
32703270

32713271
objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "")
@@ -8561,8 +8561,8 @@ func testPutObjectNoLengthV2() {
85618561
objectName := bucketName + "unique"
85628562
args["objectName"] = objectName
85638563

8564-
bufSize := dataFileMap["datafile-65-MB"]
8565-
var reader = getDataReader("datafile-65-MB")
8564+
bufSize := dataFileMap["datafile-129-MB"]
8565+
var reader = getDataReader("datafile-129-MB")
85668566
defer reader.Close()
85678567
args["size"] = bufSize
85688568

testcerts/private.key

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCwUyKC2VOXy2+8
3+
gMQkRrDJ4aA7K5pgj6LHWu25GeY93x+8DLFyQ9BhoaMcAbs2Cmw91rONDrZ0gNql
4+
yi5JX8t+iiVH8o6dcq6W8jNLnOw0GMNJ2/E1Ckfe5ktkn9synSSwMdnFp3cDk7Hb
5+
2j6IiWrb+PXb7VGL47kDrG59iKQ350MiB3PNpd1ulHbi2m2ZC3WyoTTzlgeTXiXa
6+
zhBIX4wsGVYs6RzS1bTZFBq05dIPNMJCRDVBSBYAAVuBxKjh4xvhC6j0rTCCK8uJ
7+
752KioW4Y0VAEv6yUC4Ht6D9Jcj7gODTgb2irWSCNXFH+pZaI6wWlS8pPiL6iljY
8+
P3kBeFiLAgMBAAECggEAKM20SM9+FryPSPILcdGiC7XY3JiEix/yLWwPYyxpKZw+
9+
vce6MJUc3dsH4e1Mo37Z+Z17w4LKGj/PWVpmR7iRYOEbK4EoG6t0V54I3NCdoJiy
10+
aJ8rPHj6lMx6WfjcQuQ2n0eJ+8F7OyqsmBHzMqmKPwln69MJcfPq1rzKfOZoCj9p
11+
0oZ+3Iv3roC4uH8peZFooCDUlzJL+8KiybVlemNfklKsHfRmL2vOdFBt+qvit6N/
12+
9JgBTX1mRx1+vqECj+TlVP//k3BTEPNfpIvsLCRN0eBbQcXYzu/gZfHwGnsy5Lxy
13+
HaHNJnmLZMWSCc4iyCK7uN/BHXNUSSh3qqp4wqz0IQKBgQDdGbOuOVdJW4J1yYua
14+
nDLAu2RQqvZTnoz1/b8jcrjS7tS1la5x1IN0Z9/VqTmkfxyHOK9ab1iVlklkIzjP
15+
CmHnadUwr8vrLcdicFpjVLQU3O4ZqGrgiSGIPAotvOfAOuuzMs+r5ElW/MrGq0Pa
16+
/3tGCTIx8JscZZjGhffUNoIGeQKBgQDMKB+flQB9Ajeo1JM4y3DtHbMJ5D2+/qoe
17+
IkM7kN5K85EEpNwA2PMNKL2qthgM9YFU3K6Dj0gxPNsUKg3W7Ff2r+gaj8K+VjU0
18+
VbdhTZANbou8hU551swDUCUgquassMtZJIdZnQ7puwLGK67sZwWlOS6Pe1aqaNc5
19+
nY/MRbemIwKBgEySfykCkNlGCPuUDnZATE91VrudSewRyA3VkGHNdHcQ4bf1m9Gu
20+
YMxqwRl1HxJ6Nz4ZgplWYJ6FyusUS7NgjCGiBIR1DbFoTFoqQROPnUJwdUGLk2Ap
21+
/eP5ryjB+J0ZitGn8kY8rK2kpPGDFN/+hQnvW2PySTXfdbajZP4o1oU5AoGAMiT0
22+
x3yQlyPRSf2Uf5Gwlf0Ceb5+0Ae6/xXJT7sgbmZuyyY3B1pCMIw+MczyEVTHxHFD
23+
x/qMb9OTt9swdQauAGBqcQO4gImqHcWj+hlT9Yied9qCUPjKOVIZHHH9oJL4D1gi
24+
iodCH3SYlNYr69LOFyv5XLKdsdN4caVaqYDCP+MCgYEAwXyCmSml5oCxJeAOrEDC
25+
Yg3vq3Ul9JO1wc8VDXn9+DtnFsuRHm0fTIxBelmis8AjIIq5DcObpk6wGYZwUiTU
26+
LYQU7v0/Azujv9cl10GI8wzYKiRvExZDTn0sp6OKnau735qBUZvsRDqEQQ5n7waZ
27+
xjlGmZyfah17laYZV9aJoHk=
28+
-----END PRIVATE KEY-----

testcerts/public.crt

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEKjCCApKgAwIBAgIRAPVKnAiFmDti207oQPs2VfUwDQYJKoZIhvcNAQELBQAw
3+
VTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMRUwEwYDVQQLDAxoYXJz
4+
aGFAcHJ0c2MxHDAaBgNVBAMME21rY2VydCBoYXJzaGFAcHJ0c2MwHhcNMTkwMTA3
5+
MTE1ODE2WhcNMjkwMTA3MTE1ODE2WjBEMScwJQYDVQQKEx5ta2NlcnQgZGV2ZWxv
6+
cG1lbnQgY2VydGlmaWNhdGUxGTAXBgNVBAsMEGhhcnNoYUBiYWNrc3BhY2UwggEi
7+
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwUyKC2VOXy2+8gMQkRrDJ4aA7
8+
K5pgj6LHWu25GeY93x+8DLFyQ9BhoaMcAbs2Cmw91rONDrZ0gNqlyi5JX8t+iiVH
9+
8o6dcq6W8jNLnOw0GMNJ2/E1Ckfe5ktkn9synSSwMdnFp3cDk7Hb2j6IiWrb+PXb
10+
7VGL47kDrG59iKQ350MiB3PNpd1ulHbi2m2ZC3WyoTTzlgeTXiXazhBIX4wsGVYs
11+
6RzS1bTZFBq05dIPNMJCRDVBSBYAAVuBxKjh4xvhC6j0rTCCK8uJ752KioW4Y0VA
12+
Ev6yUC4Ht6D9Jcj7gODTgb2irWSCNXFH+pZaI6wWlS8pPiL6iljYP3kBeFiLAgMB
13+
AAGjgYUwgYIwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwG
14+
A1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUD575sRLoRt9dCxSRqbVctoEHt3MwLAYD
15+
VR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqG
16+
SIb3DQEBCwUAA4IBgQC7qDRDNAHtfGtQs1UmvqWvHPI7qcBQgAibYq/Fox6X9ia1
17+
weQBfNWEoNOsk97wzbTz81ifXIQ0oV11kWE8EdsbXOf9xeFe9FmDn10d4bGjuMLd
18+
+N3OtGKxLWry2xDYEsVHJZxVxwrf5GK6AJSJj/S837Nil6uRuwjvBVTbxmh1q0nV
19+
x63V8Ag65rLS0fu8msSb64N5UHMCQk6IE+BFHY2gh0lBfZHMdtP4IbeCm756K78/
20+
WMeqjavGA3bqzVTixCHnJ9S2VLk/oQUS6mL869jM8+tN5VeE6Qsr1/Q5h+NaFCJg
21+
Ed5xjT9mmnc3BLsOHflb1dg+rA90Zz9wphgebXbJhRNuuDRv81dtRPTzM+evGRGM
22+
iRKtiDpog+K0HulfX2g4ZQ1dItEjYz+JYgUFJG+yCvBlNZ/WsTrIVcUCFKaG5rUC
23+
aNqvKrSXfbzKQx7V/TtUAeSfRk7TBRn5qh8Pl+MmQQsB0L9hwTdnqTNn057tghu4
24+
3/yIIBpzdWPhQ5uv7Vc=
25+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)