Skip to content

Commit

Permalink
πŸ› Applies strict type conversion for finalizing the multipart file (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexV525 authored Jun 8, 2024
1 parent 005251d commit d334d25
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 14 deletions.
1 change: 1 addition & 0 deletions dio/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ See the [Migration Guide][] for the complete breaking changes list.**
- Raise the min Dart SDK version to 2.18.0.
- Add constructor for `DioExceptionType.badCertificate`.
- Create type alias `DioMediaType` for `http_parser`'s `MediaType`.
- Fix the type conversion regression when using `MultipartFile.fromBytes`.

## 5.4.3+1

Expand Down
4 changes: 2 additions & 2 deletions dio/lib/src/form_data.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:math' as math;
import 'dart:typed_data';
import 'dart:typed_data' show Uint8List;

import 'multipart_file.dart';
import 'options.dart';
Expand Down Expand Up @@ -188,7 +188,7 @@ class FormData {
for (final file in files) {
writeUtf8('--$boundary$_rn');
writeUtf8(_headerForFile(file));
await writeStreamToSink(file.value.finalize(), controller);
await writeStreamToSink<Uint8List>(file.value.finalize(), controller);
writeLine();
}
}).then((_) {
Expand Down
19 changes: 10 additions & 9 deletions dio/lib/src/multipart_file.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:convert' show utf8;
import 'dart:typed_data' show Uint8List;

import 'package:http_parser/http_parser.dart';
import 'package:http_parser/http_parser.dart' show MediaType;

import 'multipart_file/io_multipart_file.dart'
if (dart.library.html) 'multipart_file/browser_multipart_file.dart';
Expand Down Expand Up @@ -32,7 +32,7 @@ class MultipartFile {
this.filename,
DioMediaType? contentType,
Map<String, List<String>>? headers,
}) : _data = (() => stream),
}) : _dataBuilder = (() => stream),
headers = caseInsensitiveKeyMap(headers),
contentType = contentType ?? MediaType('application', 'octet-stream');

Expand All @@ -48,7 +48,7 @@ class MultipartFile {
this.filename,
DioMediaType? contentType,
Map<String, List<String>>? headers,
}) : _data = data,
}) : _dataBuilder = data,
headers = caseInsensitiveKeyMap(headers),
contentType = contentType ?? MediaType('application', 'octet-stream');

Expand Down Expand Up @@ -112,7 +112,7 @@ class MultipartFile {
final DioMediaType? contentType;

/// The stream builder that will emit the file's contents for every call.
final Stream<List<int>> Function() _data;
final Stream<List<int>> Function() _dataBuilder;

/// Whether [finalize] has been called.
bool get isFinalized => _isFinalized;
Expand Down Expand Up @@ -153,7 +153,7 @@ class MultipartFile {

bool _isFinalized = false;

Stream<List<int>> finalize() {
Stream<Uint8List> finalize() {
if (isFinalized) {
throw StateError(
'The MultipartFile has already been finalized. '
Expand All @@ -162,15 +162,16 @@ class MultipartFile {
);
}
_isFinalized = true;
return _data.call();
return _dataBuilder()
.map((e) => e is Uint8List ? e : Uint8List.fromList(e));
}

/// Clone MultipartFile, returning a new instance of the same object.
/// This is useful if your request failed and you wish to retry it,
/// such as an unauthorized exception can be solved by refreshing the token.
MultipartFile clone() {
return MultipartFile.fromStream(
_data,
_dataBuilder,
length,
filename: filename,
contentType: contentType,
Expand Down
4 changes: 2 additions & 2 deletions dio/lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const kReleaseMode = bool.fromEnvironment('dart.vm.product');
/// Pipes all data and errors from [stream] into [sink]. Completes [Future] once
/// [stream] is done. Unlike [store], [sink] remains open after [stream] is
/// done.
Future writeStreamToSink(Stream stream, EventSink sink) {
final completer = Completer();
Future<void> writeStreamToSink<T>(Stream<T> stream, EventSink<T> sink) {
final completer = Completer<void>();
stream.listen(
sink.add,
onError: sink.addError,
Expand Down
29 changes: 29 additions & 0 deletions dio/test/formdata_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ void main() async {
},
contentType: DioMediaType.parse('text/plain'),
),
MultipartFile.fromBytes(
utf8.encode('hello world again.').toList(),
filename: '3.txt',
headers: {
'test': <String>['d'],
},
contentType: DioMediaType.parse('text/plain'),
),
],
});
final fmStr = await fm.readAsBytes();
Expand Down Expand Up @@ -91,6 +99,19 @@ void main() async {
),
),
);
fm1.files.add(
MapEntry(
'files',
MultipartFile.fromBytes(
utf8.encode('hello world again.'),
filename: '3.txt',
headers: {
'test': <String>['d'],
},
contentType: DioMediaType.parse('text/plain'),
),
),
);
expect(fmStr.length, fm1.length);
},
testOn: 'vm',
Expand Down Expand Up @@ -125,6 +146,14 @@ void main() async {
},
contentType: DioMediaType.parse('text/plain'),
),
MultipartFile.fromBytes(
utf8.encode('hello world again.'),
filename: '3.txt',
headers: {
'test': <String>['d'],
},
contentType: DioMediaType.parse('text/plain'),
),
],
});
final fmStr = await fm.readAsBytes();
Expand Down
6 changes: 6 additions & 0 deletions dio/test/mock/_formdata
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@ test: c
ζˆ‘εΎˆε₯½δΊΊη±»
ε“ˆε“ˆε“ˆε“ˆε“ˆπŸ˜†

----dio-boundary-3788753558
content-disposition: form-data; name="files"; filename="3.txt"
content-type: text/plain
test: d

hello world again.
----dio-boundary-3788753558--
2 changes: 1 addition & 1 deletion dio_test/lib/src/test/download_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void downloadTests(
cancelToken.cancel();
});

final completer = Completer();
final completer = Completer<Never>();
res.data!.stream.listen(
(event) {},
onError: (e, s) {
Expand Down

0 comments on commit d334d25

Please sign in to comment.