Explorar el Código

Deduplicate findHeaderValue code

Jordi Boggiano hace 5 años
padre
commit
bfee701f9b

+ 2 - 3
src/Composer/Repository/Vcs/GitHubDriver.php

@@ -19,7 +19,6 @@ use Composer\Cache;
 use Composer\IO\IOInterface;
 use Composer\Util\GitHub;
 use Composer\Util\Http\Response;
-use Composer\Util\RemoteFilesystem;
 
 /**
  * @author Jordi Boggiano <j.boggiano@seld.be>
@@ -346,10 +345,10 @@ class GitHubDriver extends VcsDriver
                     $scopesIssued = array();
                     $scopesNeeded = array();
                     if ($headers = $e->getHeaders()) {
-                        if ($scopes = RemoteFilesystem::findHeaderValue($headers, 'X-OAuth-Scopes')) {
+                        if ($scopes = Response::findHeaderValue($headers, 'X-OAuth-Scopes')) {
                             $scopesIssued = explode(' ', $scopes);
                         }
-                        if ($scopes = RemoteFilesystem::findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) {
+                        if ($scopes = Response::findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) {
                             $scopesNeeded = explode(' ', $scopes);
                         }
                     }

+ 0 - 1
src/Composer/Util/Http/CurlDownloader.php

@@ -16,7 +16,6 @@ use Composer\Config;
 use Composer\IO\IOInterface;
 use Composer\Downloader\TransportException;
 use Composer\CaBundle\CaBundle;
-use Composer\Util\RemoteFilesystem;
 use Composer\Util\StreamContextFactory;
 use Composer\Util\AuthHelper;
 use Composer\Util\Url;

+ 24 - 14
src/Composer/Util/Http/Response.php

@@ -61,20 +61,7 @@ class Response
 
     public function getHeader($name)
     {
-        $value = null;
-        foreach ($this->headers as $header) {
-            if (preg_match('{^'.$name.':\s*(.+?)\s*$}i', $header, $match)) {
-                $value = $match[1];
-            } elseif (preg_match('{^HTTP/}i', $header)) {
-                // TODO ideally redirects would be handled in CurlDownloader/RemoteFilesystem and this becomes unnecessary
-                //
-                // In case of redirects, headers contains the headers of all responses
-                // so we reset the flag when a new response is being parsed as we are only interested in the last response
-                $value = null;
-            }
-        }
-
-        return $value;
+        return self::findHeaderValue($this->headers, $name);
     }
 
     public function getBody()
@@ -91,4 +78,27 @@ class Response
     {
         $this->request = $this->code = $this->headers = $this->body = null;
     }
+
+    /**
+     * @param  array       $headers array of returned headers like from getLastHeaders()
+     * @param  string      $name    header name (case insensitive)
+     * @return string|null
+     */
+    public static function findHeaderValue(array $headers, $name)
+    {
+        $value = null;
+        foreach ($headers as $header) {
+            if (preg_match('{^'.preg_quote($name).':\s*(.+?)\s*$}i', $header, $match)) {
+                $value = $match[1];
+            } elseif (preg_match('{^HTTP/}i', $header)) {
+                // TODO ideally redirects would be handled in CurlDownloader/RemoteFilesystem and this becomes unnecessary
+                //
+                // In case of redirects, http_response_headers contains the headers of all responses
+                // so we reset the flag when a new response is being parsed as we are only interested in the last response
+                $value = null;
+            }
+        }
+
+        return $value;
+    }
 }

+ 7 - 27
src/Composer/Util/RemoteFilesystem.php

@@ -17,6 +17,7 @@ use Composer\IO\IOInterface;
 use Composer\Downloader\TransportException;
 use Composer\CaBundle\CaBundle;
 use Composer\Util\HttpDownloader;
+use Composer\Util\Response;
 
 /**
  * @author François Pluchino <francois.pluchino@opendisplay.com>
@@ -143,27 +144,6 @@ class RemoteFilesystem
         return $this->lastHeaders;
     }
 
-    /**
-     * @param  array       $headers array of returned headers like from getLastHeaders()
-     * @param  string      $name    header name (case insensitive)
-     * @return string|null
-     */
-    public static function findHeaderValue(array $headers, $name)
-    {
-        $value = null;
-        foreach ($headers as $header) {
-            if (preg_match('{^'.$name.':\s*(.+?)\s*$}i', $header, $match)) {
-                $value = $match[1];
-            } elseif (preg_match('{^HTTP/}i', $header)) {
-                // In case of redirects, http_response_headers contains the headers of all responses
-                // so we reset the flag when a new response is being parsed as we are only interested in the last response
-                $value = null;
-            }
-        }
-
-        return $value;
-    }
-
     /**
      * @param  array    $headers array of returned headers like from getLastHeaders()
      * @return int|null
@@ -294,7 +274,7 @@ 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') {
+                if ($statusCode >= 400 && Response::findHeaderValue($http_response_header, 'content-type') === 'application/json') {
                     HttpDownloader::outputWarnings($this->io, $originUrl, json_decode($result, true));
                 }
 
@@ -303,7 +283,7 @@ class RemoteFilesystem
                 }
             }
 
-            $contentLength = !empty($http_response_header[0]) ? $this->findHeaderValue($http_response_header, 'content-length') : null;
+            $contentLength = !empty($http_response_header[0]) ? Response::findHeaderValue($http_response_header, 'content-length') : null;
             if ($contentLength && Platform::strlen($result) < $contentLength) {
                 // alas, this is not possible via the stream callback because STREAM_NOTIFY_COMPLETED is documented, but not implemented anywhere in PHP
                 $e = new TransportException('Content-Length mismatch, received '.Platform::strlen($result).' bytes out of the expected '.$contentLength);
@@ -360,8 +340,8 @@ class RemoteFilesystem
         $locationHeader = null;
         if (!empty($http_response_header[0])) {
             $statusCode = $this->findStatusCode($http_response_header);
-            $contentType = $this->findHeaderValue($http_response_header, 'content-type');
-            $locationHeader = $this->findHeaderValue($http_response_header, 'location');
+            $contentType = Response::findHeaderValue($http_response_header, 'content-type');
+            $locationHeader = Response::findHeaderValue($http_response_header, 'location');
         }
 
         // check for bitbucket login page asking to authenticate
@@ -417,7 +397,7 @@ class RemoteFilesystem
 
         // decode gzip
         if ($result && extension_loaded('zlib') && substr($fileUrl, 0, 4) === 'http' && !$hasFollowedRedirect) {
-            $contentEncoding = $this->findHeaderValue($http_response_header, 'content-encoding');
+            $contentEncoding = Response::findHeaderValue($http_response_header, 'content-encoding');
             $decode = $contentEncoding && 'gzip' === strtolower($contentEncoding);
 
             if ($decode) {
@@ -700,7 +680,7 @@ class RemoteFilesystem
 
     private function handleRedirect(array $http_response_header, array $additionalOptions, $result)
     {
-        if ($locationHeader = $this->findHeaderValue($http_response_header, 'location')) {
+        if ($locationHeader = Response::findHeaderValue($http_response_header, 'location')) {
             if (parse_url($locationHeader, PHP_URL_SCHEME)) {
                 // Absolute URL; e.g. https://example.com/composer
                 $targetUrl = $locationHeader;