1. override
ByteStream finalize()

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

Source

@override
ByteStream finalize() {
  // TODO(nweiz): freeze fields and files
  String boundary = _boundaryString();
  headers['content-type'] = 'multipart/form-data; boundary="$boundary"';
  super.finalize();

  StreamController<List<int>> controller = new StreamController<List<int>>(sync: true);

  void writeAscii(String string) {
    controller.add(UTF8.encode(string));
  }

  dynamic writeUtf8(String string) => controller.add(UTF8.encode(string));
  dynamic writeLine() => controller.add(<int>[13, 10]); // \r\n

  fields.forEach((String name, String value) {
    writeAscii('--$boundary\r\n');
    writeAscii(_headerForField(name, value));
    writeUtf8(value);
    writeLine();
  });

  Future.forEach(_files, (MultipartFile file) {
    writeAscii('--$boundary\r\n');
    writeAscii(_headerForFile(file));
    return writeStreamToSink(file.finalize(), controller)
      .then((_) => writeLine());
  }).then((_) {
    // TODO(nweiz): pass any errors propagated through this future on to
    // the stream. See issue 3657.
    writeAscii('--$boundary--\r\n');
    controller.close();
  });

  return new ByteStream(controller.stream);
}