Skip to content

Commit 5ef78fa

Browse files
committed
Fix incorrect Content-Type header in Registry API
fixes: #1997 (cherry picked from commit e416df5)
1 parent d91bab6 commit 5ef78fa

File tree

4 files changed

+20
-9
lines changed

4 files changed

+20
-9
lines changed

CHANGES/1997.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed the Registry API returning 'charset utf-8' in the Content-Type header.

pulp_container/app/cache.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ def make_key(self, request):
3737
key = ":".join(all_keys[k] for k in self.keys)
3838
return key
3939

40+
async def make_response(self, key, base_key):
41+
"""Fix the Content-Type header to remove the charset."""
42+
response = await super().make_response(key, base_key)
43+
if response is not None:
44+
response.headers["Content-Type"] = response.headers["Content-Type"].split(";")[0]
45+
return response
46+
4047

4148
class RegistryApiCache(RegistryCache, SyncContentCache):
4249
"""A wrapper around the Redis content cache handler tailored for the registry API."""

pulp_container/app/registry.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ async def get_tag(self, request):
140140
"Docker-Content-Digest": digest,
141141
"Docker-Distribution-API-Version": "registry/2.0",
142142
}
143-
return web.Response(text=raw_text_manifest, headers=headers)
143+
return web.Response(body=raw_text_manifest, headers=headers)
144144
else:
145145
raise PathNotResolved(tag_name)
146146

@@ -176,7 +176,7 @@ async def get_tag(self, request):
176176
"Docker-Content-Digest": digest,
177177
"Docker-Distribution-API-Version": "registry/2.0",
178178
}
179-
return web.Response(text=raw_text_manifest, headers=headers)
179+
return web.Response(body=raw_text_manifest, headers=headers)
180180

181181
accepted_media_types = get_accepted_media_types(request.headers)
182182

@@ -200,7 +200,7 @@ async def get_tag(self, request):
200200
"Content-Type": return_media_type,
201201
"Docker-Content-Digest": tag.tagged_manifest.digest,
202202
}
203-
return web.Response(text=tag.tagged_manifest.data, headers=response_headers)
203+
return web.Response(body=tag.tagged_manifest.data, headers=response_headers)
204204

205205
# return what was found in case media_type is accepted header (docker, oci)
206206
if tag.tagged_manifest.media_type in accepted_media_types:
@@ -209,7 +209,7 @@ async def get_tag(self, request):
209209
"Content-Type": return_media_type,
210210
"Docker-Content-Digest": tag.tagged_manifest.digest,
211211
}
212-
return web.Response(text=tag.tagged_manifest.data, headers=response_headers)
212+
return web.Response(body=tag.tagged_manifest.data, headers=response_headers)
213213

214214
# return 404 in case the client is requesting docker manifest v2 schema 1
215215
raise PathNotResolved(tag_name)
@@ -249,7 +249,7 @@ async def get_by_digest(self, request):
249249
"Content-Type": manifest.media_type,
250250
"Docker-Content-Digest": manifest.digest,
251251
}
252-
return web.Response(text=manifest.data, headers=headers)
252+
return web.Response(body=manifest.data, headers=headers)
253253
elif content_type == "blobs":
254254
ca = await ContentArtifact.objects.select_related("artifact", "content").aget(
255255
content__in=content, relative_path=digest
@@ -278,7 +278,7 @@ async def get_by_digest(self, request):
278278
"Docker-Content-Digest": digest,
279279
"Docker-Distribution-API-Version": "registry/2.0",
280280
}
281-
return web.Response(text=raw_text_manifest, headers=headers)
281+
return web.Response(body=raw_text_manifest, headers=headers)
282282
elif content_type == "blobs":
283283
# there might be a case where the client has all the manifest data in place
284284
# and tries to download only missing blobs; because of that, only the reference

pulp_container/tests/functional/api/test_content_cache.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,26 @@ def _check_content(expect_metadata, dist_url, tag_name="latest", headers=None):
3131
duplicated_content_units = sorted([manifest_by_tag, manifest_by_digest] * 2)
3232
for i, c in enumerate(duplicated_content_units):
3333
url = urljoin(dist_url, c)
34-
check_cache(url, expect_metadata(i), headers, auth)
34+
check_cache(url, expect_metadata(i), headers, auth, MEDIA_TYPE.MANIFEST_LIST)
3535

3636
duplicated_content_units = [blob_by_digest] * 2
3737
for i, c in enumerate(duplicated_content_units):
3838
url = urljoin(dist_url, c)
39-
check_cache(url, expect_metadata(i), headers, auth)
39+
check_cache(url, expect_metadata(i), headers, auth, "application/octet-stream")
4040

4141
return _check_content
4242

4343

44-
def check_cache(url, expected_metadata, headers, auth):
44+
def check_cache(url, expected_metadata, headers, auth, content_type):
4545
"""A helper function to check if cache miss or hit occurred."""
4646
auth = get_auth_for_url(url, auth=auth)
4747

4848
response = requests.get(url, auth=auth, headers=headers)
4949
response_metadata = fetch_response_metadata(response)
5050
assert expected_metadata == response_metadata, url
51+
# Check that we return the correct content type for both cache hits and misses
52+
if response.status_code == 200:
53+
assert response.headers.get("Content-Type") == content_type, url
5154

5255

5356
def fetch_response_metadata(response):

0 commit comments

Comments
 (0)