From 1cbccf384b638cf12ca0ea20b012078ffd532e0b Mon Sep 17 00:00:00 2001
From: Vadym Pinchuk <vad.pinchuk@gmail.com>
Date: Thu, 22 Oct 2020 16:40:46 +0300
Subject: [PATCH] Fix: MultipartUpload fix. MalformedXML fix. Types fix.

---
 .gitignore                          |  3 ++
 CHANGELOG.md                        |  7 ++++
 lib/src/minio.dart                  | 52 ++++++++++++++++++-----------
 lib/src/minio_client.dart           |  2 +-
 lib/src/minio_models.dart           |  7 ++--
 lib/src/minio_models_generated.dart |  2 +-
 lib/src/minio_uploader.dart         | 12 ++++---
 lib/src/utils.dart                  | 10 +++---
 pubspec.yaml                        | 18 +++++-----
 9 files changed, 69 insertions(+), 44 deletions(-)

diff --git a/.gitignore b/.gitignore
index 50602ac..56260f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,6 @@ build/
 
 # Directory created by dartdoc
 doc/api/
+
+# IDE directories
+.idea/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3abdb30..8fc5b34 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.1.9
+
+- Updated dependencies
+- Fixed Malformed XML error
+- Fixed Types incompatibility in minio_uploader stream subscription queries
+- Temporarily closed call for search of unfinished uploads (Causes Signature Error)
+
 ## 0.1.8
 
 - Update dependency
diff --git a/lib/src/minio.dart b/lib/src/minio.dart
index bd89bea..b426ec3 100644
--- a/lib/src/minio.dart
+++ b/lib/src/minio.dart
@@ -259,7 +259,7 @@ class Minio {
       method: 'GET',
       bucket: bucket,
       region: 'us-east-1',
-      queries: {'location': null},
+      queries: <String, dynamic>{'location': null},
     );
 
     validate(resp);
@@ -332,11 +332,12 @@ class Minio {
     MinioInvalidObjectNameError.check(object);
 
     final resp = await _client.request(
-        method: 'POST',
-        bucket: bucket,
-        object: object,
-        headers: metaData,
-        resource: 'uploads');
+      method: 'POST',
+      bucket: bucket,
+      object: object,
+      headers: metaData,
+      resource: 'uploads',
+    );
 
     validate(resp, expect: 200);
 
