diff --git a/README.md b/README.md index b2705839f13afb560b244a3d94ed6a2e3bf5f860..840beb24b89a30bf1c5d8dcdd5f88a3a27383f5d 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 fc7faf2ebb304f377d34ff6c4de6a0201d8e90f1..e2b9f26e50d4fca45662f61494637710932a3f80 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 e57a8ec2a7f40a5620242177f6fc17261e1a3f40..4f260f53e9722ae4a94b065b2420f8f142e84141 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 4b2957e09ab919cf089de5eb15075d68bbd49f02..4c3f08b1e217bebba6e0110068a2308d62db8ce9 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 f8d115a9699b1259b15e24d613840fa9939b2953..2487c20f7d319fc652f617d13ec664daa26330c3 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 774a07d2ad9f3aa07ef5657dd301612874ba73e8..920c02683e526aaeacde0f107fa26ca5454f5d23 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