Make WordPress Core

Ticket #42839: wp_remote_multipart.diff

File wp_remote_multipart.diff, 2.3 KB (added by calin, 5 years ago)
  • wp-includes/class-http.php

    diff -Naur wordpress-orig/wp-includes/class-http.php wordpress/wp-includes/class-http.php
    old new  
    293293
    294294                // Setup arguments
    295295                $headers = $r['headers'];
    296                 $data = $r['body'];
     296                if ( isset( $r['files'] ) && $r['files'] ) {
     297                        $data = $this->prepare_multipart_data( $r['body'], $r['files'], $boundary );
     298                        if ( is_wp_error( $data ) )
     299                                return $data;
     300                        $headers['Content-Type'] = 'multipart/form-data; boundary=' . $boundary;
     301                } else {
     302                        $data = $r['body'];
     303                }
    297304                $type = $r['method'];
    298305                $options = array(
    299306                        'timeout' => $r['timeout'],
     
    423430                return apply_filters( 'http_response', $response, $r, $url );
    424431        }
    425432
     433        private function prepare_multipart_data( $data, $files, &$boundary ) {
     434                // invalid characters for "name" and "filename"
     435                static $disallow = array("\0", "\"", "\r", "\n");
     436
     437                foreach ($data as $name => $value) {
     438                        $key = str_replace($disallow, "_", $name);
     439                        $body[] = implode("\r\n", array(
     440                                "Content-Disposition: form-data; name=\"{$key}\"",
     441                                "",
     442                                filter_var($value),
     443                        ) );
     444                }
     445
     446                // build file parameters
     447                foreach ($files as $name => $filename) {
     448                        $content = file_get_contents($filename);
     449                        if ( false === $content = file_get_contents( $filename ) ) {
     450                                return new WP_Error( 'file_read_error', sprintf( __( 'Cannot read file: %s' ), $filename ) );
     451                        }
     452                        $_filename = str_replace( $disallow, "_", basename( $filename ) );
     453                        $key = str_replace( $disallow, "_", $name );
     454                        $mime_type = wp_check_filetype( $filename )['type'];
     455
     456                        $body[] = implode("\r\n", array(
     457                                "Content-Disposition: form-data; name=\"{$key}\"; filename=\"{$_filename}\"",
     458                                "Content-Type: ${mime_type}",
     459                                "",
     460                                $content,
     461                        ) );
     462                }
     463
     464                // generate safe boundary
     465                do {
     466                        $boundary = "---------------------" . uniqid( 'wp', true );
     467                } while (preg_grep("/{$boundary}/", $body));
     468
     469                // add boundary for each parameters
     470                array_walk($body, function (&$part) use ($boundary) {
     471                        $part = "--{$boundary}\r\n{$part}";
     472                });
     473
     474                // add final boundary
     475                $body[] = "--{$boundary}--";
     476                $body[] = "";
     477
     478                return implode("\r\n", $body);
     479        }
     480
    426481        /**
    427482         * Normalizes cookies for using in Requests.
    428483         *