Skip to content

Commit

Permalink
Extensions to give plugins a chance to set specific content-headers.
Browse files Browse the repository at this point in the history
Added Distribution.content_headers_for() and call it from inside
Handler.response_headers().

This is in support of pulp/pulp_rpm#2947

closes pulp#3897.
  • Loading branch information
ggainey committed Jun 8, 2023
1 parent a44a1f1 commit 4221e71
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGES/plugin_api/3897.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Added Distribution.content_headers_for() to let plugins affect content-app response headers.

This can be useful, for example, when it's desirable for specific files to
be served with Cache-control: no-cache.

11 changes: 11 additions & 0 deletions pulpcore/app/models/publication.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,17 @@ def content_handler_list_directory(self, rel_path):
"""
return set()

def content_headers_for(self, path):
"""
Opportunity for Distribution to specify response-headers for a specific path
Args:
path (str): The path being requested
Returns:
Empty dictionary, or a dictionary with HTTP Response header/value pairs.
"""
return {}

@hook(BEFORE_DELETE)
@hook(
AFTER_UPDATE,
Expand Down
19 changes: 13 additions & 6 deletions pulpcore/content/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,20 +344,27 @@ def _permit(request, distribution):
return True

@staticmethod
def response_headers(path):
def response_headers(path, distribution=None):
"""
Get the Content-Type and Encoding-Type headers for the requested `path`.
Args:
path (str): The relative path that was requested.
distribution(Distribution) : Distribution detail that might want to add headers for path
Returns:
headers (dict): A dictionary of response headers.
"""
content_type = mime_types.get_type(path)
headers = {}
if content_type:
if distribution:
headers.update(distribution.content_headers_for(path))

# If dist didn't hand us a content-type, determine from mime_types and set.
content_type = mime_types.get_type(path)
if content_type and not "Content-Type".casefold() in (
key.casefold() for key in headers.keys()
):
headers["Content-Type"] = content_type

return headers

@staticmethod
Expand Down Expand Up @@ -536,7 +543,7 @@ async def _match_and_stream(self, path, request):
if content_handler_result is not None:
return content_handler_result

headers = self.response_headers(rel_path)
headers = self.response_headers(rel_path, distro)

repository = distro.repository
publication = distro.publication
Expand Down Expand Up @@ -568,7 +575,7 @@ async def _match_and_stream(self, path, request):
await publication.published_artifact.aget(relative_path=index_path)

rel_path = index_path
headers = self.response_headers(rel_path)
headers = self.response_headers(rel_path, distro)
except ObjectDoesNotExist:
dir_list, dates, sizes = await self.list_directory(None, publication, rel_path)
dir_list.update(
Expand Down

0 comments on commit 4221e71

Please sign in to comment.