Ticket #16236: 16236.9.diff
| File 16236.9.diff, 14.5 KB (added by , 15 years ago) |
|---|
-
wp-includes/class-http.php
227 227 'body' => null, 228 228 'compress' => false, 229 229 'decompress' => true, 230 'sslverify' => true 230 'sslverify' => true, 231 'stream' => false, 232 'filename' => null 231 233 ); 232 234 233 235 $r = wp_parse_args( $args, $defaults ); … … 255 257 $r['local'] = $homeURL['host'] == $arrURL['host'] || 'localhost' == $arrURL['host']; 256 258 unset( $homeURL ); 257 259 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 258 272 if ( is_null( $r['headers'] ) ) 259 273 $r['headers'] = array(); 260 274 … … 748 762 } 749 763 750 764 $strResponse = ''; 751 while ( ! feof($handle) ) 752 $strResponse .= fread($handle, 4096); 765 $bodyStarted = false; 753 766 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 } 755 776 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 756 799 if ( true === $secure_transport ) 757 800 error_reporting($error_reporting); 758 801 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 } 761 810 762 811 // Is the response code within the 400 range? 763 812 if ( (int) $arrHeaders['response']['code'] >= 400 && (int) $arrHeaders['response']['code'] < 500 ) … … 779 828 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders['headers']) ) 780 829 $process['body'] = WP_Http_Encoding::decompress( $process['body'] ); 781 830 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'] ); 783 832 } 784 833 785 834 /** … … 1075 1124 return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); 1076 1125 } 1077 1126 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 } 1080 1140 1081 fclose($handle);1141 $meta = stream_get_meta_data( $handle ); 1082 1142 1143 fclose( $handle ); 1144 1083 1145 $processedHeaders = array(); 1084 1146 if ( isset( $meta['wrapper_data']['headers'] ) ) 1085 1147 $processedHeaders = WP_Http::processHeaders($meta['wrapper_data']['headers']); … … 1092 1154 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders['headers']) ) 1093 1155 $strResponse = WP_Http_Encoding::decompress( $strResponse ); 1094 1156 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'] ); 1096 1158 } 1097 1159 1098 1160 /** … … 1275 1337 * 1276 1338 * @return boolean False means this class can not be used, true means it can. 1277 1339 */ 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 ); 1280 1352 } 1281 1353 } 1282 1354 … … 1292 1364 class WP_Http_Curl { 1293 1365 1294 1366 /** 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 /** 1295 1376 * Send a HTTP request to a URI using cURL extension. 1296 1377 * 1297 1378 * @access public … … 1382 1463 break; 1383 1464 } 1384 1465 1385 if ( true === $r['blocking'] )1466 if ( true === $r['blocking'] && true !== $r['stream'] ) 1386 1467 curl_setopt( $handle, CURLOPT_HEADER, true ); 1387 1468 else 1388 1469 curl_setopt( $handle, CURLOPT_HEADER, false ); 1389 1470 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 1390 1483 // The option doesn't work with safe mode or when open_basedir is set. 1391 1484 // Disable HEAD when making HEAD requests. 1392 1485 if ( !ini_get('safe_mode') && !ini_get('open_basedir') && 'HEAD' != $r['method'] ) … … 1419 1512 1420 1513 $theResponse = curl_exec( $handle ); 1421 1514 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 ); 1428 1520 $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 } 1432 1532 } 1433 $theHeaders = WP_Http::processHeaders( $theHeaders);1533 $theHeaders = WP_Http::processHeaders( $theHeaders ); 1434 1534 } 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.' ) ); 1439 1539 1440 1540 $theHeaders = array( 'headers' => array(), 'cookies' => array() ); 1441 1541 $theBody = ''; … … 1447 1547 1448 1548 curl_close( $handle ); 1449 1549 1550 if ( $r['stream'] ) 1551 fclose( $stream_handle ); 1552 1450 1553 // See #11305 - When running under safe mode, redirection is disabled above. Handle it manually. 1451 1554 if ( !empty($theHeaders['headers']['location']) && (ini_get('safe_mode') || ini_get('open_basedir')) ) { 1452 1555 if ( $r['redirection']-- > 0 ) { … … 1459 1562 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders['headers']) ) 1460 1563 $theBody = WP_Http_Encoding::decompress( $theBody ); 1461 1564 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'] ); 1463 1566 } 1464 1567 1465 1568 /** 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 /** 1466 1583 * Whether this class can be used for retrieving an URL. 1467 1584 * 1468 1585 * @static … … 1470 1587 * 1471 1588 * @return boolean False means this class can not be used, true means it can. 1472 1589 */ 1473 function test( $args = array()) {1590 function test( $args = array() ) { 1474 1591 if ( function_exists('curl_init') && function_exists('curl_exec') ) 1475 1592 return apply_filters('use_curl_transport', true, $args); 1476 1593 -
wp-includes/functions.php
2111 2111 } 2112 2112 2113 2113 /** 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 */ 2123 function 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 /** 2114 2150 * Get an array containing the current upload directory's path and url. 2115 2151 * 2116 2152 * Checks the 'upload_path' option, which should be from the web root folder, -
wp-admin/includes/file.php
153 153 } 154 154 155 155 /** 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.0162 *163 * @return string Writable temporary directory164 */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 /**192 156 * Returns a filename of a Temporary unique file. 193 157 * Please note that the calling function must unlink() this itself. 194 158 * … … 513 477 function download_url( $url, $timeout = 300 ) { 514 478 //WARNING: The file is not automatically deleted, The script must unlink() the file. 515 479 if ( ! $url ) 516 return new WP_Error( 'http_no_url', __('Invalid URL Provided.'));480 return new WP_Error( 'http_no_url', __( 'Invalid URL Provided.' ) ); 517 481 518 $tmpfname = wp_tempnam( $url);482 $tmpfname = wp_tempnam( $url ); 519 483 if ( ! $tmpfname ) 520 return new WP_Error( 'http_no_file', __('Could not create Temporary file.'));484 return new WP_Error( 'http_no_file', __( 'Could not create Temporary file.' ) ); 521 485 522 $handle = @fopen($tmpfname, 'wb'); 523 if ( ! $handle ) 524 return new WP_Error('http_no_file', __('Could not create Temporary file.')); 486 $response = wp_remote_get( $url, array( 'timeout' => $timeout, 'stream' => true, 'filename' => $tmpfname ) ); 525 487 526 $response = wp_remote_get($url, array('timeout' => $timeout)); 527 528 if ( is_wp_error($response) ) { 529 fclose($handle); 530 unlink($tmpfname); 488 if ( is_wp_error( $response ) ) { 489 unlink( $tmpfname ); 531 490 return $response; 532 491 } 533 492 534 493 if ( $response['response']['code'] != '200' ){ 535 fclose($handle); 536 unlink($tmpfname); 537 return new WP_Error('http_404', trim($response['response']['message'])); 494 unlink( $tmpfname ); 495 return new WP_Error( 'http_404', trim( $response['response']['message'] ) ); 538 496 } 539 497 540 fwrite($handle, $response['body']);541 fclose($handle);542 543 498 return $tmpfname; 544 499 } 545 500