Index: wp-includes/class-http.php
===================================================================
--- wp-includes/class-http.php	(revision 18117)
+++ wp-includes/class-http.php	(working copy)
@@ -697,6 +697,9 @@
 				return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) );
 
 			while ( ! feof($handle) ) {
+				$info = stream_get_meta_data( $handle );
+				if ( $info['timed_out'] )
+					return new WP_Error('http_request_failed', __('Request timed out.'));
 				$block = fread( $handle, 4096 );
 				if ( $bodyStarted ) {
 					fwrite( $stream_handle, $block );
@@ -716,6 +719,9 @@
 
 		} else {
 			while ( ! feof($handle) )
+				$info = stream_get_meta_data( $handle );
+				if ( $info['timed_out'] )
+					return new WP_Error('http_request_failed', __('Request timed out.'));
 				$strResponse .= fread( $handle, 4096 );
 
 			$process = WP_Http::processResponse( $strResponse );
@@ -868,6 +874,9 @@
 		if ( ! empty($r['body'] ) )
 			$arrContext['http']['content'] = $r['body'];
 
+		// timeouts with stream_contect_create for some reason need to be half of what you expect
+		$arrContext['http']['timeout'] = $r['timeout'] / 2;
+
 		$context = stream_context_create($arrContext);
 
 		if ( !WP_DEBUG )
@@ -915,7 +924,7 @@
 		else
 			$processedHeaders = WP_Http::processHeaders($meta['wrapper_data']);
 
-		// Streams does not provide an error code which we can use to see why the request stream stoped.
+		// Streams does not provide an error code which we can use to see why the request stream stopped.
 		// We can however test to see if a location header is present and return based on that.
 		if ( isset($processedHeaders['headers']['location']) && 0 !== $args['_redirection'] )
 			return new WP_Error('http_request_failed', __('Too many redirects.'));
