upgrade package:http so we no longer need custom MultipartRequest (#8715)

diff --git a/dev/tools/pubspec.yaml b/dev/tools/pubspec.yaml
index 8d29d21..41d0f91 100644
--- a/dev/tools/pubspec.yaml
+++ b/dev/tools/pubspec.yaml
@@ -4,6 +4,6 @@
 dependencies:
   archive: ^1.0.20
   args: ^0.13.4
-  http: ^0.11.3
+  http: ^0.11.3+12
   intl: ^0.14.0
   path: ^1.4.0
diff --git a/examples/stocks/pubspec.yaml b/examples/stocks/pubspec.yaml
index f15f87d..112c94d 100644
--- a/examples/stocks/pubspec.yaml
+++ b/examples/stocks/pubspec.yaml
@@ -3,7 +3,7 @@
   flutter:
     sdk: flutter
   intl: '>=0.14.0 <0.15.0'
-  http: '>=0.11.3+11'
+  http: '>=0.11.3+12'
 
 dev_dependencies:
   flutter_test:
diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml
index 31f124d..d17efa6 100644
--- a/packages/flutter/pubspec.yaml
+++ b/packages/flutter/pubspec.yaml
@@ -6,7 +6,7 @@
 
 dependencies:
   collection: '>=1.9.1 <2.0.0'
-  http: '>=0.11.3+11'
+  http: '>=0.11.3+12'
   intl: '>=0.14.0 <0.15.0'
   meta: ^1.0.4
   typed_data: ^1.1.3
diff --git a/packages/flutter_tools/lib/src/crash_reporting.dart b/packages/flutter_tools/lib/src/crash_reporting.dart
index b7e9bb6..27edead 100644
--- a/packages/flutter_tools/lib/src/crash_reporting.dart
+++ b/packages/flutter_tools/lib/src/crash_reporting.dart
@@ -3,8 +3,6 @@
 // found in the LICENSE file.
 
 import 'dart:async';
-import 'dart:convert';
-import 'dart:math';
 
 import 'package:http/http.dart' as http;
 import 'package:meta/meta.dart';
@@ -94,7 +92,7 @@
         },
       );
 
-      final _MultipartRequest req = new _MultipartRequest('POST', uri);
+      final http.MultipartRequest req = new http.MultipartRequest('POST', uri);
       req.fields['product'] = _kProductId;
       req.fields['version'] = flutterVersion;
       req.fields['type'] = _kDartTypeId;
@@ -141,256 +139,3 @@
 void exitTestingMode() {
   _testing = false;
 }
