StorageClient.download_object() does not follow HTTP redirects. When the InsForge storage backend returns a 302 to the CDN (cdn.insforge.dev), httpx stops at the redirect because AsyncClient is initialized without follow_redirects=True. The method returns a StorageDownloadResult where content is the near-empty redirect body, not the actual file.
Steps to reproduce
- Upload a file to a private bucket using
storage.upload_object()
- Download it using
storage.download_object()
- Inspect
result.content — it will be empty bytes or a small HTML redirect body, not the uploaded file
Expected behavior
download_object() should return the actual file bytes regardless of whether InsForge serves them directly or via a CDN redirect.
Actual behavior
Returns the 302 redirect body when the bucket is CDN-backed.
Root cause
# _base_client.py
self.http_client = httpx.AsyncClient() # missing follow_redirects=True
download_object() calls self._client.http_client.request(...) which inherits this default. httpx.AsyncClient.request() accepts follow_redirects as a per-request parameter — the fix is straightforward.
Suggested fix
Either initialize AsyncClient with follow_redirects=True, or pass follow_redirects=True directly in the download_object request call.
StorageClient.download_object()does not follow HTTP redirects. When the InsForge storage backend returns a302to the CDN (cdn.insforge.dev),httpxstops at the redirect becauseAsyncClientis initialized withoutfollow_redirects=True. The method returns aStorageDownloadResultwherecontentis the near-empty redirect body, not the actual file.Steps to reproduce
storage.upload_object()storage.download_object()result.content— it will be empty bytes or a small HTML redirect body, not the uploaded fileExpected behavior
download_object()should return the actual file bytes regardless of whether InsForge serves them directly or via a CDN redirect.Actual behavior
Returns the 302 redirect body when the bucket is CDN-backed.
Root cause
download_object()callsself._client.http_client.request(...)which inherits this default.httpx.AsyncClient.request()acceptsfollow_redirectsas a per-request parameter — the fix is straightforward.Suggested fix
Either initialize
AsyncClientwithfollow_redirects=True, or passfollow_redirects=Truedirectly in thedownload_objectrequest call.