From 738487847189e1c02143f878686c3ac0999f0c17 Mon Sep 17 00:00:00 2001
From: xuty <xty50337@hotmail.com>
Date: Sun, 2 Jan 2022 23:56:38 +0800
Subject: [PATCH] Fix response body encoding #14

---
 lib/src/minio_client.dart  | 41 ++++++++++++++++++++++++++++++++++++--
 lib/src/minio_errors.dart  |  5 +++--
 lib/src/minio_helpers.dart |  7 ++++---
 3 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/lib/src/minio_client.dart b/lib/src/minio_client.dart
index d4045b7..4d70696 100644
--- a/lib/src/minio_client.dart
+++ b/lib/src/minio_client.dart
@@ -1,4 +1,5 @@
 import 'dart:convert';
+import 'dart:typed_data';
 
 import 'package:http/http.dart';
 import 'package:minio/minio.dart';
@@ -43,6 +44,42 @@ class MinioRequest extends BaseRequest {
   }
 }
 
+/// An HTTP response where the entire response body is known in advance.
+class MinioResponse extends BaseResponse {
+  /// The bytes comprising the body of this response.
+  final Uint8List bodyBytes;
+
+  /// Body of s3 response is always encoded as UTF-8.
+  String get body => utf8.decode(bodyBytes);
+
+  /// Create a new HTTP response with a byte array body.
+  MinioResponse.bytes(
+    this.bodyBytes,
+    int statusCode, {
+    BaseRequest? request,
+    Map<String, String> headers = const {},
+    bool isRedirect = false,
+    bool persistentConnection = true,
+    String? reasonPhrase,
+  }) : super(statusCode,
+            contentLength: bodyBytes.length,
+            request: request,
+            headers: headers,
+            isRedirect: isRedirect,
+            persistentConnection: persistentConnection,
+            reasonPhrase: reasonPhrase);
+
+  static Future<MinioResponse> fromStream(StreamedResponse response) async {
+    final body = await response.stream.toBytes();
+    return MinioResponse.bytes(body, response.statusCode,
+        request: response.request,
+        headers: response.headers,
+        isRedirect: response.isRedirect,
+        persistentConnection: response.persistentConnection,
+        reasonPhrase: response.reasonPhrase);
+  }
+}
+
 class MinioClient {
   MinioClient(this.minio) {
     anonymous = minio.accessKey.isEmpty && minio.secretKey.isEmpty;
@@ -93,7 +130,7 @@ class MinioClient {
     return response;
   }
 
-  Future<Response> request({
+  Future<MinioResponse> request({
     required String method,
     String? bucket,
     String? object,
@@ -114,7 +151,7 @@ class MinioClient {
       headers: headers,
     );
 
-    final response = await Response.fromStream(stream);
+    final response = await MinioResponse.fromStream(stream);
     logResponse(response);
 
     return response;
diff --git a/lib/src/minio_errors.dart b/lib/src/minio_errors.dart
index 54a9950..e2c5859 100644
--- a/lib/src/minio_errors.dart
+++ b/lib/src/minio_errors.dart
@@ -1,5 +1,5 @@
-import 'package:http/http.dart';
 import 'package:minio/models.dart';
+import 'package:minio/src/minio_client.dart';
 import 'package:minio/src/minio_helpers.dart';
 
 class MinioError {
@@ -88,5 +88,6 @@ class MinioS3Error extends MinioError {
   MinioS3Error(String? message, [this.error, this.response]) : super(message);
 
   Error? error;
-  Response? response;
+
+  MinioResponse? response;
 }
diff --git a/lib/src/minio_helpers.dart b/lib/src/minio_helpers.dart
index b5cf6a3..2f5f4fd 100644
--- a/lib/src/minio_helpers.dart
+++ b/lib/src/minio_helpers.dart
@@ -1,6 +1,7 @@
 import 'package:convert/convert.dart';
 import 'package:http/http.dart';
 import 'package:mime/mime.dart' show lookupMimeType;
+import 'package:minio/src/minio_client.dart';
 import 'package:minio/src/minio_errors.dart';
 import 'package:minio/src/minio_models_generated.dart';
 import 'package:xml/xml.dart' as xml;
@@ -199,20 +200,20 @@ Future<void> validateStreamed(
   int? expect,
 }) async {
   if (streamedResponse.statusCode >= 400) {
-    final response = await Response.fromStream(streamedResponse);
+    final response = await MinioResponse.fromStream(streamedResponse);
     final body = xml.XmlDocument.parse(response.body);
     final error = Error.fromXml(body.rootElement);
     throw MinioS3Error(error.message, error, response);
   }
 
   if (expect != null && streamedResponse.statusCode != expect) {
-    final response = await Response.fromStream(streamedResponse);
+    final response = await MinioResponse.fromStream(streamedResponse);
     throw MinioS3Error(
         '$expect expected, got ${streamedResponse.statusCode}', null, response);
   }
 }
 
-void validate(Response response, {int? expect}) {
+void validate(MinioResponse response, {int? expect}) {
   if (response.statusCode >= 400) {
     var error;
 
-- 
GitLab