diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php
index 0a8cee3d1..65c5f5f55 100644
--- a/src/Composer/Command/DiagnoseCommand.php
+++ b/src/Composer/Command/DiagnoseCommand.php
@@ -224,6 +224,12 @@ EOT
try {
$this->httpDownloader->get($proto . '://repo.packagist.org/packages.json');
} catch (TransportException $e) {
+ if ($hints = HttpDownloader::getExceptionHints($e)) {
+ foreach ($hints as $hint) {
+ $result[] = $hint;
+ }
+ }
+
$result[] = '[' . get_class($e) . '] ' . $e->getMessage() . '';
}
diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php
index 73779a563..192df31a0 100644
--- a/src/Composer/Console/Application.php
+++ b/src/Composer/Console/Application.php
@@ -30,6 +30,7 @@ use Composer\IO\IOInterface;
use Composer\IO\ConsoleIO;
use Composer\Json\JsonValidationException;
use Composer\Util\ErrorHandler;
+use Composer\Util\HttpDownloader;
use Composer\EventDispatcher\ScriptExecutionException;
use Composer\Exception\NoSslException;
@@ -382,6 +383,12 @@ class Application extends BaseApplication
$io->writeError('The following exception is caused by a lack of memory or swap, or not having swap configured', true, IOInterface::QUIET);
$io->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details', true, IOInterface::QUIET);
}
+
+ if ($hints = HttpDownloader::getExceptionHints($exception)) {
+ foreach ($hints as $hint) {
+ $io->writeError($hint, true, IOInterface::QUIET);
+ }
+ }
}
/**
diff --git a/src/Composer/Util/Http/CurlDownloader.php b/src/Composer/Util/Http/CurlDownloader.php
index 8deff9f43..e5a9de423 100644
--- a/src/Composer/Util/Http/CurlDownloader.php
+++ b/src/Composer/Util/Http/CurlDownloader.php
@@ -157,7 +157,6 @@ class CurlDownloader
curl_setopt($curlHandle, CURLOPT_URL, $url);
curl_setopt($curlHandle, CURLOPT_FOLLOWLOCATION, false);
- //curl_setopt($curlHandle, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curlHandle, CURLOPT_TIMEOUT, 300);
curl_setopt($curlHandle, CURLOPT_WRITEHEADER, $headerHandle);
diff --git a/src/Composer/Util/HttpDownloader.php b/src/Composer/Util/HttpDownloader.php
index 8d7bc45b5..a49a806f4 100644
--- a/src/Composer/Util/HttpDownloader.php
+++ b/src/Composer/Util/HttpDownloader.php
@@ -378,4 +378,32 @@ class HttpDownloader
$io->writeError('<'.$type.'>'.ucfirst($type).' from '.$url.': '.$data[$type].''.$type.'>');
}
}
+
+ public static function getExceptionHints(\Exception $e)
+ {
+ if (!$e instanceof TransportException) {
+ return;
+ }
+
+ if (
+ false !== strpos($e->getMessage(), 'Resolving timed out')
+ || false !== strpos($e->getMessage(), 'Could not resolve host')
+ ) {
+ Silencer::suppress();
+ $testConnectivity = file_get_contents('https://8.8.8.8', false, stream_context_create(array(
+ 'ssl' => array('verify_peer' => false),
+ 'http' => array('follow_location' => false, 'ignore_errors' => true)
+ )));
+ Silencer::restore();
+ if (false !== $testConnectivity) {
+ return array(
+ 'The following exception probably indicates you have misconfigured DNS resolver(s)'
+ );
+ }
+
+ return array(
+ 'The following exception probably indicates you are offline or have misconfigured DNS resolver(s)'
+ );
+ }
+ }
}