From: Michael Tremer Date: Sun, 9 Feb 2025 13:31:04 +0000 (+0000) Subject: registry: Split the combined handlers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f4a600d1b34a01406c3f10e2ea4d0d8106f21ed;p=pbs.git registry: Split the combined handlers I think this might all be slightly better to read instead of all the ifs and elses. Signed-off-by: Michael Tremer --- diff --git a/src/web/__init__.py b/src/web/__init__.py index 0d7d2b72..0d0da656 100644 --- a/src/web/__init__.py +++ b/src/web/__init__.py @@ -206,11 +206,13 @@ class Application(tornado.web.Application): # Manifests (r"/v2/([a-z0-9]+(?:(?:\.|_|__|-+)[a-z0-9]+)*(?:\/[a-z0-9]+(?:(?:\.|_|__|-+)[a-z0-9]+)*)*)/manifests/([a-zA-Z0-9_][a-zA-Z0-9._-]{0,127})", - registry.ManifestHandler), + registry.ManifestLabelHandler), # Blobs & Manifests referenced by digest - (r"/v2/([a-z0-9]+(?:(?:\.|_|__|-+)[a-z0-9]+)*(?:\/[a-z0-9]+(?:(?:\.|_|__|-+)[a-z0-9]+)*)*)/(blobs|manifests)/(sha256:[a-f0-9]{64})", - registry.BlobOrManifestHandler), + (r"/v2/([a-z0-9]+(?:(?:\.|_|__|-+)[a-z0-9]+)*(?:\/[a-z0-9]+(?:(?:\.|_|__|-+)[a-z0-9]+)*)*)/manifests/(sha256:[a-f0-9]{64})", + registry.ManifestHandler), + (r"/v2/([a-z0-9]+(?:(?:\.|_|__|-+)[a-z0-9]+)*(?:\/[a-z0-9]+(?:(?:\.|_|__|-+)[a-z0-9]+)*)*)/blobs/(sha256:[a-f0-9]{64})", + registry.ManifestHandler), # Catch anything else (r"/v2/.*", registry.NotFoundHandler), diff --git a/src/web/registry.py b/src/web/registry.py index 0bda117e..0c7a7a29 100644 --- a/src/web/registry.py +++ b/src/web/registry.py @@ -83,21 +83,21 @@ class IndexHandler(BaseHandler): pass -class ManifestHandler(BaseHandler): +class ManifestLabelHandler(BaseHandler): async def head(self, *args, **kwargs): return await self.get(*args, **kwargs, send_body=False) - async def get(self, distro_slug, release_slug, send_body=True): + async def get(self, distro_slug, label, send_body=True): # Fetch the distribution distro = await self.backend.distros.get_by_slug(distro_slug) if not distro: raise tornado.web.HTTPError(404) # Fetch the release - if release_slug == "latest": + if label == "latest": release = await distro.get_latest_release() else: - release = await distro.get_release(release_slug) + release = await distro.get_release(label) # Fail if we could not find a release if not release: @@ -133,37 +133,47 @@ class ManifestHandler(BaseHandler): self.finish(index) -class BlobOrManifestHandler(BaseHandler): +class ManifestHandler(BaseHandler): async def head(self, *args, **kwargs): return await self.get(*args, **kwargs, send_body=False) - async def get(self, distro_slug, type, reference, send_body=True): + async def get(self, distro_slug, digest, send_body=True): # Fetch the distribution distro = await self.backend.distros.get_by_slug(distro_slug) if not distro: raise tornado.web.HTTPError(404) # Fetch the blob - blob = await self.get_blob(distro, reference) + blob = await self.get_blob(distro, digest) if not blob: raise tornado.web.HTTPError(404) + # Set Content-Type + self.set_header("Content-Type", "application/vnd.oci.image.manifest.v1+json") + # Send the blob! - return await self._send_blob(blob, type, send_body=send_body) + if send_body: + await self.stream_blob(blob) - async def _send_blob(self, blob, type, send_body=True): - """ - Sends the blob to the client - """ - # Set Content-Type - if type == "manifests": - self.set_header("Content-Type", "application/vnd.oci.image.manifest.v1+json") - else: - self.set_header("Content-Type", "application/octet-stream") - # It would be nice to set Content-Length here, but there is no way to - # determine the length of the file without reading the whole thing first. +class BlobHandler(BaseHandler): + async def head(self, *args, **kwargs): + return await self.get(*args, **kwargs, send_body=False) + + async def get(self, distro_slug, digest, send_body=True): + # Fetch the distribution + distro = await self.backend.distros.get_by_slug(distro_slug) + if not distro: + raise tornado.web.HTTPError(404) + + # Fetch the blob + blob = await self.get_blob(distro, digest) + if not blob: + raise tornado.web.HTTPError(404) - # Done if we should not send the body + # Set Content-Type + self.set_header("Content-Type", "application/octet-stream") + + # Send the blob! if send_body: await self.stream_blob(blob)