Ticket #34538: 35553.patch
File 35553.patch, 14.3 KB (added by , 9 years ago) |
---|
-
src/wp-includes/class-http.php
140 140 $args = wp_parse_args( $args ); 141 141 142 142 // By default, Head requests do not cause redirections. 143 if ( isset( $args['method']) && 'HEAD' == $args['method'] )143 if ( isset( $args['method'] ) && 'HEAD' == $args['method'] ) 144 144 $defaults['redirection'] = 0; 145 145 146 146 $r = wp_parse_args( $args, $defaults ); … … 192 192 $arrURL = @parse_url( $url ); 193 193 194 194 if ( empty( $url ) || empty( $arrURL['scheme'] ) ) 195 return new WP_Error( 'http_request_failed', __('A valid URL was not provided.'));195 return new WP_Error( 'http_request_failed', __( 'A valid URL was not provided.' ) ); 196 196 197 197 if ( $this->block_request( $url ) ) 198 198 return new WP_Error( 'http_request_failed', __( 'User has blocked requests through HTTP.' ) ); … … 244 244 unset( $r['headers']['user-agent'] ); 245 245 } 246 246 247 if ( '1.1' == $r['httpversion'] && ! isset( $r['headers']['connection'] ) ) {247 if ( '1.1' == $r['httpversion'] && ! isset( $r['headers']['connection'] ) ) { 248 248 $r['headers']['connection'] = 'close'; 249 249 } 250 250 … … 327 327 $class = 'WP_Http_' . $transport; 328 328 329 329 // Check to see if this transport is a possibility, calls the transport statically. 330 if ( ! call_user_func( array( $class, 'test' ), $args, $url ) )330 if ( ! call_user_func( array( $class, 'test' ), $args, $url ) ) 331 331 continue; 332 332 333 333 return $class; … … 357 357 static $transports = array(); 358 358 359 359 $class = $this->_get_first_available_transport( $args, $url ); 360 if ( ! $class )360 if ( ! $class ) 361 361 return new WP_Error( 'http_failure', __( 'There are no HTTP transports available which can complete the requested request.' ) ); 362 362 363 363 // Transport claims to support request, instantiate it and give it a whirl. … … 406 406 * @param string|array $args Optional. Override the defaults. 407 407 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error 408 408 */ 409 public function post( $url, $args = array()) {410 $defaults = array( 'method' => 'POST');409 public function post( $url, $args = array() ) { 410 $defaults = array( 'method' => 'POST' ); 411 411 $r = wp_parse_args( $args, $defaults ); 412 return $this->request( $url, $r);412 return $this->request( $url, $r ); 413 413 } 414 414 415 415 /** … … 424 424 * @param string|array $args Optional. Override the defaults. 425 425 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error 426 426 */ 427 public function get( $url, $args = array()) {428 $defaults = array( 'method' => 'GET');427 public function get( $url, $args = array() ) { 428 $defaults = array( 'method' => 'GET' ); 429 429 $r = wp_parse_args( $args, $defaults ); 430 return $this->request( $url, $r);430 return $this->request( $url, $r ); 431 431 } 432 432 433 433 /** … … 442 442 * @param string|array $args Optional. Override the defaults. 443 443 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error 444 444 */ 445 public function head( $url, $args = array()) {446 $defaults = array( 'method' => 'HEAD');445 public function head( $url, $args = array() ) { 446 $defaults = array( 'method' => 'HEAD' ); 447 447 $r = wp_parse_args( $args, $defaults ); 448 return $this->request( $url, $r);448 return $this->request( $url, $r ); 449 449 } 450 450 451 451 /** … … 458 458 * @param string $strResponse The full response string 459 459 * @return array Array with 'headers' and 'body' keys. 460 460 */ 461 public static function processResponse( $strResponse) {462 $res = explode( "\r\n\r\n", $strResponse, 2);461 public static function processResponse( $strResponse ) { 462 $res = explode( "\r\n\r\n", $strResponse, 2 ); 463 463 464 return array( 'headers' => $res[0], 'body' => isset($res[1]) ? $res[1] : '');464 return array( 'headers' => $res[0], 'body' => isset( $res[1] ) ? $res[1] : '' ); 465 465 } 466 466 467 467 /** … … 481 481 */ 482 482 public static function processHeaders( $headers, $url = '' ) { 483 483 // Split headers, one per array element. 484 if ( is_string( $headers) ) {484 if ( is_string( $headers ) ) { 485 485 // Tolerate line terminator: CRLF = LF (RFC 2616 19.3). 486 $headers = str_replace( "\r\n", "\n", $headers);486 $headers = str_replace( "\r\n", "\n", $headers ); 487 487 /* 488 488 * Unfold folded header fields. LWS = [CRLF] 1*( SP | HT ) <US-ASCII SP, space (32)>, 489 489 * <US-ASCII HT, horizontal-tab (9)> (RFC 2616 2.2). 490 490 */ 491 $headers = preg_replace( '/\n[ \t]/', ' ', $headers);491 $headers = preg_replace( '/\n[ \t]/', ' ', $headers ); 492 492 // Create the headers array. 493 $headers = explode( "\n", $headers);493 $headers = explode( "\n", $headers ); 494 494 } 495 495 496 $response = array( 'code' => 0, 'message' => '');496 $response = array( 'code' => 0, 'message' => '' ); 497 497 498 498 /* 499 499 * If a redirection has taken place, The headers for each page request may have been passed. 500 500 * In this case, determine the final HTTP header and parse from there. 501 501 */ 502 for ( $i = count( $headers)-1; $i >= 0; $i-- ) {503 if ( ! empty($headers[$i]) && false === strpos($headers[$i], ':') ) {504 $headers = array_splice( $headers, $i);502 for ( $i = count( $headers )-1; $i >= 0; $i-- ) { 503 if ( ! empty( $headers[$i] ) && false === strpos( $headers[$i], ':' ) ) { 504 $headers = array_splice( $headers, $i ); 505 505 break; 506 506 } 507 507 } … … 509 509 $cookies = array(); 510 510 $newheaders = array(); 511 511 foreach ( (array) $headers as $tempheader ) { 512 if ( empty( $tempheader) )512 if ( empty( $tempheader ) ) 513 513 continue; 514 514 515 if ( false === strpos( $tempheader, ':') ) {516 $stack = explode( ' ', $tempheader, 3);515 if ( false === strpos( $tempheader, ':' ) ) { 516 $stack = explode( ' ', $tempheader, 3 ); 517 517 $stack[] = ''; 518 list( , $response['code'], $response['message'] ) = $stack;518 list( , $response['code'], $response['message'] ) = $stack; 519 519 continue; 520 520 } 521 521 522 list( $key, $value) = explode(':', $tempheader, 2);522 list( $key, $value ) = explode( ':', $tempheader, 2 ); 523 523 524 524 $key = strtolower( $key ); 525 525 $value = trim( $value ); … … 538 538 // Cast the Response Code to an int 539 539 $response['code'] = intval( $response['code'] ); 540 540 541 return array( 'response' => $response, 'headers' => $newheaders, 'cookies' => $cookies);541 return array( 'response' => $response, 'headers' => $newheaders, 'cookies' => $cookies ); 542 542 } 543 543 544 544 /** … … 555 555 * @param array $r Full array of args passed into ::request() 556 556 */ 557 557 public static function buildCookieHeader( &$r ) { 558 if ( ! empty( $r['cookies']) ) {558 if ( ! empty( $r['cookies'] ) ) { 559 559 // Upgrade any name => value cookie pairs to WP_HTTP_Cookie instances. 560 560 foreach ( $r['cookies'] as $name => $value ) { 561 561 if ( ! is_object( $value ) ) … … 638 638 * @param string $uri URI of url. 639 639 * @return bool True to block, false to allow. 640 640 */ 641 public function block_request( $uri) {641 public function block_request( $uri ) { 642 642 // We don't need to block requests, because nothing is blocked. 643 643 if ( ! defined( 'WP_HTTP_BLOCK_EXTERNAL' ) || ! WP_HTTP_BLOCK_EXTERNAL ) 644 644 return false; 645 645 646 $check = parse_url( $uri);646 $check = parse_url( $uri ); 647 647 if ( ! $check ) 648 648 return true; 649 649 650 $home = parse_url( get_option( 'siteurl') );650 $home = parse_url( get_option( 'siteurl' ) ); 651 651 652 652 // Don't block requests back to ourselves by default. 653 653 if ( 'localhost' == $check['host'] || ( isset( $home['host'] ) && $home['host'] == $check['host'] ) ) { … … 662 662 return apply_filters( 'block_local_requests', false ); 663 663 } 664 664 665 if ( ! defined('WP_ACCESSIBLE_HOSTS') )665 if ( ! defined( 'WP_ACCESSIBLE_HOSTS' ) ) 666 666 return true; 667 667 668 668 static $accessible_hosts = null; 669 669 static $wildcard_regex = array(); 670 670 if ( null === $accessible_hosts ) { 671 $accessible_hosts = preg_split( '|,\s*|', WP_ACCESSIBLE_HOSTS);671 $accessible_hosts = preg_split( '|,\s*|', WP_ACCESSIBLE_HOSTS ); 672 672 673 if ( false !== strpos( WP_ACCESSIBLE_HOSTS, '*') ) {673 if ( false !== strpos( WP_ACCESSIBLE_HOSTS, '*' ) ) { 674 674 $wildcard_regex = array(); 675 675 foreach ( $accessible_hosts as $host ) 676 676 $wildcard_regex[] = str_replace( '\*', '.+', preg_quote( $host, '/' ) ); 677 $wildcard_regex = '/^(' . implode( '|', $wildcard_regex) . ')$/i';677 $wildcard_regex = '/^(' . implode( '|', $wildcard_regex ) . ')$/i'; 678 678 } 679 679 } 680 680 681 if ( ! empty($wildcard_regex) )682 return !preg_match( $wildcard_regex, $check['host']);681 if ( ! empty( $wildcard_regex ) ) 682 return !preg_match( $wildcard_regex, $check['host'] ); 683 683 else 684 684 return !in_array( $check['host'], $accessible_hosts ); //Inverse logic, If it's in the array, then we can't access it. 685 685 … … 799 799 800 800 // Don't redirect if we've run out of redirects. 801 801 if ( $args['redirection']-- <= 0 ) 802 return new WP_Error( 'http_request_failed', __( 'Too many redirects.') );802 return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) ); 803 803 804 804 $redirect_location = $response['headers']['location']; 805 805 … … 843 843 * @return integer|bool Upon success, '4' or '6' to represent a IPv4 or IPv6 address, false upon failure 844 844 */ 845 845 public static function is_ip_address( $maybe_ip ) { 846 if ( preg_match( '/^ \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $maybe_ip ) )846 if ( preg_match( '/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/', $maybe_ip ) ) 847 847 return 4; 848 848 849 849 if ( false !== strpos( $maybe_ip, ':' ) && preg_match( '/^(((?=.*(::))(?!.*\3.+\3))\3?|([\dA-F]{1,4}(\3|:\b|$)|\2))(?4){5}((?4){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i', trim( $maybe_ip, ' []' ) ) ) -
tests/phpunit/tests/http/http.php
102 102 - ://example.com - assumed path in PHP >= 5.4.7, fails in <5.4.7 103 103 */ 104 104 } 105 106 /** 107 * @dataProvider ip_address_testcases 108 */ 109 function test_is_ip_address( $maybe_ip, $expected ) { 110 $actual = WP_Http::is_ip_address( $maybe_ip ); 111 $this->assertEquals( $expected, $actual ); 112 } 113 114 function ip_address_testcases() { 115 // 0: The IP Address, 1: The expected resulting 116 return array( 117 // Valid IPv4 address 118 // See: http://tools.ietf.org/html/rfc5737 119 array( '0.0.0.0', 4 ), 120 array( '127.0.0.1', 4 ), // The loopback address 121 array( '192.0.2.0', 4 ), // RFC 5737 - IPv4 Address Blocks Reserved for Documentation 122 array( '198.51.100.0', 4 ), // RFC 5737 - IPv4 Address Blocks Reserved for Documentation 123 array( '203.0.113.0', 4 ), // RFC 5737 - IPv4 Address Blocks Reserved for Documentation 124 array( '255.255.255.255', 4 ), 125 126 // Invalid IPv4 address 127 array( '256.255.255.255', false ), // The first octet is out of range 128 array( '255.256.255.255', false ), // The second octet is out of range 129 array( '255.255.256.255', false ), // The third octet is out of range 130 array( '255.255.255.256', false ), // The fourth octet is out of range 131 array( '999.999.999.999', false ), // All octet is out of range 132 array( '2000.1.1.1', false ), 133 array( '1.2000.1.1', false ), 134 array( '1.1.2000.1', false ), 135 array( '1.1.1.2000', false ), 136 array( '2000.2000.2000.2000', false ), 137 138 // Valid IPv6 address 139 // See: http://tools.ietf.org/html/rfc4291 140 array( '0:0:0:0:0:0:0:0', 6 ), // The unspecified address 141 array( '::', 6 ), // The unspecified address (in compressed form) 142 array( '0:0:0:0:0:0:0:1', 6 ), // The loopback address 143 array( '::1', 6 ), // The loopback address (in compressed form) 144 array( '2001:db8::', 6 ), // RFC 3849 - IPv6 Address Prefix Reserved for Documentation 145 array( '2001:0db8:0000:0000:0000:0000:dead:beaf', 6 ), 146 array( '2001:db8:0:0:0:0:dead:beaf', 6 ), 147 array( '2001:db8::dead:beaf', 6 ), 148 array( 'ABCD:EF01:2345:6789:ABCD:EF01:2345:6789', 6 ), // RFC 4291 - Example 149 array( '2001:DB8:0:0:8:800:200C:417A', 6 ), // RFC 4291 - Example of unicast address 150 array( '2001:DB8::8:800:200C:417A', 6 ), // RFC 4291 - Example of unicast address (in compressed form) 151 array( 'FF01:0:0:0:0:0:0:101', 6 ), // RFC 4291 - Example of multicast address 152 array( 'FF01::101', 6 ), // RFC 4291 - Example of multicast address (in compressed form) 153 array( '0:0:0:0:0:0:13.1.68.3', 6 ), // RFC 4291 - Example of an alternative form with a mixed environment of IPv4 and IPv6 nodes 154 array( '::13.1.68.3', 6 ), // RFC 4291 - Example of an alternative form with a mixed environment of IPv4 and IPv6 nodes (in compressed form) 155 array( '0:0:0:0:0:FFFF:129.144.52.38', 6 ), // RFC 4291 - Example of an alternative form with a mixed environment of IPv4 and IPv6 nodes 156 array( '::FFFF:129.144.52.38', 6 ), // RFC 4291 - Example of an alternative form with a mixed environment of IPv4 and IPv6 nodes (in compressed form) 157 158 // Invalid IPv6 address 159 // See: https://github.com/richb-intermapper/IPv6-Regex 160 array( '2001:DB8:0:0:8:800:200C:417A:221', false ), // unicast full 161 array( 'FF01::101::2', false ), // multicast compressed 162 array( '02001:0000:1234:0000:0000:C1C0:ABCD:0876', false ), // extra 0 not allowed 163 array( '2001:0000:1234:0000:00001:C1C0:ABCD:0876', false ), // extra 0 not allowed 164 array( '2001:0000:1234:0000:0000:C1C0:ABCD:0876 0', false ), // junk after valid address 165 array( '2001:0000:1234: 0000:0000:C1C0:ABCD:0876', false ), // internal space 166 array( '3ffe:0b00:0000:0001:0000:0000:000a', false ), // Segments is less than 8 167 array( 'FF02:0000:0000:0000:0000:0000:0000:0000:0001', false ), // Segments is over 8 168 array( '3ffe:b00::1::a', false ), // Compressed double 169 array( '::1111:2222:3333:4444:5555:6666::', false ), // Compressed double 170 array( '1::5:400.2.3.4', false ), // Embedded ipv4 address is out of range 171 array( '1::5:192.168.0.256', false ), // Embedded ipv4 address is out of range 172 array( '2001:1:1:1:1:1:255Z255X255Y255', false ), // garbage instead of "." in IPv4 173 array( '::ffff:192x168.1.26', false ), // ditto 174 array( '::ffff:2.3.4', false ), // has ipv4 octet lost 175 array( '1.2.3.4:1111:2222:3333:4444::5555', false ), // Aeron 176 array( ':', false ), 177 array( ':::', false ), 178 179 // other 180 array( '123', false ), 181 array( 'ldkfj', false ), 182 array( '.', false ), 183 array( '..', false ), 184 array( '...', false ), 185 186 ); 187 } 105 188 }