From d19006670d905050ae771d1c45211163f6c7b7d9 Mon Sep 17 00:00:00 2001 From: xuty <xty50337@hotmail.com> Date: Sun, 12 Dec 2021 23:44:30 +0800 Subject: [PATCH] Fix listObjects signing error when folder name includes space #34 --- lib/src/minio_helpers.dart | 29 +++++++++++++++++++++++++++++ lib/src/minio_sign.dart | 4 ++-- test/minio_test.dart | 11 +++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/src/minio_helpers.dart b/lib/src/minio_helpers.dart index bebc4ff..b5cf6a3 100644 --- a/lib/src/minio_helpers.dart +++ b/lib/src/minio_helpers.dart @@ -270,3 +270,32 @@ String encodePath(Uri uri) { } return result.toString(); } + +final _queryIgnoredChars = { + '-'.codeUnitAt(0), + '_'.codeUnitAt(0), + '.'.codeUnitAt(0), + '~'.codeUnitAt(0), +}; + +/// encode [uri].path to HTML hex escape sequence +String encodeCanonicalQuery(String query) { + final result = StringBuffer(); + for (var char in query.codeUnits) { + if (_A <= char && char <= _Z || + _a <= char && char <= _z || + _0 <= char && char <= _9) { + result.writeCharCode(char); + continue; + } + + if (_queryIgnoredChars.contains(char)) { + result.writeCharCode(char); + continue; + } + + result.write('%'); + result.write(hex.encode([char]).toUpperCase()); + } + return result.toString(); +} diff --git a/lib/src/minio_sign.dart b/lib/src/minio_sign.dart index 9f62262..c507ac1 100644 --- a/lib/src/minio_sign.dart +++ b/lib/src/minio_sign.dart @@ -54,8 +54,8 @@ String getCanonicalRequest( final requestQuery = queryKeys.map((key) { final value = request.url.queryParameters[key]; final hasValue = value != null; - final valuePart = hasValue ? Uri.encodeQueryComponent(value!) : ''; - return Uri.encodeQueryComponent(key) + '=' + valuePart; + final valuePart = hasValue ? encodeCanonicalQuery(value!) : ''; + return encodeCanonicalQuery(key) + '=' + valuePart; }).join('&'); final canonical = []; diff --git a/test/minio_test.dart b/test/minio_test.dart index 7faadbc..481220a 100644 --- a/test/minio_test.dart +++ b/test/minio_test.dart @@ -91,6 +91,17 @@ void testListBuckets() { await minio.removeBucket(bucketName2); }); + test('listBuckets() can list buckets with spaces in name', () async { + final minio = getMinioClient(); + final bucketName = uniqueName() + ' folder'; + await minio.makeBucket(bucketName); + + final buckets = await minio.listBuckets(); + expect(buckets.any((b) => b.name == bucketName), isTrue); + + await minio.removeBucket(bucketName); + }); + test('listBuckets() fails due to wrong access key', () async { final minio = getMinioClient(accessKey: 'incorrect-access-key'); -- GitLab