finalize method

  1. @override
ByteStream finalize()

Freezes all mutable fields and returns a single-subscription ByteStream that will emit the request body.

Implementation

@override
http.ByteStream finalize() {
  final byteStream = super.finalize();
  if (onUploadProgress == null) return byteStream;

  final total = contentLength;
  int bytes = 0;

  final t = StreamTransformer.fromHandlers(
    handleData: (List<int> data, EventSink<List<int>> sink) {
      bytes += data.length;

      // More bytes than Content-Length promised. The file grew after it was
      // measured, and sending them would be a malformed request. Report it
      // rather than quietly dropping the tail, which uploads a corrupt file
      // and returns success.
      if (bytes > total) {
        sink.addError(StateError(_sizeChanged(total, bytes)));
        return;
      }

      sink.add(data);

      onUploadProgress!(
        UploadEvent(
          total: total,
          uploaded: bytes,
          percent: total == 0 ? 100 : ((bytes / total) * 100).round(),
        ),
      );
    },
    handleDone: (EventSink<List<int>> sink) {
      // Fewer bytes than promised leaves the request hanging on a body that
      // never arrives, so name the cause here too.
      if (bytes < total) {
        sink.addError(StateError(_sizeChanged(total, bytes)));
      }
      sink.close();
    },
  );

  final stream = byteStream.transform(t);
  return http.ByteStream(stream);
}