From df0a2cdd0aa61ccd50c5fcd4bea7f495a8118554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ph=C3=A9na=20Proxima?= Date: Thu, 8 Apr 2021 11:08:13 -0400 Subject: [PATCH] Fire POST_FILE_DOWNLOAD event for metadata fetched by ComposerRepository. --- src/Composer/Plugin/PostFileDownloadEvent.php | 53 +++++++++++++++---- .../Repository/ComposerRepository.php | 19 ++++++- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/Composer/Plugin/PostFileDownloadEvent.php b/src/Composer/Plugin/PostFileDownloadEvent.php index 370f58cd4..0ec8eddde 100644 --- a/src/Composer/Plugin/PostFileDownloadEvent.php +++ b/src/Composer/Plugin/PostFileDownloadEvent.php @@ -38,32 +38,41 @@ class PostFileDownloadEvent extends Event private $url; /** - * @var \Composer\Package\PackageInterface + * @var mixed */ - private $package; + private $context; + + /** + * @var string + */ + private $type; /** * Constructor. * * @param string $name The event name - * @param string $fileName The file name + * @param string|null $fileName The file name * @param string|null $checksum The checksum * @param string $url The processed url - * @param PackageInterface $package The package. + * @param mixed $context Additional context for the download. + * @param string $type The type (package or metadata). */ - public function __construct($name, $fileName, $checksum, $url, PackageInterface $package) + public function __construct($name, $fileName, $checksum, $url, $context = null, $type = 'package') { parent::__construct($name); $this->fileName = $fileName; $this->checksum = $checksum; $this->url = $url; - $this->package = $package; + $this->context = $context; + $this->type = $type; } /** * Retrieves the target file name location. * - * @return string + * If this download is of type metadata, null is returned. + * + * @return string|null */ public function getFileName() { @@ -90,13 +99,39 @@ class PostFileDownloadEvent extends Event return $this->url; } + /** + * Returns the context of this download, if any. + * + * If this download is of type package, the package object is returned. If + * this download is of type metadata, the HTTP response is returned. + * + * @return mixed + */ + public function getContext() + { + return $this->context; + } + /** * Get the package. * - * @return \Composer\Package\PackageInterface The package. + * If this download is of type metadata, null is returned. + * + * @return \Composer\Package\PackageInterface|null The package. */ public function getPackage() { - return $this->package; + $context = $this->getContext(); + return $context instanceof PackageInterface ? $context : null; + } + + /** + * Returns the type of this download (package, metadata). + * + * @return string + */ + public function getType() + { + return $this->type; } } diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 5d238c713..3554d5656 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -22,6 +22,7 @@ use Composer\Json\JsonFile; use Composer\Cache; use Composer\Config; use Composer\IO\IOInterface; +use Composer\Plugin\PostFileDownloadEvent; use Composer\Semver\CompilingMatcher; use Composer\Util\HttpDownloader; use Composer\Util\Loop; @@ -1110,6 +1111,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito throw new RepositorySecurityException('The contents of '.$filename.' do not match its signature. This could indicate a man-in-the-middle attack or e.g. antivirus software corrupting files. Try running composer again and report this if you think it is a mistake.'); } + if ($this->eventDispatcher) { + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, $sha256, $filename, $response, 'metadata'); + $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + } + $data = $response->decodeJson(); HttpDownloader::outputWarnings($this->io, $this->url, $data); @@ -1188,6 +1194,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito return true; } + if ($this->eventDispatcher) { + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, $response, 'metadata'); + $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + } + $data = $response->decodeJson(); HttpDownloader::outputWarnings($this->io, $this->url, $data); @@ -1258,9 +1269,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $url = $this->url; $cache = $this->cache; $degradedMode = &$this->degradedMode; + $eventDispatcher = $this->eventDispatcher; $repo = $this; - $accept = function ($response) use ($io, $url, $filename, $cache, $cacheKey, $repo) { + $accept = function ($response) use ($io, $url, $filename, $cache, $cacheKey, $eventDispatcher, $repo) { // package not found is acceptable for a v2 protocol repository if ($response->getStatusCode() === 404) { $repo->packagesNotFoundCache[$filename] = true; @@ -1275,6 +1287,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito return true; } + if ($eventDispatcher) { + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $url, $response, 'metadata'); + $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + } + $data = $response->decodeJson(); HttpDownloader::outputWarnings($io, $url, $data);