WordPress.org

Make WordPress Core

Ticket #21182: 21182.diff

File 21182.diff, 11.7 KB (added by dd32, 9 months ago)
  • wp-includes/class-http.php

     
    158158                        $r['headers'] = array(); 
    159159 
    160160                if ( ! is_array( $r['headers'] ) ) { 
    161                         $processedHeaders = WP_Http::processHeaders( $r['headers'] ); 
     161                        $processedHeaders = WP_Http::processHeaders( $r['headers'], $url ); 
    162162                        $r['headers'] = $processedHeaders['headers']; 
    163163                } 
    164164 
     
    195195                                $r['headers']['Content-Length'] = strlen( $r['body'] ); 
    196196                } 
    197197 
    198                 return $this->_dispatch_request($url, $r); 
     198                $response = $this->_dispatch_request($url, $r); 
     199                if ( ! empty( $r['cookies'] ) ) { 
     200                        // Append cookies that were used in this request to the response 
     201                        $cookies_set = wp_list_pluck( $response['cookies'], 'name' ); 
     202                        foreach ( $r['cookies'] as $cookie ) { 
     203                                if ( ! in_array( $cookie->name, $cookies_set ) && $cookie->test( $url ) ) { 
     204                                        $response['cookies'][] = $cookie; 
     205                                } 
     206                        } 
     207                } 
     208 
     209                return $response; 
    199210        } 
    200211 
    201212        /** 
     
    349360         * @since 2.7.0 
    350361         * 
    351362         * @param string|array $headers 
     363         * @param string $url The URL that was requested 
    352364         * @return array Processed string headers. If duplicate headers are encountered, 
    353365         *                                      Then a numbered array is returned as the value of that header-key. 
    354366         */ 
    355         public static function processHeaders($headers) { 
     367        public static function processHeaders( $headers, $url ) { 
    356368                // split headers, one per array element 
    357369                if ( is_string($headers) ) { 
    358370                        // tolerate line terminator: CRLF = LF (RFC 2616 19.3) 
     
    399411                        } else { 
    400412                                $newheaders[ $key ] = $value; 
    401413                        } 
    402                         if ( 'set-cookie' == $key ) 
    403                                 $cookies[] = new WP_Http_Cookie( $value ); 
     414                        if ( 'set-cookie' == $key || 'set-cookie2' == $key ) 
     415                                $cookies[] = new WP_Http_Cookie( $value, $url ); 
    404416                } 
    405417 
    406418                return array('response' => $response, 'headers' => $newheaders, 'cookies' => $cookies); 
     
    420432         * @param array $r Full array of args passed into ::request() 
    421433         */ 
    422434        public static function buildCookieHeader( &$r ) { 
    423                 if ( ! empty($r['cookies']) ) { 
     435                if ( ! empty( $r['cookies'] ) ) { 
    424436                        $cookies_header = ''; 
    425437                        foreach ( (array) $r['cookies'] as $cookie ) { 
    426438                                $cookies_header .= $cookie->getHeaderValue() . '; '; 
     
    593605 
    594606                return $absolute_path . '/' . ltrim( $path, '/' ); 
    595607        } 
     608 
     609        static function handle_redirects( $url, $args, $response ) { 
     610                // If no redirects are present, or, redirects were not requested, perform no action. 
     611                if ( ! isset( $response['headers']['location'] ) || 0 === $args['_redirection'] ) 
     612                        return null; 
     613 
     614                // Only perform redirections on redirection http codes 
     615                if ( $response['response']['code'] > 399 || $response['response']['code'] < 300 ) 
     616                        return null; 
     617 
     618                // Don't redirect if we've run out of redirects 
     619                if ( $args['redirection']-- <= 0 ) 
     620                        return new WP_Error( 'http_request_failed', __('Too many redirects.') ); 
     621 
     622                $redirect_location = WP_HTTP::make_absolute_url( $response['headers']['location'], $url ); 
     623 
     624                // POST requests should not POST to a redirected location 
     625                if ( 'POST' == $args['method'] ) { 
     626                        if ( in_array( $response['response']['code'], array( 302, 303 ) ) ) 
     627                                $args['method'] = 'GET'; 
     628                } 
     629 
     630                // Include valid cookies in the redirect process 
     631                if ( ! empty( $response['cookies'] ) ) { 
     632                        foreach ( $response['cookies'] as $cookie ) { 
     633                                if ( $cookie->test( $redirect_location ) ) 
     634                                        $args['cookies'][] = $cookie; 
     635                        } 
     636                } 
     637 
     638                return wp_remote_request( $redirect_location, $args );   
     639        } 
    596640} 
    597641 
    598642/** 
     
    802846                if ( true === $secure_transport ) 
    803847                        error_reporting($error_reporting); 
    804848 
    805                 $arrHeaders = WP_Http::processHeaders( $process['headers'] ); 
     849                $arrHeaders = WP_Http::processHeaders( $process['headers'], $url ); 
    806850 
    807                 // If location is found, then assume redirect and redirect to location. 
    808                 if ( isset($arrHeaders['headers']['location']) && 0 !== $r['_redirection'] ) { 
    809                         if ( $r['redirection']-- > 0 ) { 
    810                                 return wp_remote_request( WP_HTTP::make_absolute_url( $arrHeaders['headers']['location'], $url ), $r); 
    811                         } else { 
    812                                 return new WP_Error('http_request_failed', __('Too many redirects.')); 
    813                         } 
    814                 } 
     851                $response = array( 
     852                        'headers' => $arrHeaders['headers'], 
     853                        'body' => null, // Not yet processed 
     854                        'response' => $arrHeaders['response'], 
     855                        'cookies' => $arrHeaders['cookies'], 
     856                        'filename' => $r['filename'] 
     857                ); 
    815858 
     859                // Handle redirects 
     860                if ( null !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) ) 
     861                        return $redirect_response; 
     862 
    816863                // If the body was chunk encoded, then decode it. 
    817864                if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] ) 
    818865                        $process['body'] = WP_Http::chunkTransferDecode($process['body']); 
     
    823870                if ( isset( $r['limit_response_size'] ) && strlen( $process['body'] ) > $r['limit_response_size'] ) 
    824871                        $process['body'] = substr( $process['body'], 0, $r['limit_response_size'] ); 
    825872 
    826                 return array( 'headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response'], 'cookies' => $arrHeaders['cookies'], 'filename' => $r['filename'] ); 
     873                $response['body'] = $process['body']; 
     874 
     875                return $response; 
    827876        } 
    828877 
    829878        /** 
     
    9911040 
    9921041                $processedHeaders = array(); 
    9931042                if ( isset( $meta['wrapper_data']['headers'] ) ) 
    994                         $processedHeaders = WP_Http::processHeaders($meta['wrapper_data']['headers']); 
     1043                        $processedHeaders = WP_Http::processHeaders( $meta['wrapper_data']['headers'], $url); 
    9951044                else 
    996                         $processedHeaders = WP_Http::processHeaders($meta['wrapper_data']); 
     1045                        $processedHeaders = WP_Http::processHeaders( $meta['wrapper_data'], $url ); 
    9971046 
    998                 if ( ! empty( $processedHeaders['headers']['location'] ) && 0 !== $r['_redirection'] ) { // _redirection: The requested number of redirections 
    999                         if ( $r['redirection']-- > 0 ) { 
    1000                                 return wp_remote_request( WP_HTTP::make_absolute_url( $processedHeaders['headers']['location'], $url ), $r ); 
    1001                         } else { 
    1002                                 return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) ); 
    1003                         } 
    1004                 } 
     1047                $response = array( 
     1048                        'headers' => $processedHeaders['headers'], 
     1049                        'body' => null, 
     1050                        'response' => $processedHeaders['response'], 
     1051                        'cookies' => $processedHeaders['cookies'], 
     1052                        'filename' => $r['filename'] 
     1053                ); 
    10051054 
     1055                // Handle redirects 
     1056                if ( null !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) ) 
     1057                        return $redirect_response; 
     1058 
    10061059                if ( ! empty( $strResponse ) && isset( $processedHeaders['headers']['transfer-encoding'] ) && 'chunked' == $processedHeaders['headers']['transfer-encoding'] ) 
    10071060                        $strResponse = WP_Http::chunkTransferDecode($strResponse); 
    10081061 
    10091062                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders['headers']) ) 
    10101063                        $strResponse = WP_Http_Encoding::decompress( $strResponse ); 
    10111064 
    1012                 return array( 'headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies'], 'filename' => $r['filename'] ); 
     1065                $response['body'] = $strResponse; 
     1066 
     1067                return $response; 
    10131068        } 
    10141069 
    10151070        /** 
     
    12351290                } 
    12361291 
    12371292                $theResponse = curl_exec( $handle ); 
    1238                 $theHeaders = WP_Http::processHeaders( $this->headers ); 
     1293                $theHeaders = WP_Http::processHeaders( $this->headers, $url ); 
    12391294                $theBody = $this->body; 
    12401295 
    12411296                $this->headers = ''; 
     
    12621317                if ( $r['stream'] ) 
    12631318                        fclose( $this->stream_handle ); 
    12641319 
    1265                 // See #11305 - When running under safe mode, redirection is disabled above. Handle it manually. 
    1266                 if ( ! empty( $theHeaders['headers']['location'] ) && 0 !== $r['_redirection'] ) { // _redirection: The requested number of redirections 
    1267                         if ( $r['redirection']-- > 0 ) { 
    1268                                 return wp_remote_request( WP_HTTP::make_absolute_url( $theHeaders['headers']['location'], $url ), $r ); 
    1269                         } else { 
    1270                                 return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) ); 
    1271                         } 
    1272                 } 
     1320                $response = array( 
     1321                        'headers' => $theHeaders['headers'], 
     1322                        'body' => null, 
     1323                        'response' => $response, 
     1324                        'cookies' => $theHeaders['cookies'], 
     1325                        'filename' => $r['filename'] 
     1326                ); 
    12731327 
     1328                // Handle redirects 
     1329                if ( null !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) ) 
     1330                        return $redirect_response; 
     1331 
    12741332                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders['headers']) ) 
    12751333                        $theBody = WP_Http_Encoding::decompress( $theBody ); 
    12761334 
    1277                 return array( 'headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $response, 'cookies' => $theHeaders['cookies'], 'filename' => $r['filename'] ); 
     1335                $response['body'] = $theBody; 
     1336 
     1337                return $response; 
    12781338        } 
    12791339 
    12801340        /** 
     
    15491609         * @since 2.8.0 
    15501610         * @var string 
    15511611         */ 
    1552         var $name; 
     1612        var $name = ''; 
    15531613 
    15541614        /** 
    15551615         * Cookie value. 
     
    15571617         * @since 2.8.0 
    15581618         * @var string 
    15591619         */ 
    1560         var $value; 
     1620        var $value = ''; 
    15611621 
    15621622        /** 
    15631623         * When the cookie expires. 
     
    15651625         * @since 2.8.0 
    15661626         * @var string 
    15671627         */ 
    1568         var $expires; 
     1628        var $expires = null; 
    15691629 
    15701630        /** 
    15711631         * Cookie URL path. 
     
    15731633         * @since 2.8.0 
    15741634         * @var string 
    15751635         */ 
    1576         var $path; 
     1636        var $path = null; 
    15771637 
    15781638        /** 
    15791639         * Cookie Domain. 
     
    15811641         * @since 2.8.0 
    15821642         * @var string 
    15831643         */ 
    1584         var $domain; 
     1644        var $domain = null; 
    15851645 
    15861646        /** 
    15871647         * Sets up this cookie object. 
     
    16031663         * 
    16041664         * @param string|array $data Raw cookie data. 
    16051665         */ 
    1606         function __construct( $data ) { 
     1666        function __construct( $data, $requested_url = '' ) { 
     1667                $arrURL = parse_url( $requested_url ); 
     1668                $this->domain = $arrURL['host']; 
     1669                $this->path = isset( $arrURL['path'] ) ? $arrURL['path'] : '/'; 
     1670                if ( '/' != substr( $this->path, -1 ) ) 
     1671                        $this->path = dirname( $this->path ) . '/'; 
     1672 
    16071673                if ( is_string( $data ) ) { 
    16081674                        // Assume it's a header string direct from a previous request 
    16091675                        $pairs = explode( ';', $data ); 
     
    16321698                                return false; 
    16331699 
    16341700                        // Set properties based directly on parameters 
    1635                         $this->name   = $data['name']; 
    1636                         $this->value  = isset( $data['value'] ) ? $data['value'] : ''; 
    1637                         $this->path   = isset( $data['path'] ) ? $data['path'] : ''; 
    1638                         $this->domain = isset( $data['domain'] ) ? $data['domain'] : ''; 
     1701                        foreach ( array( 'name', 'value', 'path', 'domain' ) as $field ) { 
     1702                                if ( isset( $data[ $field ] ) ) 
     1703                                        $this->$field = $data[ $field ]; 
     1704                        } 
    16391705 
    16401706                        if ( isset( $data['expires'] ) ) 
    16411707                                $this->expires = is_int( $data['expires'] ) ? $data['expires'] : strtotime( $data['expires'] ); 
     
    16561722         * @return boolean true if allowed, false otherwise. 
    16571723         */ 
    16581724        function test( $url ) { 
     1725                if ( empty( $this->name ) ) 
     1726                        return false; 
     1727 
    16591728                // Expires - if expired then nothing else matters 
    16601729                if ( isset( $this->expires ) && time() > $this->expires ) 
    16611730                        return false; 
    16621731 
    16631732                // Get details on the URL we're thinking about sending to 
    16641733                $url = parse_url( $url ); 
    1665                 $url['port'] = isset( $url['port'] ) ? $url['port'] : 80; 
     1734                $url['port'] = isset( $url['port'] ) ? $url['port'] : ( 'https' == $url['scheme'] ? 443 : 80 ); 
    16661735                $url['path'] = isset( $url['path'] ) ? $url['path'] : '/'; 
    16671736 
    16681737                // Values to use for comparison against the URL 
    16691738                $path   = isset( $this->path )   ? $this->path   : '/'; 
    1670                 $port   = isset( $this->port )   ? $this->port   : 80; 
     1739                $port   = isset( $this->port )   ? $this->port   : null; 
    16711740                $domain = isset( $this->domain ) ? strtolower( $this->domain ) : strtolower( $url['host'] ); 
    16721741                if ( false === stripos( $domain, '.' ) ) 
    16731742                        $domain .= '.local'; 
     
    16781747                        return false; 
    16791748 
    16801749                // Port - supports "port-lists" in the format: "80,8000,8080" 
    1681                 if ( !in_array( $url['port'], explode( ',', $port) ) ) 
     1750                if ( !empty( $port ) && !in_array( $url['port'], explode( ',', $port) ) ) 
    16821751                        return false; 
    16831752 
    16841753                // Path - request path must start with path restriction