Ticket #13777: 13777.2.patch
File 13777.2.patch, 19.7 KB (added by , 13 years ago) |
---|
-
wp-includes/class-http.php
### Eclipse Workspace Patch 1.0 #P wordpress-trunk
13 13 */ 14 14 15 15 /** 16 * HTTP Transport base class 17 * 18 * @since 3.2 19 */ 20 abstract class WP_Http_TransportConcrete extends WP_Http { 21 abstract protected static function test( array $args = array(), $url = null ); 22 abstract protected function _request( $url, array $args ); 23 /** 24 * Send a HTTP request to a URI. 25 * 26 * @see WP_Http::request For default options descriptions. 27 * 28 * @since 2.7 29 * @access public 30 * @param string $url URI resource. 31 * @param str|array $args Optional. Override the defaults. 32 * @return array 'headers', 'body', 'cookies' and 'response' keys. 33 */ 34 public function request( $url, $args = array() ) { 35 $defaults = array( 36 'method' => 'GET', 'timeout' => 5, 37 'redirection' => 5, 'httpversion' => '1.0', 38 'blocking' => true, 39 'headers' => array(), 'cookies' => array(), 'body' => null 40 ); 41 42 $args = wp_parse_args( $args, $defaults ); 43 44 if ( isset($args['headers']['User-Agent']) ) { 45 $args['user-agent'] = $args['headers']['User-Agent']; 46 unset($args['headers']['User-Agent']); 47 } else if ( isset($r['headers']['user-agent']) ) { 48 $args['user-agent'] = $args['headers']['user-agent']; 49 unset($args['headers']['user-agent']); 50 } 51 52 // Construct Cookie: header if any cookies are set 53 WP_Http::buildCookieHeader( $args ); 54 55 return $this->_request( $url, $args ); 56 } 57 } 58 59 /** 16 60 * WordPress HTTP Class for managing HTTP Transports and making HTTP requests. 17 61 * 18 62 * This class is called for the functionality of making HTTP requests and replaces Snoopy … … 36 80 * @since 2.7.0 37 81 */ 38 82 class WP_Http { 83 /** 84 * local store of WP_Http_* Transport Objects, keyed with their Transport name. 85 * 86 * @var array 87 */ 88 private static $_transports = array(); 39 89 40 90 /** 41 91 * Send a HTTP request to a URI. … … 102 152 'filename' => null 103 153 ); 104 154 105 106 155 // Pre-parse for the HEAD checks. 107 156 $args = wp_parse_args( $args ); 108 157 … … 110 159 if ( isset($args['method']) && 'HEAD' == $args['method'] ) 111 160 $defaults['redirection'] = 0; 112 161 113 $r = wp_parse_args( $args, $defaults );162 $r = array_merge( $defaults, $args ); 114 163 $r = apply_filters( 'http_request_args', $r, $url ); 115 164 116 165 // Certain classes decrement this, store a copy of the original value for loop purposes. … … 124 173 $arrURL = parse_url( $url ); 125 174 126 175 if ( empty( $url ) || empty( $arrURL['scheme'] ) ) 127 return new WP_Error('http_request_failed', __( 'A valid URL was not provided.'));176 return new WP_Error('http_request_failed', __( 'Invalid URL.' )); 128 177 129 178 if ( $this->block_request( $url ) ) 130 179 return new WP_Error( 'http_request_failed', __( 'User has blocked requests through HTTP.' ) ); … … 158 207 $r['headers'] = $processedHeaders['headers']; 159 208 } 160 209 161 if ( isset( $r['headers']['User-Agent']) ) {210 if ( isset($r['headers']['User-Agent']) ) { 162 211 $r['user-agent'] = $r['headers']['User-Agent']; 163 unset( $r['headers']['User-Agent'] ); 164 } 165 166 if ( isset( $r['headers']['user-agent'] ) ) { 212 unset($r['headers']['User-Agent']); 213 } else if ( isset($r['headers']['user-agent']) ) { 167 214 $r['user-agent'] = $r['headers']['user-agent']; 168 unset( $r['headers']['user-agent']);215 unset($r['headers']['user-agent']); 169 216 } 170 217 171 218 // Construct Cookie: header if any cookies are set … … 196 243 } 197 244 198 245 /** 246 * get transport object specified by name 247 * 248 * Works as a multi-singleton registry on self::$transports 249 * 250 * @param string $transport name 251 * @return Object 252 */ 253 private function _transport_object( $transport ) { 254 $class = "WP_HTTP_{$transport}"; 255 256 if ( empty( self::$_transports[ $transport ] ) ) 257 self::$_transports[ $transport ] = new $class; 258 259 return self::$_transports[ $transport ]; 260 } 261 262 /** 199 263 * Dispatches a HTTP request to a supporting transport. 200 264 * 201 265 * Tests each transport in order to find a transport which matches the request arguements. … … 218 282 * @return array|object Array containing 'headers', 'body', 'response', 'cookies'. A WP_Error instance upon error 219 283 */ 220 284 private function _dispatch_request($url, $args) { 221 static $transports = null; 222 if ( is_null($transports) ) 223 $transports = array(); 285 // default transports order 286 $request_order = $args['blocking'] ? 287 array( 'exthttp', 'curl', 'streams', 'fsockopen' ): // blocking order 288 array( 'curl', 'streams', 'fsockopen', 'exthttp' ); // non-blocking order 224 289 225 $request_order = isset($r['blocking']) && !$r['blocking'] ? 226 array('curl', 'streams', 'fsockopen', 'exthttp') : // non-blocking order 227 array('exthttp', 'curl', 'streams', 'fsockopen'); // blocking order 290 $request_order = apply_filters( 'http_get_transports', $request_order, $url, $args ); 228 291 229 // Loop over each transport on each HTTP request looking for one which will serve this requests needs 230 foreach ( $request_order as $transport ) { 231 $class = 'WP_HTTP_' . $transport; 292 // retrieve the transport from all transports and request 293 if ( $transport = $this->_test_transports( $request_order, $url, $args ) ) { 294 // Transport claims to support request, give it a whirl. 295 $response = $this->_transport_object( $transport )->request( $url, $args ); 232 296 233 // Check to see if this transport is a possibility, calls the transport statically 234 if ( ! call_user_func( array($class, 'test'), $args, $url) ) 235 continue; 297 do_action( 'http_api_debug', $response, 'response', "WP_Http_{$transport}" ); 236 298 237 // Transport claims to support request, Instantate it and give it a whirl.238 if ( empty( $transports[ $transport ] ) )239 $transports[ $transport ] = new $class;240 241 $response = $transports[ $transport ]->request( $url, $args );242 243 do_action( 'http_api_debug', $response, 'response', $class );244 245 299 if ( is_wp_error( $response ) ) 246 300 return $response; 247 301 … … 250 304 251 305 return new WP_Error('http_failure', __('There are no HTTP transports available which can complete the requested request.') ); 252 306 } 307 308 /** 309 * Test if one of the transports is available 310 * 311 * Returns on first match. 312 * 313 * @param array $transports list of transports to test against 314 * @param string $url 315 * @param array $args 316 * @return string name of the transport, empty string if non could be found 317 */ 318 private function _test_transports( array $transports, $url, array $args ) { 319 foreach( $transports as $transport ) { 320 if ( $this->test_transport( $transport, $args, $url ) ) 321 return $transport; 322 } 323 return ''; 324 } 253 325 254 326 /** 327 * test if a named transport is available 328 * 329 * @param string $transport name of the transport 330 * @param array $args Optional. Arguments for the transport to be tested against. 331 * @param string $url Optional. Url for the transport to be tested against. 332 * @return boolean Whether or not the transport can be used. 333 */ 334 public function test_transport( $transport, array $args = array() , $url = null ) { 335 $result = call_user_func( "WP_HTTP_{$transport}::test", $args, $url ); 336 return apply_filters( "use_{$transport}_transport", $result, $args, $url ); 337 } 338 339 private function _request_by_method( $method, $url, $args ) { 340 $defaults = array( 'method' => $method ); 341 $r = wp_parse_args( $args, $defaults ); 342 return $this->request( $url, $r ); 343 } 344 345 /** 255 346 * Uses the POST HTTP method. 256 347 * 257 348 * Used for sending data that is expected to be in the body. … … 264 355 * @return array|object Array containing 'headers', 'body', 'response', 'cookies'. A WP_Error instance upon error 265 356 */ 266 357 function post($url, $args = array()) { 267 $defaults = array('method' => 'POST'); 268 $r = wp_parse_args( $args, $defaults ); 269 return $this->request($url, $r); 358 return $this->_request_by_method( 'POST', $url, $args ); 270 359 } 271 360 272 361 /** … … 282 371 * @return array|object Array containing 'headers', 'body', 'response', 'cookies'. A WP_Error instance upon error 283 372 */ 284 373 function get($url, $args = array()) { 285 $defaults = array('method' => 'GET'); 286 $r = wp_parse_args( $args, $defaults ); 287 return $this->request($url, $r); 374 return $this->_request_by_method( 'GET', $url, $args ); 288 375 } 289 376 290 377 /** … … 300 387 * @return array|object Array containing 'headers', 'body', 'response', 'cookies'. A WP_Error instance upon error 301 388 */ 302 389 function head($url, $args = array()) { 303 $defaults = array('method' => 'HEAD'); 304 $r = wp_parse_args( $args, $defaults ); 305 return $this->request($url, $r); 390 return $this->_request_by_method( 'POST', $url, $args ); 306 391 } 307 392 308 393 /** … … 317 402 */ 318 403 function processResponse($strResponse) { 319 404 $res = explode("\r\n\r\n", $strResponse, 2); 405 $res[] = ''; 320 406 321 return array( 'headers' => isset($res[0]) ? $res[0] : array(), 'body' => isset($res[1]) ? $res[1] : '');407 return array( 'headers' => $res[0], 'body' => $res[1] ); 322 408 } 323 409 324 410 /** … … 537 623 * @subpackage HTTP 538 624 * @since 2.7.0 539 625 */ 540 class WP_Http_Fsockopen {626 class WP_Http_Fsockopen extends WP_Http_TransportConcrete { 541 627 /** 542 628 * Send a HTTP request to a URI using fsockopen(). 543 629 * 544 * Does not support non-blocking mode. 545 * 546 * @see WP_Http::request For default options descriptions. 547 * 548 * @since 2.7 549 * @access public 630 * @since 2.7 through request() 631 * @access public through request() 550 632 * @param string $url URI resource. 551 * @param str|array $args Optional. Override the defaults.633 * @param array $args Optional. 552 634 * @return array 'headers', 'body', 'cookies' and 'response' keys. 553 635 */ 554 function request($url, $args = array()) { 555 $defaults = array( 556 'method' => 'GET', 'timeout' => 5, 557 'redirection' => 5, 'httpversion' => '1.0', 558 'blocking' => true, 559 'headers' => array(), 'body' => null, 'cookies' => array() 560 ); 636 protected function _request($url, array $args = array()) { 637 $r = $args; # alias parameter @todo rename 561 638 562 $r = wp_parse_args( $args, $defaults );563 564 if ( isset($r['headers']['User-Agent']) ) {565 $r['user-agent'] = $r['headers']['User-Agent'];566 unset($r['headers']['User-Agent']);567 } else if ( isset($r['headers']['user-agent']) ) {568 $r['user-agent'] = $r['headers']['user-agent'];569 unset($r['headers']['user-agent']);570 }571 572 // Construct Cookie: header if any cookies are set573 WP_Http::buildCookieHeader( $r );574 575 639 $iError = null; // Store error number 576 640 $strError = null; // Store error string 577 641 … … 718 782 $arrHeaders = WP_Http::processHeaders( $process['headers'] ); 719 783 720 784 // Is the response code within the 400 range? 721 if ( (int) $arrHeaders['response']['code'] >= 400 && (int) $arrHeaders['response']['code'] < 500)785 if ( 4 === (int) ($arrHeaders['response']['code'] / 100) ) 722 786 return new WP_Error('http_request_failed', $arrHeaders['response']['code'] . ': ' . $arrHeaders['response']['message']); 723 787 724 788 // If location is found, then assume redirect and redirect to location. … … 747 811 * @static 748 812 * @return boolean False means this class can not be used, true means it can. 749 813 */ 750 function test( $args = array()) {814 protected static function test( array $args = array(), $url = null ) { 751 815 if ( false !== ($option = get_option( 'disable_fsockopen' )) && time()-$option < 43200 ) // 12 hours 752 816 return false; 753 817 … … 760 824 else 761 825 $use = false; 762 826 763 return apply_filters('use_fsockopen_transport', $use, $args);827 return $use; 764 828 } 765 829 } 766 830 … … 776 840 * @subpackage HTTP 777 841 * @since 2.7.0 778 842 */ 779 class WP_Http_Streams {843 class WP_Http_Streams extends WP_Http_TransportConcrete { 780 844 /** 781 845 * Send a HTTP request to a URI using streams with fopen(). 782 846 * … … 787 851 * @param str|array $args Optional. Override the defaults. 788 852 * @return array 'headers', 'body', 'cookies' and 'response' keys. 789 853 */ 790 function request($url, $args = array()) { 791 $defaults = array( 792 'method' => 'GET', 'timeout' => 5, 793 'redirection' => 5, 'httpversion' => '1.0', 794 'blocking' => true, 795 'headers' => array(), 'body' => null, 'cookies' => array() 796 ); 854 protected function _request($url, array $args = array()) { 855 $r = $args; # alias parameter @todo rename 797 856 798 $r = wp_parse_args( $args, $defaults );799 800 if ( isset($r['headers']['User-Agent']) ) {801 $r['user-agent'] = $r['headers']['User-Agent'];802 unset($r['headers']['User-Agent']);803 } else if ( isset($r['headers']['user-agent']) ) {804 $r['user-agent'] = $r['headers']['user-agent'];805 unset($r['headers']['user-agent']);806 }807 808 // Construct Cookie: header if any cookies are set809 WP_Http::buildCookieHeader( $r );810 811 857 $arrURL = parse_url($url); 812 858 813 859 if ( false === $arrURL ) … … 931 977 * 932 978 * @return boolean False means this class can not be used, true means it can. 933 979 */ 934 function test($args = array()) { 935 if ( ! function_exists('fopen') || (function_exists('ini_get') && true != ini_get('allow_url_fopen')) ) 936 return false; 937 938 return apply_filters('use_streams_transport', true, $args); 980 static protected function test( array $args = array(), $url = null ) { 981 return !( ! function_exists('fopen') || (function_exists('ini_get') && true != ini_get('allow_url_fopen')) ); 939 982 } 940 983 } 941 984 … … 950 993 * @subpackage HTTP 951 994 * @since 2.7.0 952 995 */ 953 class WP_Http_ExtHttp {996 class WP_Http_ExtHttp extends WP_Http_TransportConcrete { 954 997 /** 955 998 * Send a HTTP request to a URI using HTTP extension. 956 999 * … … 963 1006 * @param str|array $args Optional. Override the defaults. 964 1007 * @return array 'headers', 'body', 'cookies' and 'response' keys. 965 1008 */ 966 function request($url, $args = array()) { 967 $defaults = array( 968 'method' => 'GET', 'timeout' => 5, 969 'redirection' => 5, 'httpversion' => '1.0', 970 'blocking' => true, 971 'headers' => array(), 'body' => null, 'cookies' => array() 972 ); 1009 function _request($url, array $args = array()) { 1010 $r = $args; # alias parameter @todo rename 973 1011 974 $r = wp_parse_args( $args, $defaults );975 976 if ( isset($r['headers']['User-Agent']) ) {977 $r['user-agent'] = $r['headers']['User-Agent'];978 unset($r['headers']['User-Agent']);979 } else if ( isset($r['headers']['user-agent']) ) {980 $r['user-agent'] = $r['headers']['user-agent'];981 unset($r['headers']['user-agent']);982 }983 984 // Construct Cookie: header if any cookies are set985 WP_Http::buildCookieHeader( $r );986 987 1012 switch ( $r['method'] ) { 988 1013 case 'POST': 989 1014 $r['method'] = HTTP_METH_POST; … … 1098 1123 * 1099 1124 * @return boolean False means this class can not be used, true means it can. 1100 1125 */ 1101 function test($args = array()) {1102 return apply_filters('use_http_extension_transport', function_exists('http_request'), $args);1126 protected static function test(array $args = array(), $url = null) { 1127 return function_exists('http_request'); 1103 1128 } 1104 1129 } 1105 1130 … … 1112 1137 * @subpackage HTTP 1113 1138 * @since 2.7 1114 1139 */ 1115 class WP_Http_Curl {1140 class WP_Http_Curl extends WP_Http_TransportConcrete { 1116 1141 1117 1142 /** 1118 1143 * Temporary header storage for use with streaming to a file. … … 1133 1158 * @param str|array $args Optional. Override the defaults. 1134 1159 * @return array 'headers', 'body', 'cookies' and 'response' keys. 1135 1160 */ 1136 function request($url, $args = array()) { 1137 $defaults = array( 1138 'method' => 'GET', 'timeout' => 5, 1139 'redirection' => 5, 'httpversion' => '1.0', 1140 'blocking' => true, 1141 'headers' => array(), 'body' => null, 'cookies' => array() 1142 ); 1161 function _request($url, array $args = array()) { 1162 $r = $args; # alias parameter @todo rename 1143 1163 1144 $r = wp_parse_args( $args, $defaults );1145 1146 if ( isset($r['headers']['User-Agent']) ) {1147 $r['user-agent'] = $r['headers']['User-Agent'];1148 unset($r['headers']['User-Agent']);1149 } else if ( isset($r['headers']['user-agent']) ) {1150 $r['user-agent'] = $r['headers']['user-agent'];1151 unset($r['headers']['user-agent']);1152 }1153 1154 // Construct Cookie: header if any cookies are set.1155 WP_Http::buildCookieHeader( $r );1156 1157 1164 $handle = curl_init(); 1158 1165 1159 1166 // cURL offers really easy proxy support. … … 1314 1321 * 1315 1322 * @return boolean False means this class can not be used, true means it can. 1316 1323 */ 1317 function test($args = array()) { 1318 if ( function_exists('curl_init') && function_exists('curl_exec') ) 1319 return apply_filters('use_curl_transport', true, $args); 1320 1321 return false; 1324 protected static function test(array $args = array(), $url = null) { 1325 return function_exists('curl_init') && function_exists('curl_exec'); 1322 1326 } 1323 1327 } 1324 1328 -
wp-includes/http.php
19 19 * 20 20 * @return WP_Http HTTP Transport object. 21 21 */ 22 function &_wp_http_get_object() {22 function _wp_http_get_object() { 23 23 static $http; 24 25 if ( is_null($http) ) 26 $http = new WP_Http(); 27 28 return $http; 24 return $http ? $http : $http = new WP_Http(); 29 25 } 30 26 31 27 /** … … 56 52 * @return WP_Error|array The response or WP_Error on failure. 57 53 */ 58 54 function wp_remote_request($url, $args = array()) { 59 $objFetchSite = _wp_http_get_object(); 60 return $objFetchSite->request($url, $args); 55 return _wp_http_get_object()->request($url, $args); 61 56 } 62 57 63 58 /** … … 72 67 * @return WP_Error|array The response or WP_Error on failure. 73 68 */ 74 69 function wp_remote_get($url, $args = array()) { 75 $objFetchSite = _wp_http_get_object(); 76 return $objFetchSite->get($url, $args); 70 return _wp_http_get_object()->get($url, $args); 77 71 } 78 72 79 73 /** … … 88 82 * @return WP_Error|array The response or WP_Error on failure. 89 83 */ 90 84 function wp_remote_post($url, $args = array()) { 91 $objFetchSite = _wp_http_get_object(); 92 return $objFetchSite->post($url, $args); 85 return _wp_http_get_object()->post($url, $args); 93 86 } 94 87 95 88 /** … … 104 97 * @return WP_Error|array The response or WP_Error on failure. 105 98 */ 106 99 function wp_remote_head($url, $args = array()) { 107 $objFetchSite = _wp_http_get_object(); 108 return $objFetchSite->head($url, $args); 100 return _wp_http_get_object()->head($url, $args); 109 101 } 110 102 111 103 /** … … 116 108 * @param array $response HTTP response. 117 109 * @return array The headers of the response. Empty array if incorrect parameter given. 118 110 */ 119 function wp_remote_retrieve_headers( &$response) {111 function wp_remote_retrieve_headers($response) { 120 112 if ( is_wp_error($response) || ! isset($response['headers']) || ! is_array($response['headers'])) 121 113 return array(); 122 114 … … 132 124 * @param string $header Header name to retrieve value from. 133 125 * @return string The header value. Empty string on if incorrect parameter given, or if the header doesnt exist. 134 126 */ 135 function wp_remote_retrieve_header( &$response, $header) {127 function wp_remote_retrieve_header($response, $header) { 136 128 if ( is_wp_error($response) || ! isset($response['headers']) || ! is_array($response['headers'])) 137 129 return ''; 138 130 … … 152 144 * @param array $response HTTP response. 153 145 * @return string the response code. Empty string on incorrect parameter given. 154 146 */ 155 function wp_remote_retrieve_response_code( &$response) {147 function wp_remote_retrieve_response_code($response) { 156 148 if ( is_wp_error($response) || ! isset($response['response']) || ! is_array($response['response'])) 157 149 return ''; 158 150 … … 169 161 * @param array $response HTTP response. 170 162 * @return string The response message. Empty string on incorrect parameter given. 171 163 */ 172 function wp_remote_retrieve_response_message( &$response) {164 function wp_remote_retrieve_response_message($response) { 173 165 if ( is_wp_error($response) || ! isset($response['response']) || ! is_array($response['response'])) 174 166 return ''; 175 167 … … 184 176 * @param array $response HTTP response. 185 177 * @return string The body of the response. Empty string if no body or incorrect parameter given. 186 178 */ 187 function wp_remote_retrieve_body( &$response) {179 function wp_remote_retrieve_body($response) { 188 180 if ( is_wp_error($response) || ! isset($response['body']) ) 189 181 return ''; 190 182