Index: class-http.php
===================================================================
--- class-http.php	(revision 20460)
+++ class-http.php	(working copy)
@@ -535,6 +535,50 @@
 			return !in_array( $check['host'], $accessible_hosts ); //Inverse logic, If its in the array, then we can't access it.
 
 	}
+
+	function make_absolute_url( $relative_path, $url ) {
+
+		if ( empty( $url ) )
+			return $relative_path;
+
+		// Check for a scheme
+		if ( false !== strpos( $relative_path, '://' ) )
+			return $relative_path;
+
+		$absolute_path = '';
+		$url_parts = @parse_url( $url );
+
+		if ( ! $url_parts )
+			return $relative_path;
+
+		$absolute_path = $url_parts['scheme'] . '://' . $url_parts['host'];
+		if ( isset( $url_parts['port'] ) )
+			$absolute_path .= ':' . $url_parts['port'];
+
+		if ( '/' == $relative_path[0] || ! isset( $url_parts['path'] ) ) { // Absolute path provided, easy.
+			$new_path = $relative_path;
+
+		} elseif ( '../' == substr( $relative_path, 0, 3 ) ) { // Relative path to a parent directory, this will miss cases such as '/../something' or '/something/../something-else/'
+			$url_parts['path'] = preg_replace( '![^/]+$!', '', $url_parts['path'] ); // strip files off
+
+			while( '../' == substr( $relative_path, 0, 3 ) ) {
+				$relative_path = substr( $relative_path, 3 );
+				$url_parts['path'] = preg_replace( '![^/]+$!', '', untrailingslashit( $url_parts['path'] ) ); 
+			}
+			$new_path = ( '.' == $url_parts['path'] ? '' : trailingslashit( $url_parts['path'] ) ) . ltrim( $relative_path, '/' );
+
+		} else { // Relative path to a sibling, /here/me => /here/subling
+			if ( '/' != $relative_path[0] )
+				$url_parts['path'] = preg_replace( '![^/]+$!', '', $url_parts['path'] ); // delete the last segment of the path, dirname('/here/') will return /
+			$new_path = ( '.' == $url_parts['path'] ? '' : trailingslashit( $url_parts['path'] ) ) . ltrim( $relative_path, '/' );
+
+		}
+
+		$absolute_path .= '/' . ltrim( $new_path, '/' );
+
+		return $absolute_path;
+		
+	}
 }
 
 /**
@@ -730,7 +774,7 @@
 		// If location is found, then assume redirect and redirect to location.
 		if ( isset($arrHeaders['headers']['location']) && 0 !== $r['_redirection'] ) {
 			if ( $r['redirection']-- > 0 ) {
-				return $this->request($arrHeaders['headers']['location'], $r);
+				return $this->request( WP_HTTP::make_absolute_url( $arrHeaders['headers']['location'], $url ), $r);
 			} else {
 				return new WP_Error('http_request_failed', __('Too many redirects.'));
 			}
@@ -1131,7 +1175,7 @@
 		// 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 $this->request( $theHeaders['headers']['location'], $r );
+				return $this->request( WP_HTTP::make_absolute_url( $theHeaders['headers']['location'], $url ), $r );
 			} else {
 				return new WP_Error( 'http_request_failed', __( 'Too many redirects.' ) );
 			}
