From fc475f351f231b332bad7aebf6c8379d19bdba8b Mon Sep 17 00:00:00 2001
From: xuty <xty50337@hotmail.com>
Date: Sat, 28 Mar 2020 22:50:17 +0800
Subject: [PATCH] finish putObject and copyObject

---
 README.md                   |  4 ++--
 example/minio_example.dart  | 11 ++++++++--
 lib/src/minio.dart          | 44 +++++++++++++++++++++++++++++++++++++
 lib/src/minio_models.dart   | 25 ++++++++++++++++++++-
 lib/src/minio_uploader.dart |  3 ++-
 lib/src/utils.dart          |  4 ++++
 6 files changed, 85 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index b270583..840beb2 100644
--- a/README.md
+++ b/README.md
@@ -10,9 +10,9 @@ Created from templates made available by Stagehand under a BSD-style
 | `makeBucket`           	| `getObject`            	| presignedUrl         	| getBucketNotification                   	|
 | `listBuckets`          	| `getPartialObject`     	| presignedGetObject   	| setBucketNotification                   	|
 | `bucketExists`         	| fGetObject             	| presignedPutObject   	| removeAllBucketNotification             	|
-| `removeBucket`         	| putObject              	| presignedPostPolicy  	| getBucketPolicy                         	|
+| `removeBucket`         	| `putObject`            	| presignedPostPolicy  	| getBucketPolicy                         	|
 | `listObjects`          	| fPutObject             	|                      	| setBucketPolicy                         	|
-| listObjectsV2         	| copyObject             	|                      	| listenBucketNotification                	|
+| listObjectsV2         	| `copyObject`           	|                      	| listenBucketNotification                	|
 | `listIncompleteUploads`	| statObject             	|                      	|                                         	|
 |                       	| removeObject           	|                      	|                                         	|
 |                       	| removeObjects          	|                      	|                                         	|
diff --git a/example/minio_example.dart b/example/minio_example.dart
index fc7faf2..e2b9f26 100644
--- a/example/minio_example.dart
+++ b/example/minio_example.dart
@@ -39,8 +39,15 @@ void main() async {
   // await File('sys8_captcha.png').openWrite().addStream(object);
 
   final file = File('example/teaweb.png');
+  final object = 'teaweb.png';
   final size = await file.length();
-  final etag =
-      await minio.putObject(bucket, 'teaweb.png', file.openRead(), size);
+  final etag = await minio.putObject(bucket, object, file.openRead(), size);
   print(etag);
+
+  final copyResult = await minio.copyObject(
+    bucket,
+    '$object.copy',
+    '$bucket/$object',
+  );
+  print(copyResult.eTag);
 }
diff --git a/lib/src/minio.dart b/lib/src/minio.dart
index e57a8ec..4f260f5 100644
--- a/lib/src/minio.dart
+++ b/lib/src/minio.dart
@@ -307,6 +307,50 @@ class Minio {
     return etag;
   }
 
+  Future<CopyObjectResult> copyObject(
+    String bucket,
+    String object,
+    String srcObject, [
+    CopyConditions conditions,
+  ]) async {
+    MinioInvalidBucketNameError.check(bucket);
+    MinioInvalidObjectNameError.check(object);
+    MinioInvalidObjectNameError.check(srcObject);
+
+    final headers = <String, String>{};
+    headers['x-amz-copy-source'] = srcObject;
+
+    if (conditions != null) {
+      if (conditions.modified != null) {
+        headers['x-amz-copy-source-if-modified-since'] = conditions.modified;
+      }
+      if (conditions.unmodified != null) {
+        headers['x-amz-copy-source-if-unmodified-since'] =
+            conditions.unmodified;
+      }
+      if (conditions.matchETag != null) {
+        headers['x-amz-copy-source-if-match'] = conditions.matchETag;
+      }
+      if (conditions.matchETagExcept != null) {
+        headers['x-amz-copy-source-if-none-match'] = conditions.matchETagExcept;
+      }
+    }
+
+    final resp = await _client.request(
+      method: 'PUT',
+      bucket: bucket,
+      object: object,
+      headers: headers,
+    );
+
+    validate(resp);
+
+    final node = xml.parse(resp.body);
+    final result =  CopyObjectResult.fromXml(node.rootElement);
+    result.eTag = trimDoubleQuote(result.eTag);
+    return result;
+  }
+
   Future<String> findUploadID(String bucket, String object) async {
     MinioInvalidBucketNameError.check(bucket);
     MinioInvalidObjectNameError.check(object);
diff --git a/lib/src/minio_models.dart b/lib/src/minio_models.dart
index 4b2957e..4c3f08b 100644
--- a/lib/src/minio_models.dart
+++ b/lib/src/minio_models.dart
@@ -65,7 +65,30 @@ class IncompleteUpload {
     this.upload,
     this.size,
   });
-  
+
   final MultipartUpload upload;
   final int size;
 }
+
+class CopyConditions {
+  String modified;
+  String unmodified;
+  String matchETag;
+  String matchETagExcept;
+
+  void setModified(DateTime date) {
+    modified = date.toUtc().toIso8601String();
+  }
+
+  void setUnmodified(DateTime date) {
+    unmodified = date.toUtc().toIso8601String();
+  }
+
+  void setMatchETag(String etag) {
+    matchETag = etag;
+  }
+
+  void setMatchETagExcept(String etag) {
+    matchETagExcept = etag;
+  }
+}
diff --git a/lib/src/minio_uploader.dart b/lib/src/minio_uploader.dart
index f8d115a..2487c20 100644
--- a/lib/src/minio_uploader.dart
+++ b/lib/src/minio_uploader.dart
@@ -5,6 +5,7 @@ import 'package:convert/convert.dart';
 import 'package:crypto/crypto.dart';
 import 'package:minio/minio.dart';
 import 'package:minio/models.dart';
+import 'package:minio/src/utils.dart';
 
 class MinioUploader implements StreamConsumer<List<int>> {
   MinioUploader(
@@ -110,7 +111,7 @@ class MinioUploader implements StreamConsumer<List<int>> {
 
     var etag = resp.headers['etag'];
     if (etag != null) {
-      etag = etag.replaceAll(RegExp('^"'), '').replaceAll(RegExp(r'"$'), '');
+      etag = trimDoubleQuote(etag);
     }
 
     return etag;
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 774a07d..920c026 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -65,3 +65,7 @@ class BlockStream extends StreamTransformerBase<List<int>, List<int>> {
     }
   }
 }
+
+String trimDoubleQuote(String str) {
+  return str.replaceAll(RegExp('^"'), '').replaceAll(RegExp(r'"$'), '');
+}
\ No newline at end of file
-- 
GitLab