From b6b8013dc97f15afd3c5a667dd80d54dfb5d39f0 Mon Sep 17 00:00:00 2001 From: Uladzimir Tsykun Date: Wed, 3 May 2023 13:50:01 +0200 Subject: [PATCH] Fixes #115. Support lazy load metadata for composer V1 proxy --- src/Mirror/Decorator/ProxyRepositoryFacade.php | 16 +++++++++++----- src/Mirror/Model/HttpMetadataTrait.php | 12 +++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/Mirror/Decorator/ProxyRepositoryFacade.php b/src/Mirror/Decorator/ProxyRepositoryFacade.php index b4082125..c02e5860 100644 --- a/src/Mirror/Decorator/ProxyRepositoryFacade.php +++ b/src/Mirror/Decorator/ProxyRepositoryFacade.php @@ -5,6 +5,7 @@ namespace Packeton\Mirror\Decorator; use Composer\Downloader\TransportException; +use Composer\Util\Http\Response; use Packeton\Composer\MetadataMinifier; use Packeton\Mirror\Exception\MetadataNotFoundException; use Packeton\Mirror\Model\HttpMetadataTrait; @@ -38,11 +39,11 @@ public function findPackageMetadata(string $nameOrUri, int $modifiedSince = null [$package, ] = \explode('$', $nameOrUri); $metadata = $this->fetch(__FUNCTION__, func_get_args(), function () use ($package) { - $metadata = $this->lazyFetchPackageMetadata($package); + $metadata = $this->lazyFetchPackageMetadata($package, $hash); $this->repository->touchRoot(); - $this->repository->dumpPackage($package, $metadata); - return new JsonMetadata(\json_encode($metadata, \JSON_UNESCAPED_SLASHES)); + $this->repository->dumpPackage($package, $metadata, $hash); + return new JsonMetadata(\is_array($metadata) ? \json_encode($metadata, \JSON_UNESCAPED_SLASHES) : $metadata); }); $this->rmp->markEnable($package); @@ -98,7 +99,7 @@ protected function fetch(string $key, array $args = [], callable $fn = null): Js return $meta ? : $fn($args); } - protected function lazyFetchPackageMetadata(string $package): string|array + protected function lazyFetchPackageMetadata(string $package, string &$hash = null): string|array { $http = $this->syncService->initHttpDownloader($this->config); @@ -116,7 +117,12 @@ protected function lazyFetchPackageMetadata(string $package): string|array $this->requestMetadataVia2($http, [$package], $apiUrl, fn ($name, array $meta) => $queue->enqueue($meta), $reject); } elseif ($apiUrl = $this->config->getMetadataV1Url($package)) { - $this->requestMetadataVia1($http, [$package], $apiUrl, fn ($name, array $meta) => $queue->enqueue($meta), $reject, $this->repository->lookupAllProviders()); + $fulfilled = static function ($name, Response $meta, string $currentHash = null) use ($queue, &$hash) { + $hash = $currentHash; + $queue->enqueue($meta->getBody()); + }; + + $this->requestMetadataVia1($http, [$package], $apiUrl, $fulfilled, $reject, $this->repository->lookupAllProviders()); } if (!$queue->isEmpty() && !empty($meta = $queue->dequeue())) { diff --git a/src/Mirror/Model/HttpMetadataTrait.php b/src/Mirror/Model/HttpMetadataTrait.php index c1680635..8a2e0db5 100644 --- a/src/Mirror/Model/HttpMetadataTrait.php +++ b/src/Mirror/Model/HttpMetadataTrait.php @@ -80,7 +80,7 @@ private function requestMetadataVia2(HttpDownloader $downloader, iterable $packa } } - private function requestMetadataVia1(HttpDownloader $downloader, iterable $packages, string $url, callable $onFulfilled, callable $onReject = null, iterable $providersGenerator = []): void + private function requestMetadataVia1(HttpDownloader $downloader, iterable $packages, string $url, callable $onFulfilled, callable $onReject = null, iterable $providers = []): void { $resolvedPackages = $promise = []; $loop = new SignalLoop($downloader, $this->signal); @@ -96,11 +96,13 @@ private function requestMetadataVia1(HttpDownloader $downloader, iterable $packa $refParameter = $reflect->getParameters()[1] ?? null; $asArray = $refParameter && $refParameter->getType()?->getName() === 'array'; - foreach ($providersGenerator as $providers) { + foreach ($providers as $provider) { foreach ($packages as $package) { - if (isset($providers[$package])) { - $packUrl = \str_replace(['%package%', '%hash%'], [$package, $hash ?? ''], $url); - $resolvedPackages[$package] = [\str_replace('$', '', $packUrl), $providers[$package]['sha256'] ?? null]; + if (isset($provider[$package])) { + $hash = $provider[$package]['sha256'] ?? null; + $packUrl = \str_replace(['%package%', '%hash%'], [$package, $hash ?: ''], $url); + $packUrl = empty($hash) ? \str_replace('$', '', $packUrl) : $packUrl; + $resolvedPackages[$package] = [$packUrl, $hash]; } } }