When using MimeMultipartTransformer to parse a multipart MIME stream, if the source stream encounters an error or terminates unexpectedly (closes before the final boundary is read), the stream representing the active part (_multipartController) remains open, causing any listener of that part to hang indefinitely.
Here is a standalone example that hangs indefinitely (because of the keep-alive timer):
import 'dart:async';
import 'package:mime/mime.dart';
void main() async {
// Keep the event loop alive so the process hangs when the bug is present
final keepAlive = Timer.periodic(const Duration(seconds: 1), (timer) {});
final controller = StreamController<List<int>>();
final transformer = MimeMultipartTransformer('xxx');
final stream = controller.stream.transform(transformer);
// Start a part, but don't finish it
controller.add('--xxx\r\n'.codeUnits);
controller.add('Header: value\r\n\r\npart data'.codeUnits);
scheduleMicrotask(() {
print('Closing source stream prematurely...');
controller.close();
});
await for (final part in stream) {
await for (final bytes in part) {
print('Bytes: $bytes');
}
}
keepAlive.cancel();
}
The active part stream should propagate the error/exception and close itself so that active listeners terminate immediately.
When using
MimeMultipartTransformerto parse a multipart MIME stream, if the source stream encounters an error or terminates unexpectedly (closes before the final boundary is read), the stream representing the active part (_multipartController) remains open, causing any listener of that part to hang indefinitely.Here is a standalone example that hangs indefinitely (because of the keep-alive timer):
The active part stream should propagate the error/exception and close itself so that active listeners terminate immediately.