mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-10-05 23:27:04 +00:00
Code is Poetry.
WordPress' code just... wasn't. This is now dealt with. Props jrf, pento, netweb, GaryJ, jdgrimes, westonruter, Greg Sherwood from PHPCS, and everyone who's ever contributed to WPCS and PHPCS. Fixes #41057. git-svn-id: https://develop.svn.wordpress.org/trunk@42343 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -26,12 +26,16 @@ class WP_Http_Streams {
|
||||
* @param string|array $args Optional. Override the defaults.
|
||||
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error
|
||||
*/
|
||||
public function request($url, $args = array()) {
|
||||
public function request( $url, $args = array() ) {
|
||||
$defaults = array(
|
||||
'method' => 'GET', 'timeout' => 5,
|
||||
'redirection' => 5, 'httpversion' => '1.0',
|
||||
'blocking' => true,
|
||||
'headers' => array(), 'body' => null, 'cookies' => array()
|
||||
'method' => 'GET',
|
||||
'timeout' => 5,
|
||||
'redirection' => 5,
|
||||
'httpversion' => '1.0',
|
||||
'blocking' => true,
|
||||
'headers' => array(),
|
||||
'body' => null,
|
||||
'cookies' => array(),
|
||||
);
|
||||
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
@@ -47,14 +51,14 @@ class WP_Http_Streams {
|
||||
// Construct Cookie: header if any cookies are set.
|
||||
WP_Http::buildCookieHeader( $r );
|
||||
|
||||
$arrURL = parse_url($url);
|
||||
$arrURL = parse_url( $url );
|
||||
|
||||
$connect_host = $arrURL['host'];
|
||||
|
||||
$secure_transport = ( $arrURL['scheme'] == 'ssl' || $arrURL['scheme'] == 'https' );
|
||||
if ( ! isset( $arrURL['port'] ) ) {
|
||||
if ( $arrURL['scheme'] == 'ssl' || $arrURL['scheme'] == 'https' ) {
|
||||
$arrURL['port'] = 443;
|
||||
$arrURL['port'] = 443;
|
||||
$secure_transport = true;
|
||||
} else {
|
||||
$arrURL['port'] = 80;
|
||||
@@ -67,10 +71,11 @@ class WP_Http_Streams {
|
||||
}
|
||||
|
||||
if ( isset( $r['headers']['Host'] ) || isset( $r['headers']['host'] ) ) {
|
||||
if ( isset( $r['headers']['Host'] ) )
|
||||
if ( isset( $r['headers']['Host'] ) ) {
|
||||
$arrURL['host'] = $r['headers']['Host'];
|
||||
else
|
||||
} else {
|
||||
$arrURL['host'] = $r['headers']['host'];
|
||||
}
|
||||
unset( $r['headers']['Host'], $r['headers']['host'] );
|
||||
}
|
||||
|
||||
@@ -79,12 +84,13 @@ class WP_Http_Streams {
|
||||
* to ::1, which fails when the server is not set up for it. For compatibility, always
|
||||
* connect to the IPv4 address.
|
||||
*/
|
||||
if ( 'localhost' == strtolower( $connect_host ) )
|
||||
if ( 'localhost' == strtolower( $connect_host ) ) {
|
||||
$connect_host = '127.0.0.1';
|
||||
}
|
||||
|
||||
$connect_host = $secure_transport ? 'ssl://' . $connect_host : 'tcp://' . $connect_host;
|
||||
|
||||
$is_local = isset( $r['local'] ) && $r['local'];
|
||||
$is_local = isset( $r['local'] ) && $r['local'];
|
||||
$ssl_verify = isset( $r['sslverify'] ) && $r['sslverify'];
|
||||
if ( $is_local ) {
|
||||
/**
|
||||
@@ -108,19 +114,21 @@ class WP_Http_Streams {
|
||||
|
||||
$proxy = new WP_HTTP_Proxy();
|
||||
|
||||
$context = stream_context_create( array(
|
||||
'ssl' => array(
|
||||
'verify_peer' => $ssl_verify,
|
||||
//'CN_match' => $arrURL['host'], // This is handled by self::verify_ssl_certificate()
|
||||
'capture_peer_cert' => $ssl_verify,
|
||||
'SNI_enabled' => true,
|
||||
'cafile' => $r['sslcertificates'],
|
||||
'allow_self_signed' => ! $ssl_verify,
|
||||
$context = stream_context_create(
|
||||
array(
|
||||
'ssl' => array(
|
||||
'verify_peer' => $ssl_verify,
|
||||
//'CN_match' => $arrURL['host'], // This is handled by self::verify_ssl_certificate()
|
||||
'capture_peer_cert' => $ssl_verify,
|
||||
'SNI_enabled' => true,
|
||||
'cafile' => $r['sslcertificates'],
|
||||
'allow_self_signed' => ! $ssl_verify,
|
||||
),
|
||||
)
|
||||
) );
|
||||
);
|
||||
|
||||
$timeout = (int) floor( $r['timeout'] );
|
||||
$utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000;
|
||||
$timeout = (int) floor( $r['timeout'] );
|
||||
$utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000;
|
||||
$connect_timeout = max( $timeout, 1 );
|
||||
|
||||
// Store error number.
|
||||
@@ -129,52 +137,58 @@ class WP_Http_Streams {
|
||||
// Store error string.
|
||||
$connection_error_str = null;
|
||||
|
||||
if ( !WP_DEBUG ) {
|
||||
if ( ! WP_DEBUG ) {
|
||||
// In the event that the SSL connection fails, silence the many PHP Warnings.
|
||||
if ( $secure_transport )
|
||||
$error_reporting = error_reporting(0);
|
||||
if ( $secure_transport ) {
|
||||
$error_reporting = error_reporting( 0 );
|
||||
}
|
||||
|
||||
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) )
|
||||
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) {
|
||||
$handle = @stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context );
|
||||
else
|
||||
} else {
|
||||
$handle = @stream_socket_client( $connect_host . ':' . $arrURL['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context );
|
||||
}
|
||||
|
||||
if ( $secure_transport )
|
||||
if ( $secure_transport ) {
|
||||
error_reporting( $error_reporting );
|
||||
|
||||
}
|
||||
} else {
|
||||
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) )
|
||||
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) {
|
||||
$handle = stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context );
|
||||
else
|
||||
} else {
|
||||
$handle = stream_socket_client( $connect_host . ':' . $arrURL['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context );
|
||||
}
|
||||
}
|
||||
|
||||
if ( false === $handle ) {
|
||||
// SSL connection failed due to expired/invalid cert, or, OpenSSL configuration is broken.
|
||||
if ( $secure_transport && 0 === $connection_error && '' === $connection_error_str )
|
||||
if ( $secure_transport && 0 === $connection_error && '' === $connection_error_str ) {
|
||||
return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) );
|
||||
}
|
||||
|
||||
return new WP_Error('http_request_failed', $connection_error . ': ' . $connection_error_str );
|
||||
return new WP_Error( 'http_request_failed', $connection_error . ': ' . $connection_error_str );
|
||||
}
|
||||
|
||||
// Verify that the SSL certificate is valid for this request.
|
||||
if ( $secure_transport && $ssl_verify && ! $proxy->is_enabled() ) {
|
||||
if ( ! self::verify_ssl_certificate( $handle, $arrURL['host'] ) )
|
||||
if ( ! self::verify_ssl_certificate( $handle, $arrURL['host'] ) ) {
|
||||
return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
stream_set_timeout( $handle, $timeout, $utimeout );
|
||||
|
||||
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) //Some proxies require full URL in this field.
|
||||
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { //Some proxies require full URL in this field.
|
||||
$requestPath = $url;
|
||||
else
|
||||
$requestPath = $arrURL['path'] . ( isset($arrURL['query']) ? '?' . $arrURL['query'] : '' );
|
||||
} else {
|
||||
$requestPath = $arrURL['path'] . ( isset( $arrURL['query'] ) ? '?' . $arrURL['query'] : '' );
|
||||
}
|
||||
|
||||
$strHeaders = strtoupper($r['method']) . ' ' . $requestPath . ' HTTP/' . $r['httpversion'] . "\r\n";
|
||||
$strHeaders = strtoupper( $r['method'] ) . ' ' . $requestPath . ' HTTP/' . $r['httpversion'] . "\r\n";
|
||||
|
||||
$include_port_in_host_header = (
|
||||
( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) ||
|
||||
( 'http' == $arrURL['scheme'] && 80 != $arrURL['port'] ) ||
|
||||
( 'http' == $arrURL['scheme'] && 80 != $arrURL['port'] ) ||
|
||||
( 'https' == $arrURL['scheme'] && 443 != $arrURL['port'] )
|
||||
);
|
||||
|
||||
@@ -184,63 +198,79 @@ class WP_Http_Streams {
|
||||
$strHeaders .= 'Host: ' . $arrURL['host'] . "\r\n";
|
||||
}
|
||||
|
||||
if ( isset($r['user-agent']) )
|
||||
if ( isset( $r['user-agent'] ) ) {
|
||||
$strHeaders .= 'User-agent: ' . $r['user-agent'] . "\r\n";
|
||||
}
|
||||
|
||||
if ( is_array($r['headers']) ) {
|
||||
foreach ( (array) $r['headers'] as $header => $headerValue )
|
||||
if ( is_array( $r['headers'] ) ) {
|
||||
foreach ( (array) $r['headers'] as $header => $headerValue ) {
|
||||
$strHeaders .= $header . ': ' . $headerValue . "\r\n";
|
||||
}
|
||||
} else {
|
||||
$strHeaders .= $r['headers'];
|
||||
}
|
||||
|
||||
if ( $proxy->use_authentication() )
|
||||
if ( $proxy->use_authentication() ) {
|
||||
$strHeaders .= $proxy->authentication_header() . "\r\n";
|
||||
}
|
||||
|
||||
$strHeaders .= "\r\n";
|
||||
|
||||
if ( ! is_null($r['body']) )
|
||||
if ( ! is_null( $r['body'] ) ) {
|
||||
$strHeaders .= $r['body'];
|
||||
}
|
||||
|
||||
fwrite($handle, $strHeaders);
|
||||
fwrite( $handle, $strHeaders );
|
||||
|
||||
if ( ! $r['blocking'] ) {
|
||||
stream_set_blocking( $handle, 0 );
|
||||
fclose( $handle );
|
||||
return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() );
|
||||
return array(
|
||||
'headers' => array(),
|
||||
'body' => '',
|
||||
'response' => array(
|
||||
'code' => false,
|
||||
'message' => false,
|
||||
),
|
||||
'cookies' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
$strResponse = '';
|
||||
$bodyStarted = false;
|
||||
$strResponse = '';
|
||||
$bodyStarted = false;
|
||||
$keep_reading = true;
|
||||
$block_size = 4096;
|
||||
if ( isset( $r['limit_response_size'] ) )
|
||||
$block_size = 4096;
|
||||
if ( isset( $r['limit_response_size'] ) ) {
|
||||
$block_size = min( $block_size, $r['limit_response_size'] );
|
||||
}
|
||||
|
||||
// If streaming to a file setup the file handle.
|
||||
if ( $r['stream'] ) {
|
||||
if ( ! WP_DEBUG )
|
||||
if ( ! WP_DEBUG ) {
|
||||
$stream_handle = @fopen( $r['filename'], 'w+' );
|
||||
else
|
||||
} else {
|
||||
$stream_handle = fopen( $r['filename'], 'w+' );
|
||||
}
|
||||
if ( ! $stream_handle ) {
|
||||
return new WP_Error( 'http_request_failed', sprintf(
|
||||
/* translators: 1: fopen() 2: file name */
|
||||
__( 'Could not open handle for %1$s to %2$s.' ),
|
||||
'fopen()',
|
||||
$r['filename']
|
||||
) );
|
||||
return new WP_Error(
|
||||
'http_request_failed', sprintf(
|
||||
/* translators: 1: fopen() 2: file name */
|
||||
__( 'Could not open handle for %1$s to %2$s.' ),
|
||||
'fopen()',
|
||||
$r['filename']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$bytes_written = 0;
|
||||
while ( ! feof($handle) && $keep_reading ) {
|
||||
while ( ! feof( $handle ) && $keep_reading ) {
|
||||
$block = fread( $handle, $block_size );
|
||||
if ( ! $bodyStarted ) {
|
||||
$strResponse .= $block;
|
||||
if ( strpos( $strResponse, "\r\n\r\n" ) ) {
|
||||
$process = WP_Http::processResponse( $strResponse );
|
||||
$process = WP_Http::processResponse( $strResponse );
|
||||
$bodyStarted = true;
|
||||
$block = $process['body'];
|
||||
$block = $process['body'];
|
||||
unset( $strResponse );
|
||||
$process['body'] = '';
|
||||
}
|
||||
@@ -250,7 +280,7 @@ class WP_Http_Streams {
|
||||
|
||||
if ( isset( $r['limit_response_size'] ) && ( $bytes_written + $this_block_size ) > $r['limit_response_size'] ) {
|
||||
$this_block_size = ( $r['limit_response_size'] - $bytes_written );
|
||||
$block = substr( $block, 0, $this_block_size );
|
||||
$block = substr( $block, 0, $this_block_size );
|
||||
}
|
||||
|
||||
$bytes_written_to_file = fwrite( $stream_handle, $block );
|
||||
@@ -263,7 +293,7 @@ class WP_Http_Streams {
|
||||
|
||||
$bytes_written += $bytes_written_to_file;
|
||||
|
||||
$keep_reading = !isset( $r['limit_response_size'] ) || $bytes_written < $r['limit_response_size'];
|
||||
$keep_reading = ! isset( $r['limit_response_size'] ) || $bytes_written < $r['limit_response_size'];
|
||||
}
|
||||
|
||||
fclose( $stream_handle );
|
||||
@@ -271,13 +301,13 @@ class WP_Http_Streams {
|
||||
} else {
|
||||
$header_length = 0;
|
||||
while ( ! feof( $handle ) && $keep_reading ) {
|
||||
$block = fread( $handle, $block_size );
|
||||
$block = fread( $handle, $block_size );
|
||||
$strResponse .= $block;
|
||||
if ( ! $bodyStarted && strpos( $strResponse, "\r\n\r\n" ) ) {
|
||||
$header_length = strpos( $strResponse, "\r\n\r\n" ) + 4;
|
||||
$bodyStarted = true;
|
||||
$bodyStarted = true;
|
||||
}
|
||||
$keep_reading = ( ! $bodyStarted || !isset( $r['limit_response_size'] ) || strlen( $strResponse ) < ( $header_length + $r['limit_response_size'] ) );
|
||||
$keep_reading = ( ! $bodyStarted || ! isset( $r['limit_response_size'] ) || strlen( $strResponse ) < ( $header_length + $r['limit_response_size'] ) );
|
||||
}
|
||||
|
||||
$process = WP_Http::processResponse( $strResponse );
|
||||
@@ -290,27 +320,31 @@ class WP_Http_Streams {
|
||||
$arrHeaders = WP_Http::processHeaders( $process['headers'], $url );
|
||||
|
||||
$response = array(
|
||||
'headers' => $arrHeaders['headers'],
|
||||
'headers' => $arrHeaders['headers'],
|
||||
// Not yet processed.
|
||||
'body' => null,
|
||||
'body' => null,
|
||||
'response' => $arrHeaders['response'],
|
||||
'cookies' => $arrHeaders['cookies'],
|
||||
'filename' => $r['filename']
|
||||
'cookies' => $arrHeaders['cookies'],
|
||||
'filename' => $r['filename'],
|
||||
);
|
||||
|
||||
// Handle redirects.
|
||||
if ( false !== ( $redirect_response = WP_Http::handle_redirects( $url, $r, $response ) ) )
|
||||
if ( false !== ( $redirect_response = WP_Http::handle_redirects( $url, $r, $response ) ) ) {
|
||||
return $redirect_response;
|
||||
}
|
||||
|
||||
// If the body was chunk encoded, then decode it.
|
||||
if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] )
|
||||
$process['body'] = WP_Http::chunkTransferDecode($process['body']);
|
||||
if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] ) {
|
||||
$process['body'] = WP_Http::chunkTransferDecode( $process['body'] );
|
||||
}
|
||||
|
||||
if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders['headers']) )
|
||||
if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode( $arrHeaders['headers'] ) ) {
|
||||
$process['body'] = WP_Http_Encoding::decompress( $process['body'] );
|
||||
}
|
||||
|
||||
if ( isset( $r['limit_response_size'] ) && strlen( $process['body'] ) > $r['limit_response_size'] )
|
||||
if ( isset( $r['limit_response_size'] ) && strlen( $process['body'] ) > $r['limit_response_size'] ) {
|
||||
$process['body'] = substr( $process['body'], 0, $r['limit_response_size'] );
|
||||
}
|
||||
|
||||
$response['body'] = $process['body'];
|
||||
|
||||
@@ -337,12 +371,14 @@ class WP_Http_Streams {
|
||||
public static function verify_ssl_certificate( $stream, $host ) {
|
||||
$context_options = stream_context_get_options( $stream );
|
||||
|
||||
if ( empty( $context_options['ssl']['peer_certificate'] ) )
|
||||
if ( empty( $context_options['ssl']['peer_certificate'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cert = openssl_x509_parse( $context_options['ssl']['peer_certificate'] );
|
||||
if ( ! $cert )
|
||||
if ( ! $cert ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the request is being made to an IP address, we'll validate against IP fields
|
||||
@@ -355,25 +391,29 @@ class WP_Http_Streams {
|
||||
$match_against = preg_split( '/,\s*/', $cert['extensions']['subjectAltName'] );
|
||||
foreach ( $match_against as $match ) {
|
||||
list( $match_type, $match_host ) = explode( ':', $match );
|
||||
if ( $host_type == strtolower( trim( $match_type ) ) ) // IP: or DNS:
|
||||
if ( $host_type == strtolower( trim( $match_type ) ) ) { // IP: or DNS:
|
||||
$certificate_hostnames[] = strtolower( trim( $match_host ) );
|
||||
}
|
||||
}
|
||||
} elseif ( !empty( $cert['subject']['CN'] ) ) {
|
||||
} elseif ( ! empty( $cert['subject']['CN'] ) ) {
|
||||
// Only use the CN when the certificate includes no subjectAltName extension.
|
||||
$certificate_hostnames[] = strtolower( $cert['subject']['CN'] );
|
||||
}
|
||||
|
||||
// Exact hostname/IP matches.
|
||||
if ( in_array( strtolower( $host ), $certificate_hostnames ) )
|
||||
if ( in_array( strtolower( $host ), $certificate_hostnames ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// IP's can't be wildcards, Stop processing.
|
||||
if ( 'ip' == $host_type )
|
||||
if ( 'ip' == $host_type ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test to see if the domain is at least 2 deep for wildcard support.
|
||||
if ( substr_count( $host, '.' ) < 2 )
|
||||
if ( substr_count( $host, '.' ) < 2 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wildcard subdomains certs (*.example.com) are valid for a.example.com but not a.b.example.com.
|
||||
$wildcard_host = preg_replace( '/^[^.]+\./', '*.', $host );
|
||||
@@ -392,16 +432,19 @@ class WP_Http_Streams {
|
||||
* @return bool False means this class can not be used, true means it can.
|
||||
*/
|
||||
public static function test( $args = array() ) {
|
||||
if ( ! function_exists( 'stream_socket_client' ) )
|
||||
if ( ! function_exists( 'stream_socket_client' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$is_ssl = isset( $args['ssl'] ) && $args['ssl'];
|
||||
|
||||
if ( $is_ssl ) {
|
||||
if ( ! extension_loaded( 'openssl' ) )
|
||||
if ( ! extension_loaded( 'openssl' ) ) {
|
||||
return false;
|
||||
if ( ! function_exists( 'openssl_x509_parse' ) )
|
||||
}
|
||||
if ( ! function_exists( 'openssl_x509_parse' ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user