Changeset 42343 for trunk/src/wp-includes/class-wp-http-streams.php
- Timestamp:
- 11/30/2017 11:09:33 PM (8 years ago)
- File:
-
- 1 edited
-
trunk/src/wp-includes/class-wp-http-streams.php (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-http-streams.php
r41901 r42343 27 27 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error 28 28 */ 29 public function request( $url, $args = array()) {29 public function request( $url, $args = array() ) { 30 30 $defaults = array( 31 'method' => 'GET', 'timeout' => 5, 32 'redirection' => 5, 'httpversion' => '1.0', 33 'blocking' => true, 34 'headers' => array(), 'body' => null, 'cookies' => array() 31 'method' => 'GET', 32 'timeout' => 5, 33 'redirection' => 5, 34 'httpversion' => '1.0', 35 'blocking' => true, 36 'headers' => array(), 37 'body' => null, 38 'cookies' => array(), 35 39 ); 36 40 … … 48 52 WP_Http::buildCookieHeader( $r ); 49 53 50 $arrURL = parse_url( $url);54 $arrURL = parse_url( $url ); 51 55 52 56 $connect_host = $arrURL['host']; … … 55 59 if ( ! isset( $arrURL['port'] ) ) { 56 60 if ( $arrURL['scheme'] == 'ssl' || $arrURL['scheme'] == 'https' ) { 57 $arrURL['port'] = 443;61 $arrURL['port'] = 443; 58 62 $secure_transport = true; 59 63 } else { … … 68 72 69 73 if ( isset( $r['headers']['Host'] ) || isset( $r['headers']['host'] ) ) { 70 if ( isset( $r['headers']['Host'] ) ) 74 if ( isset( $r['headers']['Host'] ) ) { 71 75 $arrURL['host'] = $r['headers']['Host']; 72 else76 } else { 73 77 $arrURL['host'] = $r['headers']['host']; 78 } 74 79 unset( $r['headers']['Host'], $r['headers']['host'] ); 75 80 } … … 80 85 * connect to the IPv4 address. 81 86 */ 82 if ( 'localhost' == strtolower( $connect_host ) ) 87 if ( 'localhost' == strtolower( $connect_host ) ) { 83 88 $connect_host = '127.0.0.1'; 89 } 84 90 85 91 $connect_host = $secure_transport ? 'ssl://' . $connect_host : 'tcp://' . $connect_host; 86 92 87 $is_local = isset( $r['local'] ) && $r['local'];93 $is_local = isset( $r['local'] ) && $r['local']; 88 94 $ssl_verify = isset( $r['sslverify'] ) && $r['sslverify']; 89 95 if ( $is_local ) { … … 109 115 $proxy = new WP_HTTP_Proxy(); 110 116 111 $context = stream_context_create( array( 112 'ssl' => array( 113 'verify_peer' => $ssl_verify, 114 //'CN_match' => $arrURL['host'], // This is handled by self::verify_ssl_certificate() 115 'capture_peer_cert' => $ssl_verify, 116 'SNI_enabled' => true, 117 'cafile' => $r['sslcertificates'], 118 'allow_self_signed' => ! $ssl_verify, 117 $context = stream_context_create( 118 array( 119 'ssl' => array( 120 'verify_peer' => $ssl_verify, 121 //'CN_match' => $arrURL['host'], // This is handled by self::verify_ssl_certificate() 122 'capture_peer_cert' => $ssl_verify, 123 'SNI_enabled' => true, 124 'cafile' => $r['sslcertificates'], 125 'allow_self_signed' => ! $ssl_verify, 126 ), 119 127 ) 120 ) );121 122 $timeout = (int) floor( $r['timeout'] );123 $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000;128 ); 129 130 $timeout = (int) floor( $r['timeout'] ); 131 $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000; 124 132 $connect_timeout = max( $timeout, 1 ); 125 133 … … 130 138 $connection_error_str = null; 131 139 132 if ( ! WP_DEBUG ) {140 if ( ! WP_DEBUG ) { 133 141 // In the event that the SSL connection fails, silence the many PHP Warnings. 134 if ( $secure_transport ) 135 $error_reporting = error_reporting(0); 136 137 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) 142 if ( $secure_transport ) { 143 $error_reporting = error_reporting( 0 ); 144 } 145 146 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { 138 147 $handle = @stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); 139 else148 } else { 140 149 $handle = @stream_socket_client( $connect_host . ':' . $arrURL['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); 141 142 if ( $secure_transport ) 150 } 151 152 if ( $secure_transport ) { 143 153 error_reporting( $error_reporting ); 144 154 } 145 155 } else { 146 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) 156 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { 147 157 $handle = stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); 148 else158 } else { 149 159 $handle = stream_socket_client( $connect_host . ':' . $arrURL['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); 160 } 150 161 } 151 162 152 163 if ( false === $handle ) { 153 164 // SSL connection failed due to expired/invalid cert, or, OpenSSL configuration is broken. 154 if ( $secure_transport && 0 === $connection_error && '' === $connection_error_str ) 165 if ( $secure_transport && 0 === $connection_error && '' === $connection_error_str ) { 155 166 return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) ); 156 157 return new WP_Error('http_request_failed', $connection_error . ': ' . $connection_error_str ); 167 } 168 169 return new WP_Error( 'http_request_failed', $connection_error . ': ' . $connection_error_str ); 158 170 } 159 171 160 172 // Verify that the SSL certificate is valid for this request. 161 173 if ( $secure_transport && $ssl_verify && ! $proxy->is_enabled() ) { 162 if ( ! self::verify_ssl_certificate( $handle, $arrURL['host'] ) ) 174 if ( ! self::verify_ssl_certificate( $handle, $arrURL['host'] ) ) { 163 175 return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) ); 176 } 164 177 } 165 178 166 179 stream_set_timeout( $handle, $timeout, $utimeout ); 167 180 168 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) //Some proxies require full URL in this field.181 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { //Some proxies require full URL in this field. 169 182 $requestPath = $url; 170 else 171 $requestPath = $arrURL['path'] . ( isset($arrURL['query']) ? '?' . $arrURL['query'] : '' ); 172 173 $strHeaders = strtoupper($r['method']) . ' ' . $requestPath . ' HTTP/' . $r['httpversion'] . "\r\n"; 183 } else { 184 $requestPath = $arrURL['path'] . ( isset( $arrURL['query'] ) ? '?' . $arrURL['query'] : '' ); 185 } 186 187 $strHeaders = strtoupper( $r['method'] ) . ' ' . $requestPath . ' HTTP/' . $r['httpversion'] . "\r\n"; 174 188 175 189 $include_port_in_host_header = ( 176 190 ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) || 177 ( 'http' == $arrURL['scheme'] && 80!= $arrURL['port'] ) ||191 ( 'http' == $arrURL['scheme'] && 80 != $arrURL['port'] ) || 178 192 ( 'https' == $arrURL['scheme'] && 443 != $arrURL['port'] ) 179 193 ); … … 185 199 } 186 200 187 if ( isset( $r['user-agent']) )201 if ( isset( $r['user-agent'] ) ) { 188 202 $strHeaders .= 'User-agent: ' . $r['user-agent'] . "\r\n"; 189 190 if ( is_array($r['headers']) ) { 191 foreach ( (array) $r['headers'] as $header => $headerValue ) 203 } 204 205 if ( is_array( $r['headers'] ) ) { 206 foreach ( (array) $r['headers'] as $header => $headerValue ) { 192 207 $strHeaders .= $header . ': ' . $headerValue . "\r\n"; 208 } 193 209 } else { 194 210 $strHeaders .= $r['headers']; 195 211 } 196 212 197 if ( $proxy->use_authentication() ) 213 if ( $proxy->use_authentication() ) { 198 214 $strHeaders .= $proxy->authentication_header() . "\r\n"; 215 } 199 216 200 217 $strHeaders .= "\r\n"; 201 218 202 if ( ! is_null( $r['body']) )219 if ( ! is_null( $r['body'] ) ) { 203 220 $strHeaders .= $r['body']; 204 205 fwrite($handle, $strHeaders); 221 } 222 223 fwrite( $handle, $strHeaders ); 206 224 207 225 if ( ! $r['blocking'] ) { 208 226 stream_set_blocking( $handle, 0 ); 209 227 fclose( $handle ); 210 return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); 211 } 212 213 $strResponse = ''; 214 $bodyStarted = false; 228 return array( 229 'headers' => array(), 230 'body' => '', 231 'response' => array( 232 'code' => false, 233 'message' => false, 234 ), 235 'cookies' => array(), 236 ); 237 } 238 239 $strResponse = ''; 240 $bodyStarted = false; 215 241 $keep_reading = true; 216 $block_size = 4096;217 if ( isset( $r['limit_response_size'] ) ) 242 $block_size = 4096; 243 if ( isset( $r['limit_response_size'] ) ) { 218 244 $block_size = min( $block_size, $r['limit_response_size'] ); 245 } 219 246 220 247 // If streaming to a file setup the file handle. 221 248 if ( $r['stream'] ) { 222 if ( ! WP_DEBUG ) 249 if ( ! WP_DEBUG ) { 223 250 $stream_handle = @fopen( $r['filename'], 'w+' ); 224 else251 } else { 225 252 $stream_handle = fopen( $r['filename'], 'w+' ); 253 } 226 254 if ( ! $stream_handle ) { 227 return new WP_Error( 'http_request_failed', sprintf( 228 /* translators: 1: fopen() 2: file name */ 229 __( 'Could not open handle for %1$s to %2$s.' ), 230 'fopen()', 231 $r['filename'] 232 ) ); 255 return new WP_Error( 256 'http_request_failed', sprintf( 257 /* translators: 1: fopen() 2: file name */ 258 __( 'Could not open handle for %1$s to %2$s.' ), 259 'fopen()', 260 $r['filename'] 261 ) 262 ); 233 263 } 234 264 235 265 $bytes_written = 0; 236 while ( ! feof( $handle) && $keep_reading ) {266 while ( ! feof( $handle ) && $keep_reading ) { 237 267 $block = fread( $handle, $block_size ); 238 268 if ( ! $bodyStarted ) { 239 269 $strResponse .= $block; 240 270 if ( strpos( $strResponse, "\r\n\r\n" ) ) { 241 $process = WP_Http::processResponse( $strResponse );271 $process = WP_Http::processResponse( $strResponse ); 242 272 $bodyStarted = true; 243 $block = $process['body'];273 $block = $process['body']; 244 274 unset( $strResponse ); 245 275 $process['body'] = ''; … … 251 281 if ( isset( $r['limit_response_size'] ) && ( $bytes_written + $this_block_size ) > $r['limit_response_size'] ) { 252 282 $this_block_size = ( $r['limit_response_size'] - $bytes_written ); 253 $block = substr( $block, 0, $this_block_size );283 $block = substr( $block, 0, $this_block_size ); 254 284 } 255 285 … … 264 294 $bytes_written += $bytes_written_to_file; 265 295 266 $keep_reading = ! isset( $r['limit_response_size'] ) || $bytes_written < $r['limit_response_size'];296 $keep_reading = ! isset( $r['limit_response_size'] ) || $bytes_written < $r['limit_response_size']; 267 297 } 268 298 … … 272 302 $header_length = 0; 273 303 while ( ! feof( $handle ) && $keep_reading ) { 274 $block = fread( $handle, $block_size );304 $block = fread( $handle, $block_size ); 275 305 $strResponse .= $block; 276 306 if ( ! $bodyStarted && strpos( $strResponse, "\r\n\r\n" ) ) { 277 307 $header_length = strpos( $strResponse, "\r\n\r\n" ) + 4; 278 $bodyStarted = true;308 $bodyStarted = true; 279 309 } 280 $keep_reading = ( ! $bodyStarted || ! isset( $r['limit_response_size'] ) || strlen( $strResponse ) < ( $header_length + $r['limit_response_size'] ) );310 $keep_reading = ( ! $bodyStarted || ! isset( $r['limit_response_size'] ) || strlen( $strResponse ) < ( $header_length + $r['limit_response_size'] ) ); 281 311 } 282 312 … … 291 321 292 322 $response = array( 293 'headers' => $arrHeaders['headers'],323 'headers' => $arrHeaders['headers'], 294 324 // Not yet processed. 295 'body' => null,325 'body' => null, 296 326 'response' => $arrHeaders['response'], 297 'cookies' => $arrHeaders['cookies'],298 'filename' => $r['filename'] 327 'cookies' => $arrHeaders['cookies'], 328 'filename' => $r['filename'], 299 329 ); 300 330 301 331 // Handle redirects. 302 if ( false !== ( $redirect_response = WP_Http::handle_redirects( $url, $r, $response ) ) ) 332 if ( false !== ( $redirect_response = WP_Http::handle_redirects( $url, $r, $response ) ) ) { 303 333 return $redirect_response; 334 } 304 335 305 336 // If the body was chunk encoded, then decode it. 306 if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] ) 307 $process['body'] = WP_Http::chunkTransferDecode($process['body']); 308 309 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders['headers']) ) 337 if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] ) { 338 $process['body'] = WP_Http::chunkTransferDecode( $process['body'] ); 339 } 340 341 if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode( $arrHeaders['headers'] ) ) { 310 342 $process['body'] = WP_Http_Encoding::decompress( $process['body'] ); 311 312 if ( isset( $r['limit_response_size'] ) && strlen( $process['body'] ) > $r['limit_response_size'] ) 343 } 344 345 if ( isset( $r['limit_response_size'] ) && strlen( $process['body'] ) > $r['limit_response_size'] ) { 313 346 $process['body'] = substr( $process['body'], 0, $r['limit_response_size'] ); 347 } 314 348 315 349 $response['body'] = $process['body']; … … 338 372 $context_options = stream_context_get_options( $stream ); 339 373 340 if ( empty( $context_options['ssl']['peer_certificate'] ) ) 374 if ( empty( $context_options['ssl']['peer_certificate'] ) ) { 341 375 return false; 376 } 342 377 343 378 $cert = openssl_x509_parse( $context_options['ssl']['peer_certificate'] ); 344 if ( ! $cert ) 379 if ( ! $cert ) { 345 380 return false; 381 } 346 382 347 383 /* … … 356 392 foreach ( $match_against as $match ) { 357 393 list( $match_type, $match_host ) = explode( ':', $match ); 358 if ( $host_type == strtolower( trim( $match_type ) ) ) // IP: or DNS:394 if ( $host_type == strtolower( trim( $match_type ) ) ) { // IP: or DNS: 359 395 $certificate_hostnames[] = strtolower( trim( $match_host ) ); 360 } 361 } elseif ( !empty( $cert['subject']['CN'] ) ) { 396 } 397 } 398 } elseif ( ! empty( $cert['subject']['CN'] ) ) { 362 399 // Only use the CN when the certificate includes no subjectAltName extension. 363 400 $certificate_hostnames[] = strtolower( $cert['subject']['CN'] ); … … 365 402 366 403 // Exact hostname/IP matches. 367 if ( in_array( strtolower( $host ), $certificate_hostnames ) ) 404 if ( in_array( strtolower( $host ), $certificate_hostnames ) ) { 368 405 return true; 406 } 369 407 370 408 // IP's can't be wildcards, Stop processing. 371 if ( 'ip' == $host_type ) 409 if ( 'ip' == $host_type ) { 372 410 return false; 411 } 373 412 374 413 // Test to see if the domain is at least 2 deep for wildcard support. 375 if ( substr_count( $host, '.' ) < 2 ) 414 if ( substr_count( $host, '.' ) < 2 ) { 376 415 return false; 416 } 377 417 378 418 // Wildcard subdomains certs (*.example.com) are valid for a.example.com but not a.b.example.com. … … 393 433 */ 394 434 public static function test( $args = array() ) { 395 if ( ! function_exists( 'stream_socket_client' ) ) 435 if ( ! function_exists( 'stream_socket_client' ) ) { 396 436 return false; 437 } 397 438 398 439 $is_ssl = isset( $args['ssl'] ) && $args['ssl']; 399 440 400 441 if ( $is_ssl ) { 401 if ( ! extension_loaded( 'openssl' ) ) 442 if ( ! extension_loaded( 'openssl' ) ) { 402 443 return false; 403 if ( ! function_exists( 'openssl_x509_parse' ) ) 444 } 445 if ( ! function_exists( 'openssl_x509_parse' ) ) { 404 446 return false; 447 } 405 448 } 406 449
Note: See TracChangeset
for help on using the changeset viewer.