WordPress.org

Make WordPress Core

Ticket #16236: 16236.8.diff

File 16236.8.diff, 13.0 KB (added by sivel, 3 years ago)
  • wp-includes/class-http.php

     
    227227                        'body' => null, 
    228228                        'compress' => false, 
    229229                        'decompress' => true, 
    230                         'sslverify' => true 
     230                        'sslverify' => true, 
     231                        'stream' => false, 
     232                        'filename' => null 
    231233                ); 
    232234 
    233235                $r = wp_parse_args( $args, $defaults ); 
     
    255257                $r['local'] = $homeURL['host'] == $arrURL['host'] || 'localhost' == $arrURL['host']; 
    256258                unset( $homeURL ); 
    257259 
     260                // If we are streaming to a file but no filename was given drop it in the WP temp dir 
     261                // and pick it's name using the basename of the $url 
     262                if ( $r['stream']  && ! $r['filename'] ) 
     263                        $r['filename'] = get_temp_dir() . basename( $url ); 
     264 
     265                // Force some settings if we are streaming to a file and check for existence and perms of destination directory 
     266                if ( $r['stream'] ) { 
     267                        $r['blocking'] = true; 
     268                        if ( ! is_writable( dirname( $r['filename'] ) ) ) 
     269                                return new WP_Error( 'http_request_failed', __( 'Destination directory for file streaming does not exist or is not writable.' ) ); 
     270                } 
     271 
    258272                if ( is_null( $r['headers'] ) ) 
    259273                        $r['headers'] = array(); 
    260274 
     
    748762                } 
    749763 
    750764                $strResponse = ''; 
    751                 while ( ! feof($handle) ) 
    752                         $strResponse .= fread($handle, 4096); 
     765                $bodyStarted = false; 
    753766 
    754                 fclose($handle); 
     767                // If streaming to a file setup the file handle 
     768                if ( $r['stream'] ) { 
     769                        if ( ! WP_DEBUG ) 
     770                                $stream_handle = @fopen( $r['filename'], 'w+' ); 
     771                        else 
     772                                $stream_handle = fopen( $r['filename'], 'w+' ); 
     773                        if ( ! $stream_handle ) 
     774                                return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 
     775                } 
    755776 
     777                while ( ! feof($handle) ) { 
     778                        if ( $r['stream'] ) { 
     779                                $block = fread( $handle, 4096 ); 
     780                                if ( $bodyStarted ) { 
     781                                        fwrite( $stream_handle, $block ); 
     782                                } else { 
     783                                        $strResponse .= $block; 
     784                                        if ( strpos( $strResponse, "\r\n\r\n" ) ) { 
     785                                                $process = WP_Http::processResponse( $strResponse ); 
     786                                                $bodyStarted = true; 
     787                                                fwrite( $stream_handle, $process['body'] ); 
     788                                                unset( $strResponse ); 
     789                                                $process['body'] = ''; 
     790                                        } 
     791                                } 
     792                        } else { 
     793                                $strResponse .= fread( $handle, 4096 ); 
     794                        } 
     795                } 
     796 
     797                fclose( $handle ); 
     798 
    756799                if ( true === $secure_transport ) 
    757800                        error_reporting($error_reporting); 
    758801 
    759                 $process = WP_Http::processResponse($strResponse); 
    760                 $arrHeaders = WP_Http::processHeaders($process['headers']); 
     802                if ( $r['stream'] ) { 
     803                        fclose( $stream_handle ); 
     804                        $arrHeaders = WP_Http::processHeaders( $process['headers'] ); 
     805                } else { 
     806                        $process = WP_Http::processResponse( $strResponse ); 
     807                        $arrHeaders = WP_Http::processHeaders( $process['headers'] ); 
     808                        unset( $strResponse ); 
     809                } 
    761810 
    762811                // Is the response code within the 400 range? 
    763812                if ( (int) $arrHeaders['response']['code'] >= 400 && (int) $arrHeaders['response']['code'] < 500 ) 
     
    779828                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders['headers']) ) 
    780829                        $process['body'] = WP_Http_Encoding::decompress( $process['body'] ); 
    781830 
    782                 return array('headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response'], 'cookies' => $arrHeaders['cookies']); 
     831                return array( 'headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response'], 'cookies' => $arrHeaders['cookies'], 'filename' => $r['filename'] ); 
    783832        } 
    784833 
    785834        /** 
     
    10751124                        return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); 
    10761125                } 
    10771126 
    1078                 $strResponse = stream_get_contents($handle); 
    1079                 $meta = stream_get_meta_data($handle); 
     1127                if ( $r['stream'] ) { 
     1128                        if ( ! WP_DEBUG ) 
     1129                                $stream_handle = @fopen( $r['filename'], 'w+' ); 
     1130                        else 
     1131                                $stream_handle = fopen( $r['filename'], 'w+' ); 
     1132                        if ( ! $stream_handle ) 
     1133                                return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 
     1134                        stream_copy_to_stream( $handle, $stream_handle ); 
     1135                        fclose( $stream_handle ); 
     1136                        $strResponse = ''; 
     1137                } else { 
     1138                        $strResponse = stream_get_contents( $handle ); 
     1139                } 
    10801140 
    1081                 fclose($handle); 
     1141                $meta = stream_get_meta_data( $handle ); 
    10821142 
     1143                fclose( $handle ); 
     1144 
    10831145                $processedHeaders = array(); 
    10841146                if ( isset( $meta['wrapper_data']['headers'] ) ) 
    10851147                        $processedHeaders = WP_Http::processHeaders($meta['wrapper_data']['headers']); 
     
    10921154                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders['headers']) ) 
    10931155                        $strResponse = WP_Http_Encoding::decompress( $strResponse ); 
    10941156 
    1095                 return array('headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies']); 
     1157                return array( 'headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies'], 'filename' => $r['filename'] ); 
    10961158        } 
    10971159 
    10981160        /** 
     
    12751337         * 
    12761338         * @return boolean False means this class can not be used, true means it can. 
    12771339         */ 
    1278         function test($args = array()) { 
    1279                 return apply_filters('use_http_extension_transport', function_exists('http_request'), $args ); 
     1340        function test( $args = array() ) { 
     1341                $use = true; 
     1342 
     1343                if ( ! function_exists( 'http_request' ) ) 
     1344                        $use = false; 
     1345 
     1346                $stream = ! empty( $args['stream'] ); 
     1347 
     1348                if ( $stream ) 
     1349                        $use = false; 
     1350 
     1351                return apply_filters( 'use_http_extension_transport', $use, $args ); 
    12801352        } 
    12811353} 
    12821354 
     
    12921364class WP_Http_Curl { 
    12931365 
    12941366        /** 
     1367         * Temporary header storage for use with streaming to a file. 
     1368         * 
     1369         * @since 3.2.0 
     1370         * @access private 
     1371         * @var string 
     1372         */ 
     1373        private $headers; 
     1374 
     1375        /** 
    12951376         * Send a HTTP request to a URI using cURL extension. 
    12961377         * 
    12971378         * @access public 
     
    13871468                else 
    13881469                        curl_setopt( $handle, CURLOPT_HEADER, false ); 
    13891470 
     1471                // If streaming to a file open a file handle, and setup our callback for grabbing the headers 
     1472                if ( $r['stream'] ) { 
     1473                        if ( ! WP_DEBUG ) 
     1474                                $stream_handle = @fopen( $r['filename'], 'w+' ); 
     1475                        else 
     1476                                $stream_handle = fopen( $r['filename'], 'w+' ); 
     1477                        if ( ! $stream_handle ) 
     1478                                return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 
     1479                        curl_setopt( $handle, CURLOPT_FILE, $stream_handle ); 
     1480                        curl_setopt( $handle, CURLOPT_HEADERFUNCTION, array( &$this, 'stream_headers' ) ); 
     1481                } 
     1482 
    13901483                // The option doesn't work with safe mode or when open_basedir is set. 
    13911484                // Disable HEAD when making HEAD requests. 
    13921485                if ( !ini_get('safe_mode') && !ini_get('open_basedir') && 'HEAD' != $r['method'] ) 
     
    14191512 
    14201513                $theResponse = curl_exec( $handle ); 
    14211514 
    1422                 if ( !empty($theResponse) ) { 
    1423                         $headerLength = curl_getinfo($handle, CURLINFO_HEADER_SIZE); 
    1424                         $theHeaders = trim( substr($theResponse, 0, $headerLength) ); 
    1425                         if ( strlen($theResponse) > $headerLength ) 
    1426                                 $theBody = substr( $theResponse, $headerLength ); 
    1427                         else 
     1515                if ( ! empty( $theResponse ) ) { 
     1516                        // If we are streaming to a file the $headers property will hold our headers 
     1517                        if ( ! empty( $this->headers ) ) { 
     1518                                $theHeaders = $this->headers; 
     1519                                unset( $this->headers ); 
    14281520                                $theBody = ''; 
    1429                         if ( false !== strpos($theHeaders, "\r\n\r\n") ) { 
    1430                                 $headerParts = explode("\r\n\r\n", $theHeaders); 
    1431                                 $theHeaders = $headerParts[ count($headerParts) -1 ]; 
     1521                        } else { 
     1522                                $headerLength = curl_getinfo( $handle, CURLINFO_HEADER_SIZE ); 
     1523                                $theHeaders = trim( substr( $theResponse, 0, $headerLength ) ); 
     1524                                if ( strlen( $theResponse ) > $headerLength ) 
     1525                                        $theBody = substr( $theResponse, $headerLength ); 
     1526                                else 
     1527                                        $theBody = ''; 
     1528                                if ( false !== strpos( $theHeaders, "\r\n\r\n" ) ) { 
     1529                                        $headerParts = explode( "\r\n\r\n", $theHeaders ); 
     1530                                        $theHeaders = $headerParts[ count( $headerParts ) - 1 ]; 
     1531                                } 
    14321532                        } 
    1433                         $theHeaders = WP_Http::processHeaders($theHeaders); 
     1533                        $theHeaders = WP_Http::processHeaders( $theHeaders ); 
    14341534                } else { 
    1435                         if ( $curl_error = curl_error($handle) ) 
    1436                                 return new WP_Error('http_request_failed', $curl_error); 
    1437                         if ( in_array( curl_getinfo( $handle, CURLINFO_HTTP_CODE ), array(301, 302) ) ) 
    1438                                 return new WP_Error('http_request_failed', __('Too many redirects.')); 
     1535                        if ( $curl_error = curl_error( $handle ) ) 
     1536                                return new WP_Error( 'http_request_failed', $curl_error ); 
     1537                        if ( in_array( curl_getinfo( $handle, CURLINFO_HTTP_CODE ), array( 301, 302 ) ) ) 
     1538                                return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) ); 
    14391539 
    14401540                        $theHeaders = array( 'headers' => array(), 'cookies' => array() ); 
    14411541                        $theBody = ''; 
     
    14471547 
    14481548                curl_close( $handle ); 
    14491549 
     1550                if ( $r['stream'] ) 
     1551                        fclose( $stream_handle ); 
     1552 
    14501553                // See #11305 - When running under safe mode, redirection is disabled above. Handle it manually. 
    14511554                if ( !empty($theHeaders['headers']['location']) && (ini_get('safe_mode') || ini_get('open_basedir')) ) { 
    14521555                        if ( $r['redirection']-- > 0 ) { 
     
    14591562                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders['headers']) ) 
    14601563                        $theBody = WP_Http_Encoding::decompress( $theBody ); 
    14611564 
    1462                 return array('headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $response, 'cookies' => $theHeaders['cookies']); 
     1565                return array( 'headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $response, 'cookies' => $theHeaders['cookies'], 'filename' => $r['filename'] ); 
    14631566        } 
    14641567 
    14651568        /** 
     1569         * Grab the headers of the cURL request when steraming to a file 
     1570         * 
     1571         * Each header is sent individually to this callback, so we append to the $header property for temporary storage 
     1572         * 
     1573         * @since 3.2.0 
     1574         * @access private 
     1575         * @return int 
     1576         */ 
     1577        private function stream_headers( $handle, $headers ) { 
     1578                $this->headers .= $headers; 
     1579                return strlen( $headers ); 
     1580        } 
     1581 
     1582        /** 
    14661583         * Whether this class can be used for retrieving an URL. 
    14671584         * 
    14681585         * @static 
     
    14701587         * 
    14711588         * @return boolean False means this class can not be used, true means it can. 
    14721589         */ 
    1473         function test($args = array()) { 
     1590        function test( $args = array() ) { 
    14741591                if ( function_exists('curl_init') && function_exists('curl_exec') ) 
    14751592                        return apply_filters('use_curl_transport', true, $args); 
    14761593 
  • wp-includes/functions.php

     
    21112111} 
    21122112 
    21132113/** 
     2114 * Determines a writable directory for temporary files. 
     2115 * Function's preference is to WP_CONTENT_DIR followed by the return value of <code>sys_get_temp_dir()</code>, before finally defaulting to /tmp/ 
     2116 * 
     2117 * In the event that this function does not find a writable location, It may be overridden by the <code>WP_TEMP_DIR</code> constant in your <code>wp-config.php</code> file. 
     2118 * 
     2119 * @since 2.5.0 
     2120 * 
     2121 * @return string Writable temporary directory 
     2122 */ 
     2123function get_temp_dir() { 
     2124        static $temp; 
     2125        if ( defined('WP_TEMP_DIR') ) 
     2126                return trailingslashit(WP_TEMP_DIR); 
     2127 
     2128        if ( $temp ) 
     2129                return trailingslashit($temp); 
     2130 
     2131        $temp = WP_CONTENT_DIR . '/'; 
     2132        if ( is_dir($temp) && @is_writable($temp) ) 
     2133                return $temp; 
     2134 
     2135        if  ( function_exists('sys_get_temp_dir') ) { 
     2136                $temp = sys_get_temp_dir(); 
     2137                if ( @is_writable($temp) ) 
     2138                        return trailingslashit($temp); 
     2139        } 
     2140 
     2141        $temp = ini_get('upload_tmp_dir'); 
     2142        if ( is_dir($temp) && @is_writable($temp) ) 
     2143                return trailingslashit($temp); 
     2144 
     2145        $temp = '/tmp/'; 
     2146        return $temp; 
     2147} 
     2148 
     2149/** 
    21142150 * Get an array containing the current upload directory's path and url. 
    21152151 * 
    21162152 * Checks the 'upload_path' option, which should be from the web root folder, 
  • wp-admin/includes/file.php

     
    153153} 
    154154 
    155155/** 
    156  * Determines a writable directory for temporary files. 
    157  * Function's preference is to WP_CONTENT_DIR followed by the return value of <code>sys_get_temp_dir()</code>, before finally defaulting to /tmp/ 
    158  * 
    159  * In the event that this function does not find a writable location, It may be overridden by the <code>WP_TEMP_DIR</code> constant in your <code>wp-config.php</code> file. 
    160  * 
    161  * @since 2.5.0 
    162  * 
    163  * @return string Writable temporary directory 
    164  */ 
    165 function get_temp_dir() { 
    166         static $temp; 
    167         if ( defined('WP_TEMP_DIR') ) 
    168                 return trailingslashit(WP_TEMP_DIR); 
    169  
    170         if ( $temp ) 
    171                 return trailingslashit($temp); 
    172  
    173         $temp = WP_CONTENT_DIR . '/'; 
    174         if ( is_dir($temp) && @is_writable($temp) ) 
    175                 return $temp; 
    176  
    177         if  ( function_exists('sys_get_temp_dir') ) { 
    178                 $temp = sys_get_temp_dir(); 
    179                 if ( @is_writable($temp) ) 
    180                         return trailingslashit($temp); 
    181         } 
    182  
    183         $temp = ini_get('upload_tmp_dir'); 
    184         if ( is_dir($temp) && @is_writable($temp) ) 
    185                 return trailingslashit($temp); 
    186  
    187         $temp = '/tmp/'; 
    188         return $temp; 
    189 } 
    190  
    191 /** 
    192156 * Returns a filename of a Temporary unique file. 
    193157 * Please note that the calling function must unlink() this itself. 
    194158 *