WordPress.org

Make WordPress Core

Changeset 24843


Ignore:
Timestamp:
07/29/2013 01:19:54 AM (8 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.