-
-
-// Below is a patched version of the MultipartRequest class from package:http
-// made to conform to Flutter's style guide and to comply with the crash
-// reporting backend. Specifically, the backend does not correctly handle quoted
-// boundary values. The implementation below:
-//   - reduces boundary character set to those that do not need quotes
-//   - compensates for the smaller set by generating a longer boundary value
-
-final RegExp _newlineRegExp = new RegExp(r"\r\n|\r|\n");
-
-/// A `multipart/form-data` request. Such a request has both string [fields],
-/// which function as normal form fields, and (potentially streamed) binary
-/// [files].
-///
-/// This request automatically sets the Content-Type header to
-/// `multipart/form-data`. This value will override any value set by the user.
-///
-///     var uri = Uri.parse("http://pub.dartlang.org/packages/create");
-///     var request = new http.MultipartRequest("POST", url);
-///     request.fields['user'] = 'nweiz@google.com';
-///     request.files.add(new http.MultipartFile.fromFile(
-///         'package',
-///         new File('build/package.tar.gz'),
-///         contentType: new MediaType('application', 'x-tar'));
-///     request.send().then((response) {
-///       if (response.statusCode == 200) print("Uploaded!");
-///     });
-class _MultipartRequest extends http.BaseRequest {
-  /// The total length of the multipart boundaries used when building the
-  /// request body. According to http://tools.ietf.org/html/rfc1341.html, this
-  /// can't be longer than 70.
-  static const int _BOUNDARY_LENGTH = 70;
-
-  static final Random _random = new Random();
-
-  /// The form fields to send for this request.
-  final Map<String, String> fields;
-
-  /// The private version of [files].
-  final List<http.MultipartFile> _files;
-
-  /// Creates a new [MultipartRequest].
-  _MultipartRequest(String method, Uri url)
-      : fields = <String, String>{},
-        _files = <http.MultipartFile>[],
-        super(method, url);
-
-  /// The list of files to upload for this request.
-  List<http.MultipartFile> get files => _files;
-
-  /// The total length of the request body, in bytes. This is calculated from
-  /// [fields] and [files] and cannot be set manually.
-  @override
-  int get contentLength {
-    int length = 0;
-
-    fields.forEach((String name, String value) {
-      length += "--".length + _BOUNDARY_LENGTH + "\r\n".length +
-          UTF8.encode(_headerForField(name, value)).length +
-          UTF8.encode(value).length + "\r\n".length;
-    });
-
-    for (http.MultipartFile file in _files) {
-      length += "--".length + _BOUNDARY_LENGTH + "\r\n".length +
-          UTF8.encode(_headerForFile(file)).length +
-          file.length + "\r\n".length;
-    }
-
-    return length + "--".length + _BOUNDARY_LENGTH + "--\r\n".length;
-  }
-
-  @override
-  set contentLength(int value) {
-    throw new UnsupportedError("Cannot set the contentLength property of "
-        "multipart requests.");
-  }
-
-  /// Freezes all mutable fields and returns a single-subscription [ByteStream]
-  /// that will emit the request body.
-  @override
-  http.ByteStream finalize() {
-    final String boundary = _boundaryString();
-    headers['content-type'] = 'multipart/form-data; boundary=$boundary';
-    super.finalize();
-
-    final StreamController<List<int>> controller = new StreamController<List<int>>(sync: true);
-
-    void writeAscii(String string) {
-      controller.add(UTF8.encode(string));
-    }
-
-    void writeUtf8(String string) {
-      controller.add(UTF8.encode(string));
-    }
-    void 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, (http.MultipartFile file) {
-      writeAscii('--$boundary\r\n');
-      writeAscii(_headerForFile(file));
-      return writeStreamToSink(file.finalize(), controller)
-          .then((dynamic _) => writeLine());
-    }).then<Null>((dynamic _) {
-      writeAscii('--$boundary--\r\n');
-      controller.close();
-    });
-
-    return new http.ByteStream(controller.stream);
-  }
-
-  /// Valid boundary character codes that do not need to be quoted. From
-  /// http://tools.ietf.org/html/rfc2046#section-5.1.1.
-  static const List<int> _BOUNDARY_CHARACTERS = const <int>[
-    // Digits
-    48,
-    49,
-    50,
-    51,
-    52,
-    53,
-    54,
-    55,
-    56,
-    57,
-    // Capital letters
-    65,
-    66,
-    67,
-    68,
-    69,
-    70,
-    71,
-    72,
-    73,
-    74,
-    75,
-    76,
-    77,
-    78,
-    79,
-    80,
-    81,
-    82,
-    83,
-    84,
-    85,
-    86,
-    87,
-    88,
-    89,
-    90,
-    // Small letters
-    97,
-    98,
-    99,
-    100,
-    101,
-    102,
-    103,
-    104,
-    105,
-    106,
-    107,
-    108,
-    109,
-    110,
-    111,
-    112,
-    113,
-    114,
-    115,
-    116,
-    117,
-    118,
-    119,
-    120,
-    121,
-    122,
-  ];
-
-  /// Returns the header string for a field. The return value is guaranteed to
-  /// contain only ASCII characters.
-  String _headerForField(String name, String value) {
-    String header =
-        'content-disposition: form-data; name="${_browserEncode(name)}"';
-    if (!isPlainAscii(value)) {
-      header = '$header\r\n'
-          'content-type: text/plain; charset=utf-8\r\n'
-          'content-transfer-encoding: binary';
-    }
-    return '$header\r\n\r\n';
-  }
-
-  /// Returns the header string for a file. The return value is guaranteed to
-  /// contain only ASCII characters.
-  String _headerForFile(http.MultipartFile file) {
-    String header = 'content-type: ${file.contentType}\r\n'
-        'content-disposition: form-data; name="${_browserEncode(file.field)}"';
-
-    if (file.filename != null) {
-      header = '$header; filename="${_browserEncode(file.filename)}"';
-    }
-    return '$header\r\n\r\n';
-  }
-
-  /// Encode [value] in the same way browsers do.
-  String _browserEncode(String value) {
-    // http://tools.ietf.org/html/rfc2388 mandates some complex encodings for
-    // field names and file names, but in practice user agents seem not to
-    // follow this at all. Instead, they URL-encode `\r`, `\n`, and `\r\n` as
-    // `\r\n`; URL-encode `"`; and do nothing else (even for `%` or non-ASCII
-    // characters). We follow their behavior.
-    return value.replaceAll(_newlineRegExp, "%0D%0A").replaceAll('"', "%22");
-  }
-
-  /// Returns a randomly-generated multipart boundary string
-  String _boundaryString() {
-    final String prefix = "dart-";
-    final List<int> list = new List<int>.generate(_BOUNDARY_LENGTH - prefix.length,
-            (int index) =>
-        _BOUNDARY_CHARACTERS[_random.nextInt(_BOUNDARY_CHARACTERS.length)],
-        growable: false);
-    return "$prefix${new String.fromCharCodes(list)}";
-  }
-}
-
-/// 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<Null> writeStreamToSink<O, I extends O>(Stream<I> stream, EventSink<O> sink) {
-  final Completer<Null> completer = new Completer<Null>();
-  stream.listen(sink.add,
-      onError: sink.addError,
-      onDone: () => completer.complete());
-  return completer.future;
-}
-
-/// A regular expression that matches strings that are composed entirely of
-/// ASCII-compatible characters.
-final RegExp _kAsciiOnly = new RegExp(r"^[\x00-\x7F]+$");
-
-/// Returns whether [string] is composed entirely of ASCII-compatible
-/// characters.
-bool isPlainAscii(String string) => _kAsciiOnly.hasMatch(string);
diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml
index 4c66ffe..7d33384 100644
--- a/packages/flutter_tools/pubspec.yaml
+++ b/packages/flutter_tools/pubspec.yaml
@@ -13,7 +13,7 @@
   coverage: ^0.8.0
   crypto: '>=1.1.1 <3.0.0'
   file: 2.3.0
-  http: ^0.11.3
+  http: ^0.11.3+12
   intl: '>=0.14.0 <0.15.0'
   json_rpc_2: ^2.0.0
   json_schema: 1.0.6