Skip to content

Commit 3bb452d

Browse files
committed
Fix some content negotiation issues
1 parent 1eb656d commit 3bb452d

2 files changed

Lines changed: 43 additions & 13 deletions

File tree

pulp_rust/app/views.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from rest_framework.viewsets import ViewSet
88
from rest_framework.response import Response
99
from rest_framework.exceptions import Throttled
10+
from rest_framework.renderers import BaseRenderer
1011
from django.core.exceptions import ObjectDoesNotExist
1112
from django.shortcuts import redirect, get_object_or_404
1213

@@ -30,13 +31,22 @@
3031
log = logging.getLogger(__name__)
3132

3233
BASE_CONTENT_URL = urljoin(settings.CONTENT_ORIGIN, settings.CONTENT_PATH_PREFIX)
33-
BASE_API_URL = urljoin(settings.CRATES_IO_API_HOSTNAME, "/pulp/cargo/")
34-
CRATES_IO_API = "/api/v1/crates/"
34+
35+
36+
class PlainTextRenderer(BaseRenderer):
37+
"""Renderer for text/plain responses (Cargo sends Accept: text/plain)."""
38+
39+
media_type = "text/plain"
40+
format = "txt"
41+
42+
def render(self, data, accepted_media_type=None, renderer_context=None):
43+
return data
3544

3645

3746
class ApiMixin:
3847
"""Mixin to get index specific info."""
3948

49+
renderer_classes = [PlainTextRenderer]
4050
_distro = None
4151

4252
@property
@@ -87,14 +97,17 @@ def initial(self, request, *args, **kwargs):
8797
super().initial(request, *args, **kwargs)
8898
domain_name = get_domain().name
8999
repo = self.kwargs["repo"]
100+
scheme = request.META.get("HTTP_X_FORWARDED_PROTO", request.scheme)
101+
host = request.META.get("HTTP_X_FORWARDED_HOST", request.get_host())
102+
base_api_url = f"{scheme}://{host}/pulp/cargo/"
90103
if settings.DOMAIN_ENABLED:
91104
self.base_content_url = urljoin(BASE_CONTENT_URL, f"pulp/cargo/{domain_name}/{repo}/")
92-
self.base_api_url = urljoin(BASE_API_URL, f"{domain_name}/{repo}/")
93-
self.base_download_url = urljoin(BASE_API_URL, f"{domain_name}/{repo}{CRATES_IO_API}")
105+
self.base_api_url = f"{base_api_url}{domain_name}/{repo}/"
106+
self.base_download_url = f"{base_api_url}{domain_name}/{repo}/api/v1/crates"
94107
else:
95108
self.base_content_url = urljoin(BASE_CONTENT_URL, f"pulp/cargo/{repo}/")
96-
self.base_api_url = urljoin(BASE_API_URL, f"{repo}/")
97-
self.base_download_url = urljoin(BASE_API_URL, f"{repo}{CRATES_IO_API}")
109+
self.base_api_url = f"{base_api_url}{repo}/"
110+
self.base_download_url = f"{base_api_url}{repo}/api/v1/crates"
98111

99112
@classmethod
100113
def urlpattern(cls):
@@ -221,13 +234,12 @@ class IndexRoot(ApiMixin, ViewSet):
221234
@extend_schema(responses={200: IndexRootSerializer}, summary="Get index info")
222235
def retrieve(self, request, repo):
223236
"""Gets index route."""
224-
return Response(
225-
data={
226-
"dl": self.base_download_url,
227-
"api": self.base_api_url,
228-
"auth-required": False,
229-
}
230-
)
237+
data = {
238+
"dl": self.base_download_url,
239+
"api": self.base_api_url,
240+
"auth-required": False,
241+
}
242+
return HttpResponse(json.dumps(data), content_type="application/json")
231243

232244

233245
class CargoDownloadApiView(APIView):
@@ -238,6 +250,7 @@ class CargoDownloadApiView(APIView):
238250
# Authentication disabled for now
239251
authentication_classes = []
240252
permission_classes = []
253+
renderer_classes = [PlainTextRenderer]
241254

242255
def get_full_path(self, base_path, pulp_domain=None): # TODO: replace with ApiMixin?
243256
if settings.DOMAIN_ENABLED:

pulp_rust/tests/functional/api/test_cargo_api.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ def test_config_json(
3131
assert "/api/v1/crates/" in config["dl"]
3232

3333

34+
def test_config_json_accept_text_plain(
35+
rust_repo_factory,
36+
rust_distribution_factory,
37+
cargo_registry_url,
38+
):
39+
"""config.json should be served when Accept: text/plain is sent (as Cargo does)."""
40+
repository = rust_repo_factory()
41+
distribution = rust_distribution_factory(repository=repository.pulp_href)
42+
43+
config_url = urljoin(cargo_registry_url(distribution.base_path), "config.json")
44+
downloaded = download_file(config_url, headers={"Accept": "text/plain"})
45+
assert downloaded.response_obj.status == 200
46+
47+
config = json.loads(downloaded.body)
48+
assert "dl" in config
49+
50+
3451
def test_config_json_dl_points_to_pulp(
3552
rust_remote_factory,
3653
rust_repo_factory,

0 commit comments

Comments
 (0)