Index: wp-includes/class-http.php
===================================================================
--- wp-includes/class-http.php	(revision 24804)
+++ wp-includes/class-http.php	(working copy)
@@ -593,6 +593,30 @@
 
 		return $absolute_path . '/' . ltrim( $path, '/' );
 	}
+
+	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 null;
+
+		// Only perform redirections on redirection http codes
+		if ( $response['response']['code'] > 399 || $response['response']['code'] < 300 )
+			return null;
+
+		// 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,15 +828,18 @@
 
 		$arrHeaders = WP_Http::processHeaders( $process['headers'] );
 
-		// If location is found, then assume redirect and redirect to location.
-		if ( isset($arrHeaders['headers']['location']) && 0 !== $r['_redirection'] ) {
-			if ( $r['redirection']-- > 0 ) {
-				return wp_remote_request( WP_HTTP::make_absolute_url( $arrHeaders['headers']['location'], $url ), $r);
-			} else {
-				return new WP_Error('http_request_failed', __('Too many redirects.'));
-			}
-		}
+		$response = array(
+			'headers' => $arrHeaders['headers'],
+			'body' => null, // Not yet processed
+			'response' => $arrHeaders['response'],
+			'cookies' => $arrHeaders['cookies'],
+			'filename' => $r['filename']
+		);
 
+		// Handle redirects
+		if ( null !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) )
+			return $redirect_response;
+
 		// If the body was chunk encoded, then decode it.
 		if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] )
 			$process['body'] = WP_Http::chunkTransferDecode($process['body']);
@@ -823,7 +850,9 @@
 		if ( isset( $r['limit_response_size'] ) && strlen( $process['body'] ) > $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,21 +1024,27 @@
 		else
 			$processedHeaders = WP_Http::processHeaders($meta['wrapper_data']);
 
-		if ( ! empty( $processedHeaders['headers']['location'] ) && 0 !== $r['_redirection'] ) { // _redirection: The requested number of redirections
-			if ( $r['redirection']-- > 0 ) {
-				return wp_remote_request( WP_HTTP::make_absolute_url( $processedHeaders['headers']['location'], $url ), $r );
-			} else {
-				return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) );
-			}
-		}
+		$response = array(
+			'headers' => $processedHeaders['headers'],
+			'body' => null,
+			'response' => $processedHeaders['response'],
+			'cookies' => $processedHeaders['cookies'],
+			'filename' => $r['filename']
+		);
 
+		// Handle redirects
+		if ( null !== ( $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'] )
 			$strResponse = WP_Http::chunkTransferDecode($strResponse);
 
 		if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders['headers']) )
 			$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 +1297,24 @@
 		if ( $r['stream'] )
 			fclose( $this->stream_handle );
 
-		// See #11305 - When running under safe mode, redirection is disabled above. Handle it manually.
-		if ( ! empty( $theHeaders['headers']['location'] ) && 0 !== $r['_redirection'] ) { // _redirection: The requested number of redirections
-			if ( $r['redirection']-- > 0 ) {
-				return wp_remote_request( WP_HTTP::make_absolute_url( $theHeaders['headers']['location'], $url ), $r );
-			} else {
-				return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) );
-			}
-		}
+		$response = array(
+			'headers' => $theHeaders['headers'],
+			'body' => null,
+			'response' => $response,
+			'cookies' => $theHeaders['cookies'],
+			'filename' => $r['filename']
+		);
 
+		// Handle redirects
+		if ( null !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) )
+			return $redirect_response;
+
 		if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($theHeaders['headers']) )
 			$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;
 	}
 
 	/**
