Make WordPress Core


Ignore:
Timestamp:
07/29/2013 01:19:54 AM (13 years ago)
Author:
dd32
Message:

WP_HTTP: Abstract out the Redirection handling code into it's own method and fix a bunch of redirection edgecases at the same time.
Fixes #17588
Fixes 16889
Props wonderboymusic and kovshenin for initial patches

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class-http.php

    r24767 r24843  
    594594                return $absolute_path . '/' . ltrim( $path, '/' );
    595595        }
     596
     597        /**
     598         * Handles HTTP Redirects and follows them if appropriate.
     599         *
     600         * @since 3.7
     601         *
     602         * @param $url The URL which was requested
     603         * @param $args The Arguements which were used to make the request
     604         * @param $response The Response of the HTTP request
     605         * @return false|object False if no redirect is present, a WP_HTTP or WP_Error result otherwise
     606         */
     607        static function handle_redirects( $url, $args, $response ) {
     608                // If no redirects are present, or, redirects were not requested, perform no action.
     609                if ( ! isset( $response['headers']['location'] ) || 0 === $args['_redirection'] )
     610                        return false;
     611
     612                // Only perform redirections on redirection http codes
     613                if ( $response['response']['code'] > 399 || $response['response']['code'] < 300 )
     614                        return false;
     615
     616                // Don't redirect if we've run out of redirects
     617                if ( $args['redirection']-- <= 0 )
     618                        return new WP_Error( 'http_request_failed', __('Too many redirects.') );
     619
     620                $redirect_location = WP_HTTP::make_absolute_url( $response['headers']['location'], $url );
     621
     622                // POST requests should not POST to a redirected location
     623                if ( 'POST' == $args['method'] ) {
     624                        if ( in_array( $response['response']['code'], array( 302, 303 ) ) )
     625                                $args['method'] = 'GET';
     626                }
     627
     628                return wp_remote_request( $redirect_location, $args ); 
     629        }
    596630}
    597631
     
    805839                $arrHeaders = WP_Http::processHeaders( $process['headers'] );
    806840
    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                 }
     841                $response = array(
     842                        'headers' => $arrHeaders['headers'],
     843                        'body' => null, // Not yet processed
     844                        'response' => $arrHeaders['response'],
     845                        'cookies' => $arrHeaders['cookies'],
     846                        'filename' => $r['filename']
     847                );
     848
     849                // Handle redirects
     850                if ( false !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) )
     851                        return $redirect_response;
    815852
    816853                // If the body was chunk encoded, then decode it.
     
    824861                        $process['body'] = substr( $process['body'], 0, $r['limit_response_size'] );
    825862
    826                 return array( 'headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response'], 'cookies' => $arrHeaders['cookies'], 'filename' => $r['filename'] );
     863                $response['body'] = $process['body'];
     864
     865                return $response;
    827866        }
    828867
     
    9961035                        $processedHeaders = WP_Http::processHeaders($meta['wrapper_data']);
    9971036
    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                 }
     1037                $response = array(
     1038                        'headers' => $processedHeaders['headers'],
     1039                        'body' => null,
     1040                        'response' => $processedHeaders['response'],
     1041                        'cookies' => $processedHeaders['cookies'],
     1042                        'filename' => $r['filename']
     1043                );
     1044
     1045                // Handle redirects
     1046                if ( false !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) )
     1047                        return $redirect_response;
    10051048
    10061049                if ( ! empty( $strResponse ) && isset( $processedHeaders['headers']['transfer-encoding'] ) && 'chunked' == $processedHeaders['headers']['transfer-encoding'] )
     
    10101053                        $strResponse = WP_Http_Encoding::decompress( $strResponse );
    10111054
    1012                 return array( 'headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies'], 'filename' => $r['filename'] );
     1055                $response['body'] = $strResponse;
     1056
     1057                return $response;
    10131058        }
    10141059
     
    12631308                        fclose( $this->stream_handle );
    12641309
    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                 }
     1310                $response = array(
     1311                        'headers' => $theHeaders['headers'],
     1312                        'body' => null,
     1313                        'response' => $response,
     1314                        'cookies' => $theHeaders['cookies'],
     1315                        'filename' => $r['filename']
     1316                );
     1317
     1318                // Handle redirects
     1319                if ( false !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) )
     1320                        return $redirect_response;
    12731321
    12741322                if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders['headers']) )
    12751323                        $theBody = WP_Http_Encoding::decompress( $theBody );
    12761324
    1277                 return array( 'headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $response, 'cookies' => $theHeaders['cookies'], 'filename' => $r['filename'] );
     1325                $response['body'] = $theBody;
     1326
     1327                return $response;
    12781328        }
    12791329
Note: See TracChangeset for help on using the changeset viewer.