mirror of
https://github.com/TencentCloud/Octop.git
synced 2026-10-02 07:34:38 +08:00
`_fetch_ranking_json` was the only fetch in this module that hand-rolled
`urllib.request.urlopen` instead of calling `_http_request`.
`response.read()` therefore buffered the whole body with no size limit, where
`_http_request` checks `Content-Length` and then reads in `HTTP_READ_CHUNK`
slices up to `MAX_HTTP_BYTES` — the search path already passes a cap.
Its `except` ladder also stopped at `HTTPError`/`URLError`/`TimeoutError`, so a
mid-stream `ConnectionResetError` or an `http.client.HTTPException` escaped as a
raw exception. The endpoint that serves rankings (`routers/skills.py::
_hub_rankings`, used by `GET /skills/hub/rankings` and
`GET /agents/{id}/skills/hub/rankings`) only maps `SkillHubMarketError` to 502
and `SkillHubMarketTimeout` to 504, so an upstream hiccup became an opaque 500.
Rankings now go through `_http_request` like `_fetch_search_json` and
`_download_skillhub_package` already do. The 4 MiB JSON cap is named
`_MAX_JSON_BYTES` and used by both JSON fetches instead of repeating the literal.
`_Response` in `tests/unit/agents/test_skillhub_market.py` is the stub that
`test_fetch_ranking_json_uses_showcase_endpoint` hands back from `urlopen`, so it
has to accept the `size` argument `_http_request` passes. It now wraps the
payload in `io.BytesIO` and reads exactly like `_BytesResponse` next door, which
also makes the read loop stop on the first empty chunk instead of spinning.