@@ -389,7 +390,7 @@ class Minio {
     MinioInvalidBucketNameError.check(bucket);
     MinioInvalidPrefixError.check(prefix);
 
-    var queries = {
+    var queries = <String, dynamic>{
       'uploads': null,
       'prefix': prefix,
       'delimiter': delimiter,
@@ -486,7 +487,7 @@ class Minio {
     MinioInvalidBucketNameError.check(bucket);
     MinioInvalidPrefixError.check(prefix);
 
-    final queries = <String, String>{};
+    final queries = <String, dynamic>{};
     queries['prefix'] = prefix;
     queries['delimiter'] = delimiter;
 
@@ -539,7 +540,13 @@ class Minio {
 
     do {
       final resp = await listObjectsV2Query(
-          bucket, prefix, continuationToken, delimiter, 1000, startAfter);
+        bucket,
+        prefix,
+        continuationToken,
+        delimiter,
+        1000,
+        startAfter,
+      );
       isTruncated = resp.isTruncated;
       continuationToken = resp.nextContinuationToken;
       yield ListObjectsChunk()
@@ -560,7 +567,7 @@ class Minio {
     MinioInvalidBucketNameError.check(bucket);
     MinioInvalidPrefixError.check(prefix);
 
-    final queries = <String, String>{};
+    final queries = <String, dynamic>{};
     queries['prefix'] = prefix;
     queries['delimiter'] = delimiter;
     queries['list-type'] = '2';
@@ -628,7 +635,7 @@ class Minio {
     String uploadId,
     int marker,
   ) async {
-    var queries = <String, String>{'uploadId': uploadId};
+    var queries = <String, dynamic>{'uploadId': uploadId};
 
     if (marker != null && marker != 0) {
       queries['part-number-marker'] = marker.toString();
@@ -652,7 +659,8 @@ class Minio {
     MinioInvalidBucketNameError.check(bucket);
     if (this.region != null && region != null && this.region != region) {
       throw MinioInvalidArgumentError(
-          'Configured region ${this.region}, requested $region');
+        'Configured region ${this.region}, requested $region',
+      );
     }
 
     region ??= this.region ?? 'us-east-1';
@@ -704,7 +712,8 @@ class Minio {
   Future presignedPostPolicy(PostPolicy postPolicy) async {
     if (_client.anonymous) {
       throw MinioAnonymousRequestError(
-          'Presigned POST policy cannot be generated for anonymous requests');
+        'Presigned POST policy cannot be generated for anonymous requests',
+      );
     }
 
     final region = await getBucketRegion(postPolicy.formData['bucket']);
@@ -797,7 +806,14 @@ class Minio {
 
     final region = await getBucketRegion(bucket);
     final request = _client.getBaseRequest(
-        method, bucket, object, region, resource, reqParams, {});
+      method,
+      bucket,
+      object,
+      region,
+      resource,
+      reqParams,
+      {},
+    );
     return presignSignatureV4(this, request, region, requestDate, expires);
   }
 
@@ -815,7 +831,7 @@ class Minio {
     assert(data != null);
     assert(size >= 0 || size == null);
 
-    metadata = prependXAMZMeta(metadata ?? {});
+    metadata = prependXAMZMeta(metadata ?? <String, String>{});
 
     size ??= maxObjectSize;
     size = _calculatePartSize(size);
@@ -834,10 +850,8 @@ class Minio {
   }
 
   /// Remove all bucket notification
-  Future<void> removeAllBucketNotification(bucket) {
-    return setBucketNotification(
-        bucket, NotificationConfiguration(null, null, null));
-  }
+  Future<void> removeAllBucketNotification(bucket) => setBucketNotification(
+      bucket, NotificationConfiguration(null, null, null));
 
   /// Remove a bucket.
   Future<void> removeBucket(String bucket) async {
diff --git a/lib/src/minio_client.dart b/lib/src/minio_client.dart
index 7ce25ab..7bb8d08 100644
--- a/lib/src/minio_client.dart
+++ b/lib/src/minio_client.dart
@@ -51,7 +51,7 @@ class MinioClient {
   }
 
   final Minio minio;
-  final String userAgent = 'MinIO (Unknown; Unknown) minio-dart/0.1.5';
+  final String userAgent = 'MinIO (Unknown; Unknown) minio-dart/0.1.9';
 
   bool enableSHA256;
   bool anonymous;
diff --git a/lib/src/minio_models.dart b/lib/src/minio_models.dart
index 382e6da..d8e04fe 100644
--- a/lib/src/minio_models.dart
+++ b/lib/src/minio_models.dart
@@ -28,10 +28,9 @@ class CompleteMultipartUpload {
 
   XmlNode toXml() {
     final builder = XmlBuilder();
-    builder.element('CompleteMultipartUpload', nest: () {
-      builder.element('Parts', nest: parts.map((p) => p.toXml()));
-    });
-    return builder.build();
+    builder.element('CompleteMultipartUpload',
+        nest: parts.map((p) => p.toXml()));
+    return builder.buildDocument();
   }
 
   /// Array of CompletedPart data types.
diff --git a/lib/src/minio_models_generated.dart b/lib/src/minio_models_generated.dart
index c042b50..a7da818 100644
--- a/lib/src/minio_models_generated.dart
+++ b/lib/src/minio_models_generated.dart
@@ -439,7 +439,7 @@ class CompletedPart {
 
   XmlNode toXml() {
     final builder = XmlBuilder();
-    builder.element('CompletedPart', nest: () {
+    builder.element('Part', nest: () {
       builder.element('ETag', nest: eTag);
       builder.element('PartNumber', nest: partNumber.toString());
     });
diff --git a/lib/src/minio_uploader.dart b/lib/src/minio_uploader.dart
index dff64bd..3dd0ffa 100644
--- a/lib/src/minio_uploader.dart
+++ b/lib/src/minio_uploader.dart
@@ -67,8 +67,8 @@ class MinioUploader implements StreamConsumer<List<int>> {
         }
       }
 
-      final queries = {
-        'partNumber': partNumber,
+      final queries = <String, String>{
+        'partNumber': '$partNumber',
         'uploadId': uploadId,
       };
 
@@ -120,10 +120,14 @@ class MinioUploader implements StreamConsumer<List<int>> {
   }
 
   Future<void> initMultipartUpload() async {
-    uploadId = await minio.findUploadId(bucket, object);
+    //FIXME: this code still causes Signature Error
+    //FIXME: https://github.com/xtyxtyx/minio-dart/issues/7
+    //TODO: uncomment when fixed
+    // uploadId = await minio.findUploadId(bucket, object);
 
     if (uploadId == null) {
-      await minio.initiateNewMultipartUpload(bucket, object, metadata);
+      uploadId =
+          await minio.initiateNewMultipartUpload(bucket, object, metadata);
       return;
     }
 
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 6402605..7fbf68b 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -8,7 +8,7 @@ import 'package:crypto/crypto.dart';
 import 'package:intl/intl.dart';
 import 'package:xml/xml.dart';
 
-String sha256Hex(Object data) {
+String sha256Hex(dynamic data) {
   if (data is String) {
     data = utf8.encode(data);
   } else if (data is List<int>) {
@@ -20,11 +20,9 @@ String sha256Hex(Object data) {
   return hex.encode(sha256.convert(data).bytes);
 }
 
-String sha256HmacHex(String data, List<int> signingKey) {
-  return hex
-      .encode(Hmac(sha256, signingKey).convert(utf8.encode(data)).bytes)
-      .toLowerCase();
-}
+String sha256HmacHex(String data, List<int> signingKey) => hex
+    .encode(Hmac(sha256, signingKey).convert(utf8.encode(data)).bytes)
+    .toLowerCase();
 
 String md5Base64(String source) {
   final md5digest = md5.convert(utf8.encode(source)).bytes;
diff --git a/pubspec.yaml b/pubspec.yaml
index 8f203b9..f9ac99c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -8,17 +8,17 @@ environment:
   sdk: ">=2.7.0 <3.0.0"
 
 dependencies:
-  meta: ^1.1.7
-  http: ^0.12.0+4
-  crypto: ^2.1.4
+  meta: ^1.2.3
+  http: ^0.12.2
+  crypto: ^2.1.5
   convert: ^2.1.1
   xml: ^4.2.0
-  buffer: ^1.0.6
+  buffer: ^1.0.7
   intl: ^0.16.1
-  mime: ^0.9.6+3
-  path: ^1.6.0
+  mime: ^0.9.7
+  path: ^1.7.0
 
 dev_dependencies:
-  pedantic: ^1.8.0
-  test: ^1.6.0
-  html: ^0.14.0+3
+  pedantic: ^1.9.2
+  test: ^1.15.4
+  html: ^0.14.0+4
-- 
GitLab