diff -Naur wordpress-orig/wp-includes/class-http.php wordpress/wp-includes/class-http.php
--- wordpress-orig/wp-includes/class-http.php	2017-12-08 13:28:38.000000000 +0200
+++ wordpress/wp-includes/class-http.php	2017-12-08 18:34:08.000000000 +0200
@@ -293,7 +293,14 @@
 
 		// Setup arguments
 		$headers = $r['headers'];
-		$data = $r['body'];
+		if ( isset( $r['files'] ) && $r['files'] ) {
+			$data = $this->prepare_multipart_data( $r['body'], $r['files'], $boundary );
+			if ( is_wp_error( $data ) )
+				return $data;
+			$headers['Content-Type'] = 'multipart/form-data; boundary=' . $boundary;
+		} else {
+			$data = $r['body'];
+		}
 		$type = $r['method'];
 		$options = array(
 			'timeout' => $r['timeout'],
@@ -423,6 +430,54 @@
 		return apply_filters( 'http_response', $response, $r, $url );
 	}
 
+	private function prepare_multipart_data( $data, $files, &$boundary ) {
+		// invalid characters for "name" and "filename"
+		static $disallow = array("\0", "\"", "\r", "\n");
+
+		foreach ($data as $name => $value) {
+			$key = str_replace($disallow, "_", $name);
+			$body[] = implode("\r\n", array(
+				"Content-Disposition: form-data; name=\"{$key}\"",
+				"",
+				filter_var($value),
+			) );
+		}
+
+		// build file parameters
+		foreach ($files as $name => $filename) {
+			$content = file_get_contents($filename);
+			if ( false === $content = file_get_contents( $filename ) ) {
+				return new WP_Error( 'file_read_error', sprintf( __( 'Cannot read file: %s' ), $filename ) );
+			}
+			$_filename = str_replace( $disallow, "_", basename( $filename ) );
+			$key = str_replace( $disallow, "_", $name );
+			$mime_type = wp_check_filetype( $filename )['type'];
+
+			$body[] = implode("\r\n", array(
+				"Content-Disposition: form-data; name=\"{$key}\"; filename=\"{$_filename}\"",
+				"Content-Type: ${mime_type}",
+				"",
+				$content,
+			) );
+		}
+
+		// generate safe boundary
+		do {
+			$boundary = "---------------------" . uniqid( 'wp', true );
+		} while (preg_grep("/{$boundary}/", $body));
+
+		// add boundary for each parameters
+		array_walk($body, function (&$part) use ($boundary) {
+			$part = "--{$boundary}\r\n{$part}";
+		});
+
+		// add final boundary
+		$body[] = "--{$boundary}--";
+		$body[] = "";
+
+		return implode("\r\n", $body);
+	}
+
 	/**
 	 * Normalizes cookies for using in Requests.
 	 *
