Skip to content

Commit

Permalink
Serve static proxy metadata and use v2 endpoint for dist lookup (#222)
Browse files Browse the repository at this point in the history
  • Loading branch information
akondas authored Jul 16, 2020
1 parent 741e610 commit b79780a
Show file tree
Hide file tree
Showing 34 changed files with 905 additions and 753 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ GA_TRACKING=
###< google analytics ###

###> storage ###
STORAGE_SOURCE=storage.local
PROXY_DIST_DIR=%kernel.project_dir%/var/proxy
PACKAGES_DIST_DIR=%kernel.project_dir%/var/repo
SECURITY_ADVISORIES_DB_DIR=%kernel.project_dir%/var/security-advisories
Expand Down
1 change: 1 addition & 0 deletions .env.docker
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ GA_TRACKING=
###< google analytics ###

###> storage ###
STORAGE_SOURCE=storage.local
PROXY_DIST_DIR=%kernel.project_dir%/var/proxy
PACKAGES_DIST_DIR=%kernel.project_dir%/var/repo
SECURITY_ADVISORIES_DB_DIR=%kernel.project_dir%/var/security-advisories
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"doctrine/orm": "^2.7",
"knplabs/github-api": "^2.12",
"knpuniversity/oauth2-client-bundle": "^2.0",
"league/flysystem-bundle": "^1.5",
"league/oauth2-github": "^2.0",
"m4tthumphrey/php-gitlab-api": "^9.17",
"munusphp/munus": "^0.2.1",
Expand Down
179 changes: 177 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions config/bundles.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle::class => ['all' => true],
League\FlysystemBundle\FlysystemBundle::class => ['all' => true],
];
12 changes: 12 additions & 0 deletions config/packages/flysystem.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Read the documentation at https://github.com/thephpleague/flysystem-bundle/blob/master/docs/1-getting-started.md
flysystem:
storages:
storage.local.proxy:
adapter: 'local'
options:
directory: '%dists_dir%'

proxy.storage:
adapter: 'lazy'
options:
source: '%env(STORAGE_SOURCE)%.proxy'
1 change: 1 addition & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ services:
$distsDir: '%dists_dir%'
$resetPasswordTokenTtl: 86400 # 24h
Symfony\Component\HttpFoundation\Session\Session $session: '@session'
$proxyFilesystem: '@proxy.storage'

# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
Expand Down
8 changes: 0 additions & 8 deletions src/Controller/OrganizationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -342,14 +342,6 @@ public function packageScanResults(Organization $organization, Package $package,
]);
}

protected function getUser(): User
{
/** @var User $user */
$user = parent::getUser();

return $user;
}

private function tryToRemoveWebhook(Package $package): void
{
if ($package->webhookCreatedAt() !== null) {
Expand Down
74 changes: 56 additions & 18 deletions src/Controller/ProxyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
use Buddy\Repman\Message\Proxy\AddDownloads;
use Buddy\Repman\Message\Proxy\AddDownloads\Package;
use Buddy\Repman\Service\Proxy;
use Buddy\Repman\Service\Proxy\Metadata;
use Buddy\Repman\Service\Proxy\ProxyRegister;
use Buddy\Repman\Service\Symfony\ResponseCallback;
use Munus\Control\Option;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\RouterInterface;
Expand Down Expand Up @@ -47,34 +50,59 @@ public function packages(): JsonResponse
}

/**
* @Route("/p/{package}", name="package_provider", requirements={"package"="%package_name_pattern%"}, methods={"GET"})
* @Route("/p/{package}",
* name="package_legacy_metadata",
* host="repo.{domain}",
* defaults={"domain"="%domain%"},
* requirements={"package"="%package_name_pattern%","domain"="%domain%"},
* methods={"GET"})
*/
public function provider(string $package): JsonResponse
public function legacyMetadata(string $package): Response
{
return new JsonResponse($this->register->all()
->map(fn (Proxy $proxy) => $proxy->providerData($package))
/** @var Metadata $metadata */
$metadata = $this->register->all()
->map(fn (Proxy $proxy) => $proxy->legacyMetadata($package))
->find(fn (Option $option) => !$option->isEmpty())
->map(fn (Option $option) => $option->get())
->getOrElse(['packages' => new \stdClass()])
);
->getOrElse(Metadata::fromString('{"packages": {}}'));

return (new StreamedResponse(ResponseCallback::fromStream($metadata->stream()), 200, [
'Accept-Ranges' => 'bytes',
'Content-Type' => 'application/json',
/* @phpstan-ignore-next-line */
'Content-Length' => fstat($metadata->stream())['size'],
]))
->setPublic()
->setLastModified((new \DateTime())->setTimestamp($metadata->timestamp()))
;
}

/**
* @Route("/p2/{package}.json",
* name="package_provider_v2",
* name="package_metadata",
* host="repo.{domain}",
* defaults={"domain"="%domain%"},
* requirements={"package"="%package_name_pattern%","domain"="%domain%"},
* methods={"GET"})
*/
public function providerV2(string $package): JsonResponse
public function metadata(string $package): Response
{
return new JsonResponse($this->register->all()
->map(fn (Proxy $proxy) => $proxy->providerDataV2($package))
/** @var Metadata $metadata */
$metadata = $this->register->all()
->map(fn (Proxy $proxy) => $proxy->metadata($package))
->find(fn (Option $option) => !$option->isEmpty())
->map(fn (Option $option) => $option->get())
->getOrElse(['packages' => new \stdClass()])
);
->getOrElseThrow(new NotFoundHttpException());

return (new StreamedResponse(ResponseCallback::fromStream($metadata->stream()), 200, [
'Accept-Ranges' => 'bytes',
'Content-Type' => 'application/json',
/* @phpstan-ignore-next-line */
'Content-Length' => fstat($metadata->stream())['size'],
]))
->setPublic()
->setLastModified((new \DateTime())->setTimestamp($metadata->timestamp()))
;
}

/**
Expand All @@ -85,14 +113,24 @@ public function providerV2(string $package): JsonResponse
* requirements={"package"="%package_name_pattern%","ref"="[a-f0-9]*?","type"="zip|tar","domain"="%domain%"},
* methods={"GET"})
*/
public function distribution(string $package, string $version, string $ref, string $type): BinaryFileResponse
public function distribution(string $package, string $version, string $ref, string $type): Response
{
return new BinaryFileResponse($this->register->all()
->map(fn (Proxy $proxy) => $proxy->distFilename($package, $version, $ref, $type))
/** @var resource $stream */
$stream = $this->register->all()
->map(fn (Proxy $proxy) => $proxy->distribution($package, $version, $ref, $type))
->find(fn (Option $option) => !$option->isEmpty())
->map(fn (Option $option) => $option->get())
->getOrElseThrow(new NotFoundHttpException('This distribution file can not be found or downloaded from origin url.'))
);
->getOrElseThrow(new NotFoundHttpException('This distribution file can not be found or downloaded from origin url.'));

return (new StreamedResponse(ResponseCallback::fromStream($stream), 200, [
'Accept-Ranges' => 'bytes',
'Content-Type' => 'application/zip',
/* @phpstan-ignore-next-line */
'Content-Length' => fstat($stream)['size'],
]))
->setPublic()
->setEtag($ref)
;
}

/**
Expand Down
Loading

0 comments on commit b79780a

Please sign in to comment.