Ticket #16236: 16236.14.diff
| File 16236.14.diff, 14.6 KB (added by , 15 years ago) |
|---|
-
wp-includes/class-http.php
97 97 'body' => null, 98 98 'compress' => false, 99 99 'decompress' => true, 100 'sslverify' => true 100 'sslverify' => true, 101 'stream' => false, 102 'filename' => null 101 103 ); 102 104 103 105 … … 136 138 $r['local'] = $homeURL['host'] == $arrURL['host'] || 'localhost' == $arrURL['host']; 137 139 unset( $homeURL ); 138 140 141 // If we are streaming to a file but no filename was given drop it in the WP temp dir 142 // and pick it's name using the basename of the $url 143 if ( $r['stream'] && empty( $r['filename'] ) ) 144 $r['filename'] = get_temp_dir() . basename( $url ); 145 146 // Force some settings if we are streaming to a file and check for existence and perms of destination directory 147 if ( $r['stream'] ) { 148 $r['blocking'] = true; 149 if ( ! is_writable( dirname( $r['filename'] ) ) ) 150 return new WP_Error( 'http_request_failed', __( 'Destination directory for file streaming does not exist or is not writable.' ) ); 151 } 152 139 153 if ( is_null( $r['headers'] ) ) 140 154 $r['headers'] = array(); 141 155 … … 659 673 } 660 674 661 675 $strResponse = ''; 662 while ( ! feof($handle) ) 663 $strResponse .= fread($handle, 4096); 676 $bodyStarted = false; 664 677 665 fclose($handle); 678 // If streaming to a file setup the file handle 679 if ( $r['stream'] ) { 680 if ( ! WP_DEBUG ) 681 $stream_handle = @fopen( $r['filename'], 'w+' ); 682 else 683 $stream_handle = fopen( $r['filename'], 'w+' ); 684 if ( ! $stream_handle ) 685 return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 666 686 687 while ( ! feof($handle) ) { 688 $block = fread( $handle, 4096 ); 689 if ( $bodyStarted ) { 690 fwrite( $stream_handle, $block ); 691 } else { 692 $strResponse .= $block; 693 if ( strpos( $strResponse, "\r\n\r\n" ) ) { 694 $process = WP_Http::processResponse( $strResponse ); 695 $bodyStarted = true; 696 fwrite( $stream_handle, $process['body'] ); 697 unset( $strResponse ); 698 $process['body'] = ''; 699 } 700 } 701 } 702 703 fclose( $stream_handle ); 704 705 } else { 706 while ( ! feof($handle) ) 707 $strResponse .= fread( $handle, 4096 ); 708 } 709 710 fclose( $handle ); 711 667 712 if ( true === $secure_transport ) 668 713 error_reporting($error_reporting); 669 714 670 $process = WP_Http::processResponse($strResponse); 671 $arrHeaders = WP_Http::processHeaders($process['headers']); 715 if ( $r['stream'] ) { 716 $arrHeaders = WP_Http::processHeaders( $process['headers'] ); 717 } else { 718 $process = WP_Http::processResponse( $strResponse ); 719 $arrHeaders = WP_Http::processHeaders( $process['headers'] ); 720 unset( $strResponse ); 721 } 672 722 673 723 // Is the response code within the 400 range? 674 724 if ( (int) $arrHeaders['response']['code'] >= 400 && (int) $arrHeaders['response']['code'] < 500 ) … … 690 740 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders['headers']) ) 691 741 $process['body'] = WP_Http_Encoding::decompress( $process['body'] ); 692 742 693 return array( 'headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response'], 'cookies' => $arrHeaders['cookies']);743 return array( 'headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response'], 'cookies' => $arrHeaders['cookies'], 'filename' => $r['filename'] ); 694 744 } 695 745 696 746 /** … … 834 884 return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); 835 885 } 836 886 837 $strResponse = stream_get_contents($handle); 838 $meta = stream_get_meta_data($handle); 887 if ( $r['stream'] ) { 888 if ( ! WP_DEBUG ) 889 $stream_handle = @fopen( $r['filename'], 'w+' ); 890 else 891 $stream_handle = fopen( $r['filename'], 'w+' ); 892 if ( ! $stream_handle ) 893 return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 894 stream_copy_to_stream( $handle, $stream_handle ); 895 fclose( $stream_handle ); 896 $strResponse = ''; 897 } else { 898 $strResponse = stream_get_contents( $handle ); 899 } 839 900 840 fclose($handle);901 $meta = stream_get_meta_data( $handle ); 841 902 903 fclose( $handle ); 904 842 905 $processedHeaders = array(); 843 906 if ( isset( $meta['wrapper_data']['headers'] ) ) 844 907 $processedHeaders = WP_Http::processHeaders($meta['wrapper_data']['headers']); … … 856 919 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders['headers']) ) 857 920 $strResponse = WP_Http_Encoding::decompress( $strResponse ); 858 921 859 return array( 'headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies']);922 return array( 'headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies'], 'filename' => $r['filename'] ); 860 923 } 861 924 862 925 /** … … 1006 1069 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders['headers']) ) 1007 1070 $theBody = http_inflate( $theBody ); 1008 1071 1072 if ( $r['stream'] ) { 1073 if ( !WP_DEBUG ) 1074 $stream_handle = @fopen( $r['filename'], 'w+' ); 1075 else 1076 $stream_handle = fopen( $r['filename'], 'w+' ); 1077 1078 if ( ! $stream_handle ) 1079 return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 1080 1081 fwrite( $stream_handle, $theBody ); 1082 fclose( $stream_handle ); 1083 $theBody = ''; 1084 } 1085 1009 1086 $theResponse = array(); 1010 1087 $theResponse['code'] = $info['response_code']; 1011 1088 $theResponse['message'] = get_status_header_desc($info['response_code']); 1012 1089 1013 return array( 'headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $theResponse, 'cookies' => $theHeaders['cookies']);1090 return array( 'headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $theResponse, 'cookies' => $theHeaders['cookies'], 'filename' => $r['filename'] ); 1014 1091 } 1015 1092 1016 1093 /** … … 1038 1115 class WP_Http_Curl { 1039 1116 1040 1117 /** 1118 * Temporary header storage for use with streaming to a file. 1119 * 1120 * @since 3.2.0 1121 * @access private 1122 * @var string 1123 */ 1124 private $headers; 1125 1126 /** 1041 1127 * Send a HTTP request to a URI using cURL extension. 1042 1128 * 1043 1129 * @access public … … 1121 1207 } 1122 1208 1123 1209 if ( true === $r['blocking'] ) 1124 curl_setopt( $handle, CURLOPT_HEADER, true ); 1125 else 1126 curl_setopt( $handle, CURLOPT_HEADER, false ); 1210 curl_setopt( $handle, CURLOPT_HEADERFUNCTION, array( &$this, 'stream_headers' ) ); 1127 1211 1212 curl_setopt( $handle, CURLOPT_HEADER, false ); 1213 1214 // If streaming to a file open a file handle, and setup our curl streaming handler 1215 if ( $r['stream'] ) { 1216 if ( ! WP_DEBUG ) 1217 $stream_handle = @fopen( $r['filename'], 'w+' ); 1218 else 1219 $stream_handle = fopen( $r['filename'], 'w+' ); 1220 if ( ! $stream_handle ) 1221 return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 1222 curl_setopt( $handle, CURLOPT_FILE, $stream_handle ); 1223 } 1224 1128 1225 // The option doesn't work with safe mode or when open_basedir is set. 1129 1226 if ( !ini_get('safe_mode') && !ini_get('open_basedir') && 0 !== $r['_redirection'] ) 1130 1227 curl_setopt( $handle, CURLOPT_FOLLOWLOCATION, true ); … … 1155 1252 } 1156 1253 1157 1254 $theResponse = curl_exec( $handle ); 1255 $theBody = ''; 1256 $theHeaders = WP_Http::processHeaders( $this->headers ); 1158 1257 1159 if ( !empty($theResponse) ) { 1160 $headerLength = curl_getinfo($handle, CURLINFO_HEADER_SIZE); 1161 $theHeaders = trim( substr($theResponse, 0, $headerLength) ); 1162 if ( strlen($theResponse) > $headerLength ) 1163 $theBody = substr( $theResponse, $headerLength ); 1164 else 1165 $theBody = ''; 1166 if ( false !== strpos($theHeaders, "\r\n\r\n") ) { 1167 $headerParts = explode("\r\n\r\n", $theHeaders); 1168 $theHeaders = $headerParts[ count($headerParts) -1 ]; 1169 } 1170 $theHeaders = WP_Http::processHeaders($theHeaders); 1171 } else { 1258 if ( ! empty($theResponse) && ! is_bool( $theResponse ) ) 1259 $theBody = $theResponse; 1260 1261 // If no response, and It's not a HEAD request with valid headers returned 1262 if ( empty($theResponse) && 'HEAD' != $args['method'] && ! empty($this->headers) ) { 1172 1263 if ( $curl_error = curl_error($handle) ) 1173 1264 return new WP_Error('http_request_failed', $curl_error); 1174 1265 if ( in_array( curl_getinfo( $handle, CURLINFO_HTTP_CODE ), array(301, 302) ) ) 1175 1266 return new WP_Error('http_request_failed', __('Too many redirects.')); 1176 1177 $theHeaders = array( 'headers' => array(), 'cookies' => array() );1178 $theBody = '';1179 1267 } 1180 1268 1269 unset( $this->headers ); 1270 1181 1271 $response = array(); 1182 1272 $response['code'] = curl_getinfo( $handle, CURLINFO_HTTP_CODE ); 1183 1273 $response['message'] = get_status_header_desc($response['code']); 1184 1274 1185 1275 curl_close( $handle ); 1186 1276 1277 if ( $r['stream'] ) 1278 fclose( $stream_handle ); 1279 1187 1280 // See #11305 - When running under safe mode, redirection is disabled above. Handle it manually. 1188 if ( ! empty($theHeaders['headers']['location']) && (ini_get('safe_mode') || ini_get('open_basedir')) && 0 !== $r['_redirection'] ) {1281 if ( ! empty( $theHeaders['headers']['location'] ) && ( ini_get( 'safe_mode' ) || ini_get( 'open_basedir' ) ) && 0 !== $r['_redirection'] ) { 1189 1282 if ( $r['redirection']-- > 0 ) { 1190 return $this->request( $theHeaders['headers']['location'], $r);1283 return $this->request( $theHeaders['headers']['location'], $r ); 1191 1284 } else { 1192 return new WP_Error( 'http_request_failed', __('Too many redirects.'));1285 return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) ); 1193 1286 } 1194 1287 } 1195 1288 1196 1289 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders['headers']) ) 1197 1290 $theBody = WP_Http_Encoding::decompress( $theBody ); 1198 1291 1199 return array( 'headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $response, 'cookies' => $theHeaders['cookies']);1292 return array( 'headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $response, 'cookies' => $theHeaders['cookies'], 'filename' => $r['filename'] ); 1200 1293 } 1201 1294 1202 1295 /** 1296 * Grab the headers of the cURL request 1297 * 1298 * Each header is sent individually to this callback, so we append to the $header property for temporary storage 1299 * 1300 * @since 3.2.0 1301 * @access private 1302 * @return int 1303 */ 1304 private function stream_headers( $handle, $headers ) { 1305 $this->headers .= $headers; 1306 return strlen( $headers ); 1307 } 1308 1309 /** 1203 1310 * Whether this class can be used for retrieving an URL. 1204 1311 * 1205 1312 * @static -
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