Преглед изворни кода

Show warning in all 400/500 responses if available, fixes #7814

Jordi Boggiano пре 6 година
родитељ
комит
3f5a986170

+ 3 - 23
src/Composer/Repository/ComposerRepository.php

@@ -962,7 +962,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
                 }
 
                 $data = $response->decodeJson();
-                $this->outputWarnings($data);
+                HttpDownloader::outputWarnings($this->io, $this->url, $data);
 
                 if ($cacheKey) {
                     if ($storeLastModifiedTime) {
@@ -1036,7 +1036,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
                 }
 
                 $data = $response->decodeJson();
-                $this->outputWarnings($data);
+                HttpDownloader::outputWarnings($this->io, $this->url, $data);
 
                 $lastModifiedDate = $response->getHeader('last-modified');
                 $response->collect();
@@ -1101,7 +1101,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
             }
 
             $data = $response->decodeJson();
-            $this->outputWarnings($data);
+            HttpDownloader::outputWarnings($io, $url, $data);
 
             $lastModifiedDate = $response->getHeader('last-modified');
             $response->collect();
@@ -1161,24 +1161,4 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
         // wipe rootData as it is fully consumed at this point and this saves some memory
         $this->rootData = true;
     }
-
-    private function outputWarnings($data)
-    {
-        foreach (array('warning', 'info') as $type) {
-            if (empty($data[$type])) {
-                continue;
-            }
-
-            if (!empty($data[$type . '-versions'])) {
-                $versionParser = new VersionParser();
-                $constraint = $versionParser->parseConstraints($data[$type . '-versions']);
-                $composer = new Constraint('==', $versionParser->normalize(Composer::getVersion()));
-                if (!$constraint->matches($composer)) {
-                    continue;
-                }
-            }
-
-            $this->io->writeError('<'.$type.'>'.ucfirst($type).' from '.$this->url.': '.$data[$type].'</'.$type.'>');
-        }
-    }
 }

+ 1 - 6
src/Composer/Util/AuthHelper.php

@@ -71,12 +71,11 @@ class AuthHelper
      * @param string $origin
      * @param int $statusCode HTTP status code that triggered this call
      * @param string|null $reason a message/description explaining why this was called
-     * @param string $warning an authentication warning returned by the server as {"warning": ".."}, if present
      * @param string[] $headers
      * @return array|null containing retry (bool) and storeAuth (string|bool) keys, if retry is true the request should be
      *               retried, if storeAuth is true then on a successful retry the authentication should be persisted to auth.json
      */
-    public function promptAuthIfNeeded($url, $origin, $statusCode, $reason = null, $warning = null, $headers = array())
+    public function promptAuthIfNeeded($url, $origin, $statusCode, $reason = null, $headers = array())
     {
         $storeAuth = false;
         $retry = false;
@@ -173,10 +172,6 @@ class AuthHelper
                 throw new TransportException("Invalid credentials for '" . $url . "', aborting.", $statusCode);
             }
 
-            $this->io->overwriteError('');
-            if ($warning) {
-                $this->io->writeError('    <warning>'.$warning.'</warning>');
-            }
             $this->io->writeError('    Authentication required (<info>'.parse_url($url, PHP_URL_HOST).'</info>):');
             $username = $this->io->ask('      Username: ');
             $password = $this->io->askAndHideAnswer('      Password: ');

+ 6 - 9
src/Composer/Util/Http/CurlDownloader.php

@@ -20,6 +20,7 @@ use Composer\Util\RemoteFilesystem;
 use Composer\Util\StreamContextFactory;
 use Composer\Util\AuthHelper;
 use Composer\Util\Url;
