From 468ed77014b367c00e9107b1e5462305edbcb6f0 Mon Sep 17 00:00:00 2001 From: xuty <xty50337@hotmail.com> Date: Sun, 29 Mar 2020 13:57:28 +0800 Subject: [PATCH] complete statObject --- README.md | 2 +- example/minio_example.dart | 11 +++++++++-- lib/src/minio.dart | 27 ++++++++++++++++++++++++++- lib/src/minio_helpers.dart | 16 ++++++++++++++++ lib/src/minio_models.dart | 14 ++++++++++++++ lib/src/utils.dart | 7 ++++++- pubspec.yaml | 1 + 7 files changed, 73 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 840beb2..060006d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Created from templates made available by Stagehand under a BSD-style | `removeBucket` | `putObject` | presignedPostPolicy | getBucketPolicy | | `listObjects` | fPutObject | | setBucketPolicy | | listObjectsV2 | `copyObject` | | listenBucketNotification | -| `listIncompleteUploads` | statObject | | | +| `listIncompleteUploads` | `statObject` | | | | | removeObject | | | | | removeObjects | | | | | removeIncompleteUpload | | | diff --git a/example/minio_example.dart b/example/minio_example.dart index e2b9f26..4e2329a 100644 --- a/example/minio_example.dart +++ b/example/minio_example.dart @@ -12,6 +12,7 @@ void main() async { ); final bucket = '00test'; + final object = 'teaweb.png'; if (!await minio.bucketExists(bucket)) { await minio.makeBucket(bucket); @@ -38,8 +39,7 @@ void main() async { // final object = await minio.getObject('00test', 'sys8_captcha.png'); // await File('sys8_captcha.png').openWrite().addStream(object); - final file = File('example/teaweb.png'); - final object = 'teaweb.png'; + final file = File('example/$object'); final size = await file.length(); final etag = await minio.putObject(bucket, object, file.openRead(), size); print(etag); @@ -50,4 +50,11 @@ void main() async { '$bucket/$object', ); print(copyResult.eTag); + + final stat = await minio.statObject(bucket, object); + print('Stat:'); + print(stat.etag); + print(stat.size); + print(stat.lastModified); + print(stat.metaData); } diff --git a/lib/src/minio.dart b/lib/src/minio.dart index 4f260f5..d1c3043 100644 --- a/lib/src/minio.dart +++ b/lib/src/minio.dart @@ -346,7 +346,7 @@ class Minio { validate(resp); final node = xml.parse(resp.body); - final result = CopyObjectResult.fromXml(node.rootElement); + final result = CopyObjectResult.fromXml(node.rootElement); result.eTag = trimDoubleQuote(result.eTag); return result; } @@ -733,6 +733,31 @@ class Minio { validate(resp, expect: 204); _regionMap.remove(bucket); } + + Future<StatObjectResult> statObject(String bucket, String object) async { + MinioInvalidBucketNameError.check(bucket); + MinioInvalidObjectNameError.check(object); + + final resp = await _client.request( + method: 'HEAD', + bucket: bucket, + object: object, + ); + + validate(resp, expect: 200); + + var etag = resp.headers['etag']; + if (etag != null) { + etag = trimDoubleQuote(etag); + } + + return StatObjectResult( + etag: etag, + size: int.parse(resp.headers['content-length']), + metaData: extractMetadata(resp.headers), + lastModified: parseRfc7231Time(resp.headers['last-modified']), + ); + } } Future<void> validateStreamed( diff --git a/lib/src/minio_helpers.dart b/lib/src/minio_helpers.dart index eb8b108..c0e7277 100644 --- a/lib/src/minio_helpers.dart +++ b/lib/src/minio_helpers.dart @@ -154,3 +154,19 @@ bool isSupportedHeader(key) { bool isStorageclassHeader(key) { return key.toLowerCase() == 'x-amz-storage-class'; } + +Map<String, String> extractMetadata(Map<String, String> metaData) { + var newMetadata = <String, String>{}; + for (var key in metaData.keys) { + if (isSupportedHeader(key) || + isStorageclassHeader(key) || + isAmzHeader(key)) { + if (key.toLowerCase().startsWith('x-amz-meta-')) { + newMetadata[key.substring(11, key.length)] = metaData[key]; + } else { + newMetadata[key] = metaData[key]; + } + } + } + return newMetadata; +} diff --git a/lib/src/minio_models.dart b/lib/src/minio_models.dart index 4c3f08b..404c4dc 100644 --- a/lib/src/minio_models.dart +++ b/lib/src/minio_models.dart @@ -92,3 +92,17 @@ class CopyConditions { matchETagExcept = etag; } } + +class StatObjectResult { + StatObjectResult({ + this.size, + this.etag, + this.lastModified, + this.metaData, + }); + + final int size; + final String etag; + final DateTime lastModified; + final Map<String, String> metaData; +} diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 920c026..e0be398 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:typed_data'; import 'package:buffer/buffer.dart'; import 'package:convert/convert.dart'; import 'package:crypto/crypto.dart'; +import 'package:intl/intl.dart'; import 'package:xml/xml.dart'; String sha256Hex(Object data) { @@ -68,4 +68,9 @@ class BlockStream extends StreamTransformerBase<List<int>, List<int>> { String trimDoubleQuote(String str) { return str.replaceAll(RegExp('^"'), '').replaceAll(RegExp(r'"$'), ''); +} + +DateTime parseRfc7231Time(String time) { + final format = DateFormat('EEE, dd MMM yyyy hh:mm:ss zzz'); + return format.parse(time); } \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index d42d6fc..cccb171 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,6 +14,7 @@ dependencies: convert: ^2.1.1 xml: ^3.7.0 buffer: ^1.0.6 + intl: ^0.16.1 # path: ^1.6.0 dev_dependencies: -- GitLab