Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. ComposerRepository.php

function ComposerRepository::asyncFetchFile

@phpstan-return PromiseInterface<array<mixed>|true> true if the response was a 304 and the cache is fresh, otherwise it returns the decoded json

File

vendor/composer/composer/src/Composer/Repository/ComposerRepository.php, line 1630

Class

ComposerRepository
@author Jordi Boggiano <j.boggiano@seld.be>

Namespace

Composer\Repository

Code

private function asyncFetchFile(string $filename, string $cacheKey, ?string $lastModifiedTime = null) : PromiseInterface {
    if ('' === $filename) {
        throw new \InvalidArgumentException('$filename should not be an empty string');
    }
    if (isset($this->packagesNotFoundCache[$filename])) {
        return \React\Promise\resolve([
            'packages' => [],
        ]);
    }
    if (isset($this->freshMetadataUrls[$filename]) && $lastModifiedTime) {
        // make it look like we got a 304 response
        
        /** @var PromiseInterface<true> $promise */
        $promise = \React\Promise\resolve(true);
        return $promise;
    }
    $httpDownloader = $this->httpDownloader;
    $options = $this->options;
    if ($this->eventDispatcher) {
        $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', [
            'repository' => $this,
        ]);
        $preFileDownloadEvent->setTransportOptions($this->options);
        $this->eventDispatcher
            ->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
        $filename = $preFileDownloadEvent->getProcessedUrl();
        $options = $preFileDownloadEvent->getTransportOptions();
    }
    if ($lastModifiedTime) {
        if (isset($options['http']['header'])) {
            $options['http']['header'] = (array) $options['http']['header'];
        }
        $options['http']['header'][] = 'If-Modified-Since: ' . $lastModifiedTime;
    }
    $io = $this->io;
    $url = $this->url;
    $cache = $this->cache;
    $degradedMode =& $this->degradedMode;
    $eventDispatcher = $this->eventDispatcher;
    
    /**
     * @return array<mixed>|true true if the response was a 304 and the cache is fresh
     */
    $accept = function ($response) use ($io, $url, $filename, $cache, $cacheKey, $eventDispatcher) {
        // package not found is acceptable for a v2 protocol repository
        if ($response->getStatusCode() === 404) {
            $this->packagesNotFoundCache[$filename] = true;
            return [
                'packages' => [],
            ];
        }
        $json = (string) $response->getBody();
        if ($json === '' && $response->getStatusCode() === 304) {
            $this->freshMetadataUrls[$filename] = true;
            return true;
        }
        if ($eventDispatcher) {
            $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, 'metadata', [
                'response' => $response,
                'repository' => $this,
            ]);
            $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent);
        }
        $data = $response->decodeJson();
        HttpDownloader::outputWarnings($io, $url, $data);
        $lastModifiedDate = $response->getHeader('last-modified');
        $response->collect();
        if ($lastModifiedDate) {
            $data['last-modified'] = $lastModifiedDate;
            $json = JsonFile::encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        }
        if (!$cache->isReadOnly()) {
            $cache->write($cacheKey, $json);
        }
        $this->freshMetadataUrls[$filename] = true;
        return $data;
    };
    $reject = function ($e) use ($filename, $accept, $io, $url, &$degradedMode, $lastModifiedTime) {
        if ($e instanceof TransportException && $e->getStatusCode() === 404) {
            $this->packagesNotFoundCache[$filename] = true;
            return false;
        }
        if (!$degradedMode) {
            $io->writeError('<warning>' . $url . ' could not be fully loaded (' . $e->getMessage() . '), package information was loaded from the local cache and may be out of date</warning>');
        }
        $degradedMode = true;
        // if the file is in the cache, we fake a 304 Not Modified to allow the process to continue
        if ($lastModifiedTime) {
            return $accept(new Response([
                'url' => $url,
            ], 304, [], ''));
        }
        // special error code returned when network is being artificially disabled
        if ($e instanceof TransportException && $e->getStatusCode() === 499) {
            return $accept(new Response([
                'url' => $url,
            ], 404, [], ''));
        }
        throw $e;
    };
    return $httpDownloader->add($filename, $options)
        ->then($accept, $reject);
}
RSS feed
Powered by Drupal