+use Composer\Util\HttpDownloader;
 use React\Promise\Promise;
 
 /**
@@ -261,6 +262,10 @@ class CurlDownloader
                     $this->io->writeError('['.$statusCode.'] '.$progress['url'], true, IOInterface::DEBUG);
                 }
 
+                if ($response->getStatusCode() >= 400 && $response->getHeader('content-type') === 'application/json') {
+                    HttpDownloader::outputWarnings($this->io, $job['origin'], json_decode($response->getBody(), true));
+                }
+
                 $result = $this->isAuthenticatedRetryNeeded($job, $response);
                 if ($result['retry']) {
                     if ($job['filename']) {
@@ -371,15 +376,7 @@ class CurlDownloader
     private function isAuthenticatedRetryNeeded(array $job, Response $response)
     {
         if (in_array($response->getStatusCode(), array(401, 403)) && $job['attributes']['retryAuthFailure']) {
-            $warning = null;
-            if ($response->getHeader('content-type') === 'application/json') {
-                $data = json_decode($response->getBody(), true);
-                if (!empty($data['warning'])) {
-                    $warning = $data['warning'];
-                }
-            }
-
-            $result = $this->authHelper->promptAuthIfNeeded($job['url'], $job['origin'], $response->getStatusCode(), $response->getStatusMessage(), $warning, $response->getHeaders());
+            $result = $this->authHelper->promptAuthIfNeeded($job['url'], $job['origin'], $response->getStatusCode(), $response->getStatusMessage(), $response->getHeaders());
 
             if ($result['retry']) {
                 return $result;

+ 22 - 0
src/Composer/Util/HttpDownloader.php

@@ -17,6 +17,8 @@ use Composer\IO\IOInterface;
 use Composer\Downloader\TransportException;
 use Composer\CaBundle\CaBundle;
 use Composer\Util\Http\Response;
+use Composer\Package\Version\VersionParser;
+use Composer\Semver\Constraint\Constraint;
 use React\Promise\Promise;
 
 /**
@@ -313,4 +315,24 @@ class HttpDownloader
 
         return $resp;
     }
+
+    public static function outputWarnings(IOInterface $io, $url, $data)
+    {
+        foreach (array('warning', 'info') as $type) {
+            if (empty($data[$type])) {
+                continue;
+            }
+
+            if (!empty($data[$type . '-versions'])) {
+                $versionParser = new VersionParser();
+                $constraint = $versionParser->parseConstraints($data[$type . '-versions']);
+                $composer = new Constraint('==', $versionParser->normalize(Composer::getVersion()));
+                if (!$constraint->matches($composer)) {
+                    continue;
+                }
+            }
+
+            $io->writeError('<'.$type.'>'.ucfirst($type).' from '.$url.': '.$data[$type].'</'.$type.'>');
+        }
+    }
 }

+ 8 - 10
src/Composer/Util/RemoteFilesystem.php

@@ -16,6 +16,7 @@ use Composer\Config;
 use Composer\IO\IOInterface;
 use Composer\Downloader\TransportException;
 use Composer\CaBundle\CaBundle;
+use Composer\Util\HttpDownloader;
 
 /**
  * @author François Pluchino <francois.pluchino@opendisplay.com>
@@ -291,15 +292,12 @@ class RemoteFilesystem
 
             if (!empty($http_response_header[0])) {
                 $statusCode = $this->findStatusCode($http_response_header);
+                if ($statusCode >= 400 && $this->findHeaderValue($http_response_header, 'content-type') === 'application/json') {
+                    HttpDownloader::outputWarnings($this->io, $originUrl, json_decode($result, true));
+                }
+
                 if (in_array($statusCode, array(401, 403)) && $this->retryAuthFailure) {
-                    $warning = null;
-                    if ($this->findHeaderValue($http_response_header, 'content-type') === 'application/json') {
-                        $data = json_decode($result, true);
-                        if (!empty($data['warning'])) {
-                            $warning = $data['warning'];
-                        }
-                    }
-                    $this->promptAuthAndRetry($statusCode, $this->findStatusMessage($http_response_header), $warning, $http_response_header);
+                    $this->promptAuthAndRetry($statusCode, $this->findStatusMessage($http_response_header), $http_response_header);
                 }
             }
 
@@ -613,9 +611,9 @@ class RemoteFilesystem
         }
     }
 
-    protected function promptAuthAndRetry($httpStatus, $reason = null, $warning = null, $headers = array())
+    protected function promptAuthAndRetry($httpStatus, $reason = null, $headers = array())
     {
-        $result = $this->authHelper->promptAuthIfNeeded($this->fileUrl, $this->originUrl, $httpStatus, $reason, $warning, $headers);
+        $result = $this->authHelper->promptAuthIfNeeded($this->fileUrl, $this->originUrl, $httpStatus, $reason, $headers);
 
         $this->storeAuth = $result['storeAuth'];
         $this->retry = $result['retry'];