From c72929ec86b671d3fe8ed0711ac4bbec8633847f Mon Sep 17 00:00:00 2001 From: David Davis Date: Thu, 2 Nov 2023 13:45:20 -0400 Subject: [PATCH] Allow content_handler to return a content artifact fixes #4635 --- CHANGES/plugin_api/4635.feature | 2 ++ docs/plugin_dev/api-reference/content-app.rst | 5 ++++- pulpcore/content/handler.py | 17 ++++++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 CHANGES/plugin_api/4635.feature diff --git a/CHANGES/plugin_api/4635.feature b/CHANGES/plugin_api/4635.feature new file mode 100644 index 0000000000..160741c7d2 --- /dev/null +++ b/CHANGES/plugin_api/4635.feature @@ -0,0 +1,2 @@ +Added content app feature to accept a ``ContentArtifact`` from ``content_handler`` so that the +plugin writer no longer has to generate a response when dealing with ``ContentArtifacts``. diff --git a/docs/plugin_dev/api-reference/content-app.rst b/docs/plugin_dev/api-reference/content-app.rst index 41df5b2591..deb0c446d2 100644 --- a/docs/plugin_dev/api-reference/content-app.rst +++ b/docs/plugin_dev/api-reference/content-app.rst @@ -17,7 +17,10 @@ Making a custom Handler is a two-step process: If content needs to be served from within the :term:`Distribution`'s base_path, overriding the :meth:`~pulpcore.plugin.models.Distribution.content_handler` and :meth:`~pulpcore.plugin.models.Distribution.content_handler_directory_listing` -methods in your Distribution is an easier way to serve this content. +methods in your Distribution is an easier way to serve this content. The +:meth:`~pulpcore.plugin.models.Distribution.content_handler` method should +return an instance of `aiohttp.web_response.Response` or a +`pulpcore.plugin.models.ContentArtifact`. Creating your Handler --------------------- diff --git a/pulpcore/content/handler.py b/pulpcore/content/handler.py index 46cc8e60fd..45704d9918 100644 --- a/pulpcore/content/handler.py +++ b/pulpcore/content/handler.py @@ -573,11 +573,22 @@ async def _match_and_stream(self, path, request): if not ends_in_slash: rel_path = f"{rel_path}/" + headers = self.response_headers(original_rel_path, distro) + content_handler_result = await sync_to_async(distro.content_handler)(original_rel_path) if content_handler_result is not None: - return content_handler_result - - headers = self.response_headers(original_rel_path, distro) + if isinstance(content_handler_result, ContentArtifact): + if content_handler_result.artifact: + return await self._serve_content_artifact( + content_handler_result, headers, request + ) + else: + return await self._stream_content_artifact( + request, StreamResponse(headers=headers), content_handler_result + ) + else: + # the result is a response so just return it + return content_handler_result repository = distro.repository publication = distro.publication