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 git-svn-id: http://core.svn.wordpress.org/trunk@24843 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
d8f819fdda
commit
c61a2dac03
|
@ -593,6 +593,40 @@ class WP_Http {
|
||||||
|
|
||||||
return $absolute_path . '/' . ltrim( $path, '/' );
|
return $absolute_path . '/' . ltrim( $path, '/' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles HTTP Redirects and follows them if appropriate.
|
||||||
|
*
|
||||||
|
* @since 3.7
|
||||||
|
*
|
||||||
|
* @param $url The URL which was requested
|
||||||
|
* @param $args The Arguements which were used to make the request
|
||||||
|
* @param $response The Response of the HTTP request
|
||||||
|
* @return false|object False if no redirect is present, a WP_HTTP or WP_Error result otherwise
|
||||||
|
*/
|
||||||
|
static function handle_redirects( $url, $args, $response ) {
|
||||||
|
// If no redirects are present, or, redirects were not requested, perform no action.
|
||||||
|
if ( ! isset( $response['headers']['location'] ) || 0 === $args['_redirection'] )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Only perform redirections on redirection http codes
|
||||||
|
if ( $response['response']['code'] > 399 || $response['response']['code'] < 300 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Don't redirect if we've run out of redirects
|
||||||
|
if ( $args['redirection']-- <= 0 )
|
||||||
|
return new WP_Error( 'http_request_failed', __('Too many redirects.') );
|
||||||
|
|
||||||
|
$redirect_location = WP_HTTP::make_absolute_url( $response['headers']['location'], $url );
|
||||||
|
|
||||||
|
// POST requests should not POST to a redirected location
|
||||||
|
if ( 'POST' == $args['method'] ) {
|
||||||
|
if ( in_array( $response['response']['code'], array( 302, 303 ) ) )
|
||||||
|
$args['method'] = 'GET';
|
||||||
|
}
|
||||||
|
|
||||||
|
return wp_remote_request( $redirect_location, $args );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -804,14 +838,17 @@ class WP_Http_Fsockopen {
|
||||||
|
|
||||||
$arrHeaders = WP_Http::processHeaders( $process['headers'] );
|
$arrHeaders = WP_Http::processHeaders( $process['headers'] );
|
||||||
|
|
||||||
// If location is found, then assume redirect and redirect to location.
|
$response = array(
|
||||||
if ( isset($arrHeaders['headers']['location']) && 0 !== $r['_redirection'] ) {
|
'headers' => $arrHeaders['headers'],
|
||||||
if ( $r['redirection']-- > 0 ) {
|
'body' => null, // Not yet processed
|
||||||
return wp_remote_request( WP_HTTP::make_absolute_url( $arrHeaders['headers']['location'], $url ), $r);
|
'response' => $arrHeaders['response'],
|
||||||
} else {
|
'cookies' => $arrHeaders['cookies'],
|
||||||
return new WP_Error('http_request_failed', __('Too many redirects.'));
|
'filename' => $r['filename']
|
||||||
}
|
);
|
||||||
}
|
|
||||||
|
// Handle redirects
|
||||||
|
if ( false !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) )
|
||||||
|
return $redirect_response;
|
||||||
|
|
||||||
// If the body was chunk encoded, then decode it.
|
// If the body was chunk encoded, then decode it.
|
||||||
if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] )
|
if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] )
|
||||||
|
@ -823,7 +860,9 @@ class WP_Http_Fsockopen {
|
||||||
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'] );
|
$process['body'] = substr( $process['body'], 0, $r['limit_response_size'] );
|
||||||
|
|
||||||
return array( 'headers' => $arrHeaders['headers'], 'body' => $process['body'], 'response' => $arrHeaders['response'], 'cookies' => $arrHeaders['cookies'], 'filename' => $r['filename'] );
|
$response['body'] = $process['body'];
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -995,13 +1034,17 @@ class WP_Http_Streams {
|
||||||
else
|
else
|
||||||
$processedHeaders = WP_Http::processHeaders($meta['wrapper_data']);
|
$processedHeaders = WP_Http::processHeaders($meta['wrapper_data']);
|
||||||
|
|
||||||
if ( ! empty( $processedHeaders['headers']['location'] ) && 0 !== $r['_redirection'] ) { // _redirection: The requested number of redirections
|
$response = array(
|
||||||
if ( $r['redirection']-- > 0 ) {
|
'headers' => $processedHeaders['headers'],
|
||||||
return wp_remote_request( WP_HTTP::make_absolute_url( $processedHeaders['headers']['location'], $url ), $r );
|
'body' => null,
|
||||||
} else {
|
'response' => $processedHeaders['response'],
|
||||||
return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) );
|
'cookies' => $processedHeaders['cookies'],
|
||||||
}
|
'filename' => $r['filename']
|
||||||
}
|
);
|
||||||
|
|
||||||
|
// Handle redirects
|
||||||
|
if ( false !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) )
|
||||||
|
return $redirect_response;
|
||||||
|
|
||||||
if ( ! empty( $strResponse ) && isset( $processedHeaders['headers']['transfer-encoding'] ) && 'chunked' == $processedHeaders['headers']['transfer-encoding'] )
|
if ( ! empty( $strResponse ) && isset( $processedHeaders['headers']['transfer-encoding'] ) && 'chunked' == $processedHeaders['headers']['transfer-encoding'] )
|
||||||
$strResponse = WP_Http::chunkTransferDecode($strResponse);
|
$strResponse = WP_Http::chunkTransferDecode($strResponse);
|
||||||
|
@ -1009,7 +1052,9 @@ class WP_Http_Streams {
|
||||||
if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders['headers']) )
|
if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders['headers']) )
|
||||||
$strResponse = WP_Http_Encoding::decompress( $strResponse );
|
$strResponse = WP_Http_Encoding::decompress( $strResponse );
|
||||||
|
|
||||||
return array( 'headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies'], 'filename' => $r['filename'] );
|
$response['body'] = $strResponse;
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1262,19 +1307,24 @@ class WP_Http_Curl {
|
||||||
if ( $r['stream'] )
|
if ( $r['stream'] )
|
||||||
fclose( $this->stream_handle );
|
fclose( $this->stream_handle );
|
||||||
|
|
||||||
// See #11305 - When running under safe mode, redirection is disabled above. Handle it manually.
|
$response = array(
|
||||||
if ( ! empty( $theHeaders['headers']['location'] ) && 0 !== $r['_redirection'] ) { // _redirection: The requested number of redirections
|
'headers' => $theHeaders['headers'],
|
||||||
if ( $r['redirection']-- > 0 ) {
|
'body' => null,
|
||||||
return wp_remote_request( WP_HTTP::make_absolute_url( $theHeaders['headers']['location'], $url ), $r );
|
'response' => $response,
|
||||||
} else {
|
'cookies' => $theHeaders['cookies'],
|
||||||
return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) );
|
'filename' => $r['filename']
|
||||||
}
|
);
|
||||||
}
|
|
||||||
|
// Handle redirects
|
||||||
|
if ( false !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) )
|
||||||
|
return $redirect_response;
|
||||||
|
|
||||||
if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders['headers']) )
|
if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders['headers']) )
|
||||||
$theBody = WP_Http_Encoding::decompress( $theBody );
|
$theBody = WP_Http_Encoding::decompress( $theBody );
|
||||||
|
|
||||||
return array( 'headers' => $theHeaders['headers'], 'body' => $theBody, 'response' => $response, 'cookies' => $theHeaders['cookies'], 'filename' => $r['filename'] );
|
$response['body'] = $theBody;
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue