Skip to content

fix(ghrel): route the asset-download endpoint to bytes, not the JSON rewriter - #203

Merged
luthermonson merged 1 commit into
mainfrom
fix/ghrel-asset-endpoint
Sep 22, 2026
Merged

luthermonson merged 1 commit into
mainfrom
fix/ghrel-asset-endpoint

Conversation

@luthermonson

Copy link
Copy Markdown
Contributor

The ghrel proxy took out every php-sdk Linux build the day it was first enabled. This is the fix; the proxy is currently disabled on the fleet to keep builds working.

The bug

The proxy treated every path under /repos/ as JSON metadata. One of them is not — GitHub serves asset bytes from:

/repos/{owner}/{repo}/releases/assets/{id}      Accept: application/octet-stream

That is how a client fetches an asset from a private repo, and it is what spc’s GitHubRelease downloader uses. So it was not an edge case — it was the main path for every type: ghrel artifact.

serveMetadata ran that binary body through rewriteAssetURLs, json.Unmarshal failed, and the handler answered 502. The build saw only:

Download artifact 'zlib' failed. Please check your internet connection
Last failed command: curl -sfSL --max-time 3600 …  - Exit code: 22

Nothing pointing at the proxy — it invented the failure and the error blamed the network. Run 35611830865, 8 retries each.

The fix

isAPIAssetPath matches that one shape and routes it to ServeArtifact against the API upstream, so the bytes stream and cache like any other artifact.

Metadata paths are unaffected and pinned by a table test — /releases, /releases/latest, /releases/tags/{tag} and /releases/assets (no id) all still reach the rewriter. Misrouting the other way would serve every release document as opaque bytes and silently stop rewriting asset URLs, which is the same class of failure in the opposite direction.

Testing

  • binary response under /repos/ served intact and cached (one upstream hit across two requests)
  • the routing predicate, as a table test
  • revert-verified: with the route removed, the regression test reproduces the outage exactly — status 502, want 200

go build, go vet, full ./pkg/proxies/... ./pkg/config/... ./cmd/... suite, and mage lint all clean (the single staticcheck hit is the pre-existing Windows-only one in pkg/networking, which Linux CI does not build).

Re-enabling

After this merges and ships, [ghrel_proxy] enabled = true goes back in the fleet config. Metadata caching was already working before the outage — the cache had entries and logged clean hits — so only the asset path was broken.

…rewriter

The proxy treated every path under /repos/ as JSON metadata. One of them is
not: GitHub serves asset BYTES from

  /repos/{owner}/{repo}/releases/assets/{id}

asked with Accept: application/octet-stream. That is how a client fetches an
asset from a PRIVATE repo, and it is what spc's GitHubRelease downloader uses
-- so it was not an edge case, it was the main path for every `type: ghrel`
artifact.

serveMetadata ran that binary body through rewriteAssetURLs, json.Unmarshal
failed, and the handler answered 502. The client saw only a failed download
with nothing pointing at the proxy:

  Download artifact 'zlib' failed. Please check your internet connection
  Last failed command: curl -sfSL --max-time 3600 ... - Exit code: 22

That took out every php-sdk Linux build the day this proxy was first enabled
(run 35611830865), after 8 retries each. The proxy was disabled on the fleet to
restore builds; this is the fix.

isAPIAssetPath matches that one shape and routes it to ServeArtifact against
the API upstream, so the bytes stream and cache like any other artifact.
Metadata paths are unaffected -- /releases, /releases/latest,
/releases/tags/{tag} and /releases/assets (no id) all still go to the rewriter,
which is pinned by a table test, because misrouting the other way would serve
every release document as opaque bytes and silently stop rewriting asset URLs.

Tests: a binary response under /repos/ served intact and cached (one upstream
hit across two requests), plus the routing predicate. Revert-verified -- with
the route removed the regression test reproduces the outage exactly,
"status 502, want 200".
@ephpm

ephpm Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

ePHPm Preview — removed

Preview deployment has been torn down.

@ephpm
ephpm Bot temporarily deployed to preview-pr-203 September 22, 2026 00:16 Inactive
@ephpm
ephpm Bot temporarily deployed to preview-pr-203 September 22, 2026 00:16 Inactive
@luthermonson
luthermonson merged commit 952dc06 into main Sep 22, 2026
4 checks passed
@luthermonson
luthermonson deleted the fix/ghrel-asset-endpoint branch September 22, 2026 00:26

This branch was successfully deployed

1 active deployment
preview-pr-203 — 00184eae Deployed Sep 22, 2026 by ephpm[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant