Ticket #23472: 23472.diff
| File 23472.diff, 8.8 KB (added by , 14 years ago) |
|---|
-
wp-includes/class-http.php
95 95 'decompress' => true, 96 96 'sslverify' => true, 97 97 'stream' => false, 98 'filename' => null 98 'filename' => null, 99 'first-x-bytes' => null, 99 100 ); 100 101 101 102 // Pre-parse for the HEAD checks. … … 166 167 // Construct Cookie: header if any cookies are set 167 168 WP_Http::buildCookieHeader( $r ); 168 169 169 if ( WP_Http_Encoding::is_available( ) )170 if ( WP_Http_Encoding::is_available( $r ) ) 170 171 $r['headers']['Accept-Encoding'] = WP_Http_Encoding::accept_encoding(); 171 172 172 173 if ( ( ! is_null( $r['body'] ) && '' != $r['body'] ) || 'POST' == $r['method'] || 'PUT' == $r['method'] ) { … … 731 732 732 733 $strResponse = ''; 733 734 $bodyStarted = false; 735 $keep_reading = true; 736 $block_size = 4096; 737 if ( isset( $r['first-x-bytes'] ) ) 738 $block_size = min( $block_size, $r['first-x-bytes'] ); 734 739 735 740 // If streaming to a file setup the file handle 736 741 if ( $r['stream'] ) { … … 741 746 if ( ! $stream_handle ) 742 747 return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 743 748 744 while ( ! feof($handle) ) { 745 $block = fread( $handle, 4096 ); 746 if ( $bodyStarted ) { 747 fwrite( $stream_handle, $block ); 748 } else { 749 $bytes_written = 0; 750 while ( ! feof($handle) && $keep_reading ) { 751 $block = fread( $handle, $block_size ); 752 if ( ! $bodyStarted ) { 749 753 $strResponse .= $block; 750 754 if ( strpos( $strResponse, "\r\n\r\n" ) ) { 751 755 $process = WP_Http::processResponse( $strResponse ); 752 756 $bodyStarted = true; 753 fwrite( $stream_handle, $process['body'] );757 $block = $process['body']; 754 758 unset( $strResponse ); 755 759 $process['body'] = ''; 756 760 } 757 761 } 762 763 if ( isset( $r['first-x-bytes'] ) && ( $bytes_written + strlen( $block ) ) > $r['first-x-bytes'] ) { 764 $block = substr( $block, 0, ( $r['first-x-bytes'] - $bytes_written ) ); 765 } 766 $bytes_written += fwrite( $stream_handle, $block ); 767 768 $keep_reading = !isset( $r['first-x-bytes'] ) || $bytes_written < $r['first-x-bytes']; 758 769 } 759 770 760 771 fclose( $stream_handle ); 761 772 762 773 } else { 763 while ( ! feof($handle) ) 764 $strResponse .= fread( $handle, 4096 ); 774 $header_length = 0; 775 while ( ! feof( $handle ) && $keep_reading ) { 776 $block = fread( $handle, $block_size ); 777 $strResponse .= $block; 778 if ( ! $bodyStarted && strpos( $strResponse, "\r\n\r\n" ) ) { 779 $header_length = strpos( $strResponse, "\r\n\r\n" ) + 4; 780 $bodyStarted = true; 781 } 782 $keep_reading = ( ! $bodyStarted || !isset( $r['first-x-bytes'] ) || strlen( $strResponse ) < ( $header_length + $r['first-x-bytes'] ) ); 783 } 765 784 766 785 $process = WP_Http::processResponse( $strResponse ); 767 786 unset( $strResponse ); 787 768 788 } 769 789 770 790 fclose( $handle ); … … 790 810 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders['headers']) ) 791 811 $process['body'] = WP_Http_Encoding::decompress( $process['body'] ); 792 812 813 if ( isset( $r['first-x-bytes'] ) && strlen( $process['body'] ) > $r['first-x-bytes'] ) 814 $process['body'] = substr( $process['body'], 0, $r['first-x-bytes'] ); 815 793 816 return array( 'headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response'], 'cookies' => $arrHeaders['cookies'], 'filename' => $r['filename'] ); 794 817 } 795 818 … … 933 956 return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); 934 957 } 935 958 959 $max_bytes = isset( $r['first-x-bytes'] ) ? intval( $r['first-x-bytes'] ) : -1; 936 960 if ( $r['stream'] ) { 937 961 if ( ! WP_DEBUG ) 938 962 $stream_handle = @fopen( $r['filename'], 'w+' ); … … 942 966 if ( ! $stream_handle ) 943 967 return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 944 968 945 stream_copy_to_stream( $handle, $stream_handle );969 stream_copy_to_stream( $handle, $stream_handle, $max_bytes ); 946 970 947 971 fclose( $stream_handle ); 948 972 $strResponse = ''; 949 973 } else { 950 $strResponse = stream_get_contents( $handle );974 $strResponse = stream_get_contents( $handle, $max_bytes ); 951 975 } 952 976 953 977 $meta = stream_get_meta_data( $handle ); … … 1011 1035 class WP_Http_Curl { 1012 1036 1013 1037 /** 1014 * Temporary header storage for use with streaming to a file.1038 * Temporary header storage for during requests. 1015 1039 * 1016 1040 * @since 3.2.0 1017 1041 * @access private … … 1020 1044 private $headers = ''; 1021 1045 1022 1046 /** 1047 * Temporary body storage for during requests. 1048 * 1049 * @since 3.6.0 1050 * @access private 1051 * @var string 1052 */ 1053 private $body = ''; 1054 1055 /** 1056 * The maximum amount of data to recieve from the remote server 1057 * 1058 * @since 3.6.0 1059 * @access private 1060 * @var int 1061 */ 1062 private $max_body_length = false; 1063 1064 /** 1065 * The file resource used for streaming to file. 1066 * 1067 * @since 3.6.0 1068 * @access private 1069 * @var resource 1070 */ 1071 private $stream_handle = false; 1072 1073 /** 1023 1074 * Send a HTTP request to a URI using cURL extension. 1024 1075 * 1025 1076 * @access public … … 1108 1159 break; 1109 1160 } 1110 1161 1111 if ( true === $r['blocking'] ) 1162 if ( true === $r['blocking'] ) { 1112 1163 curl_setopt( $handle, CURLOPT_HEADERFUNCTION, array( $this, 'stream_headers' ) ); 1164 curl_setopt( $handle, CURLOPT_WRITEFUNCTION, array( $this, 'stream_body' ) ); 1165 } 1113 1166 1114 1167 curl_setopt( $handle, CURLOPT_HEADER, false ); 1115 1168 1169 if ( isset( $r['first-x-bytes'] ) ) 1170 $this->max_body_length = intval( $r['first-x-bytes'] ); 1171 1116 1172 // If streaming to a file open a file handle, and setup our curl streaming handler 1117 1173 if ( $r['stream'] ) { 1118 1174 if ( ! WP_DEBUG ) 1119 $ stream_handle = @fopen( $r['filename'], 'w+' );1175 $this->stream_handle = @fopen( $r['filename'], 'w+' ); 1120 1176 else 1121 $ stream_handle = fopen( $r['filename'], 'w+' );1122 if ( ! $ stream_handle )1177 $this->stream_handle = fopen( $r['filename'], 'w+' ); 1178 if ( ! $this->stream_handle ) 1123 1179 return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) ); 1124 curl_setopt( $handle, CURLOPT_FILE, $stream_handle );1125 1180 } 1126 1181 1127 1182 if ( !empty( $r['headers'] ) ) { … … 1150 1205 } 1151 1206 1152 1207 $theResponse = curl_exec( $handle ); 1153 $theBody = '';1154 1208 $theHeaders = WP_Http::processHeaders( $this->headers ); 1209 $theBody = $this->body; 1155 1210 1156 if ( strlen($theResponse) > 0 && ! is_bool( $theResponse ) ) // is_bool: when using $args['stream'], curl_exec will return (bool)true1157 $theBody = $theResponse;1211 $this->headers = ''; 1212 $this->body = ''; 1158 1213 1159 1214 // If no response 1160 if ( 0 == strlen( $the Response) && empty( $theHeaders['headers'] ) ) {1215 if ( 0 == strlen( $theBody ) && empty( $theHeaders['headers'] ) ) { 1161 1216 if ( $curl_error = curl_error( $handle ) ) 1162 1217 return new WP_Error( 'http_request_failed', $curl_error ); 1163 1218 if ( in_array( curl_getinfo( $handle, CURLINFO_HTTP_CODE ), array( 301, 302 ) ) ) 1164 1219 return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) ); 1165 1220 } 1166 1221 1167 $this->headers = '';1168 1169 1222 $response = array(); 1170 1223 $response['code'] = curl_getinfo( $handle, CURLINFO_HTTP_CODE ); 1171 1224 $response['message'] = get_status_header_desc($response['code']); … … 1173 1226 curl_close( $handle ); 1174 1227 1175 1228 if ( $r['stream'] ) 1176 fclose( $ stream_handle );1229 fclose( $this->stream_handle ); 1177 1230 1178 1231 // See #11305 - When running under safe mode, redirection is disabled above. Handle it manually. 1179 1232 if ( ! empty( $theHeaders['headers']['location'] ) && 0 !== $r['_redirection'] ) { // _redirection: The requested number of redirections … … 1205 1258 } 1206 1259 1207 1260 /** 1261 * Grab the body of the cURL request 1262 * 1263 * The contents of the document are passed in chunks, so we append to the $body property for temporary storage. 1264 * Returning a length shorter than the length of $data passed in will cause cURL to abort the request as "completed" 1265 * 1266 * @since 3.6.0 1267 * @access private 1268 * @return int 1269 */ 1270 private function stream_body( $handle, $data ) { 1271 if ( $this->max_body_length && ( strlen( $this->body ) + strlen( $data ) ) > $this->max_body_length ) 1272 $data = substr( $data, 0, ( $this->max_body_length - strlen( $this->body ) ) ); 1273 1274 if ( $this->stream_handle ) 1275 fwrite( $this->stream_handle, $data ); 1276 else 1277 $this->body .= $data; 1278 1279 return strlen( $data ); 1280 } 1281 1282 /** 1208 1283 * Whether this class can be used for retrieving an URL. 1209 1284 * 1210 1285 * @static … … 1785 1860 * 1786 1861 * @return bool 1787 1862 */ 1788 public static function is_available() { 1863 public static function is_available( $args ) { 1864 // If only partial content is being requested, we won't be able to decompress it 1865 if ( isset( $args['first-x-bytes'] ) ) 1866 return false; 1867 1789 1868 return ( function_exists('gzuncompress') || function_exists('gzdeflate') || function_exists('gzinflate') ); 1790 1869 } 1791 1870 }
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)