Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,13 @@ async def _make_request(

def _create_httpx_client(self) -> httpx.AsyncClient:
"""Creates a new httpx.AsyncClient with appropriate SSL/mTLS configuration."""
# The Agent Registry media download (alt=media) replies with a 302 to a
# short-lived GCS signed URL, so the client must follow redirects; httpx
# drops the Authorization header on cross-origin redirects, so the OAuth
# token is not forwarded to the signed-URL host.
if self._ssl_context is not None:
return httpx.AsyncClient(verify=self._ssl_context)
return httpx.AsyncClient()
return httpx.AsyncClient(verify=self._ssl_context, follow_redirects=True)
return httpx.AsyncClient(follow_redirects=True)

async def get_skill(self, *, name: str) -> models.Skill:
"""Fetches a skill from the registry.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import io
import os
import ssl
from unittest import mock
import zipfile

Expand Down Expand Up @@ -455,7 +456,9 @@ async def mock_get(url, *unused_args, **kwargs):
skill = await registry.get_skill(name="my-skill")

# Verify AsyncClient was instantiated with verify=mock_ssl_context
mock_client_class.assert_called_with(verify=mock_ssl_context)
mock_client_class.assert_called_with(
verify=mock_ssl_context, follow_redirects=True
)

assert skill.frontmatter.name == "my-skill"

Expand Down Expand Up @@ -491,3 +494,22 @@ async def test_use_custom_credentials():
}),
params={"search_string": "query"},
)


@pytest.mark.asyncio
async def test_create_httpx_client_follows_redirects():
"""Clients follow the 302 redirect issued by the media download endpoint."""
registry = gcp_skill_registry.GCPSkillRegistry()

client = registry._create_httpx_client()
try:
assert client.follow_redirects is True
finally:
await client.aclose()

registry._ssl_context = ssl.create_default_context()
client = registry._create_httpx_client()
try:
assert client.follow_redirects is True
finally:
await client.aclose()