Skip to content

fix(assets): serve unchunked assets to range requests - #596

Open
yhabib wants to merge 1 commit into
mainfrom
fix/range-request-unchunked-assets
Open

yhabib wants to merge 1 commit into
mainfrom
fix/range-request-unchunked-assets

Conversation

@yhabib

@yhabib yhabib commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

Slack shows no link card for most proposals. Slackbot sends Range: bytes=0-32768, and on mainnet a Range GET on a stored proposal page returns 503 backend_response_verification. Only the first fetch of a page works, so 144742 got a card, and 144740 and 144743 did not.

AssetRouter stores an asset under a byte range only if the asset is chunked. On any other asset, Range selects the wildcard index.html fallback, and the gateway rejects it. The same 503 happens on / and /robots.txt.

Changes

  • Removed the Range header before serve_asset, unless the asset is chunked.
  • Kept Range on chunked assets, because the gateway uses it to fetch the later chunks of core-bg-original.mp4.
  • Added tests for a Range request on a proposal page and on a chunked asset.
  • Tested with real Slack through a tunnel: a stored page on the fixed local canister unfurled, and the same request to mainnet got 503. Both video chunks still return 206.

A Range header on an unchunked asset selected the wildcard fallback,
and the HTTP gateway rejected the response with a 503. Slack link
previews failed on each stored proposal page for this reason.

Remove the header unless the asset is chunked.
@yhabib
yhabib requested a review from a team as a code owner November 7, 2026 08:13
Copilot AI balanced review requested due to automatic review settings November 7, 2026 08:13
@zeropath-ai

zeropath-ai Bot commented Nov 7, 2026

Copy link
Copy Markdown

✅ No security or compliance issues detected. Reviewed everything up to 74f6694.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► src/governance-app-backend/src/assets.rs
      Add range header handling and new without_unusable_range function
► src/governance-app-backend/src/assets.rs
      Improve asset serving to handle Range requests for chunked assets
► src/governance-app-backend/src/assets.rs
      Add tests for range requests and chunked asset behavior

@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown

📊 Build Bundle Stats

The latest build generated the following assets:

dist/index.html                                           6.12 kB │ gzip:   1.73 kB
dist/assets/index-DHR8rj0Y.css                          150.06 kB │ gzip:  24.02 kB
dist/assets/icpLedger-MLP5bV9V.js                         0.23 kB │ gzip:   0.21 kB
dist/assets/useNowInSeconds-CAzBdtFb.js                   0.43 kB │ gzip:   0.31 kB
dist/assets/Skeleton-DpfiAV0_.js                          0.44 kB │ gzip:   0.32 kB
dist/assets/webhid-D0yio6wG.js                            0.53 kB │ gzip:   0.32 kB
dist/assets/advancedFeatures-rM9sysYS.js                  0.53 kB │ gzip:   0.27 kB
dist/assets/useTvlValue-CLfcKjOJ.js                       0.60 kB │ gzip:   0.41 kB
dist/assets/webVitals-BJ_6xNUg.js                         0.63 kB │ gzip:   0.46 kB
dist/assets/nnsDapp-uyZgu8f3.js                           0.68 kB │ gzip:   0.25 kB
dist/assets/SkeletonPageHeader-DDZQdNyQ.js                0.76 kB │ gzip:   0.47 kB
dist/assets/PageHeader-jXzaR6sL.js                        0.77 kB │ gzip:   0.45 kB
dist/assets/CertifiedBadge-BAvA48CJ.js                    0.81 kB │ gzip:   0.48 kB
dist/assets/SkeletonStatCard-j2crj6cH.js                  0.81 kB │ gzip:   0.50 kB
dist/assets/Separator-D7SxEzOg.js                         0.83 kB │ gzip:   0.50 kB
dist/assets/useForecastPeriod-8uu2M8KV.js                 1.00 kB │ gzip:   0.60 kB
dist/assets/utils-Dm3Qrhxk.js                             1.02 kB │ gzip:   0.59 kB
dist/assets/useIcpIndex-ZJ8pM-_M.js                       1.09 kB │ gzip:   0.64 kB
dist/assets/useSubaccountsMetadata-em-spJfH.js            1.10 kB │ gzip:   0.62 kB
dist/assets/numbers-xhCGVRHh.js                           1.15 kB │ gzip:   0.57 kB
dist/assets/routeLoaders-1fbHRTb-.js                      1.19 kB │ gzip:   0.56 kB
dist/assets/rolldown-runtime-DAXXjFlN.js                  1.26 kB │ gzip:   0.70 kB
dist/assets/useHardwareWalletsMetadata-ZDp9XLKV.js        1.39 kB │ gzip:   0.69 kB
dist/assets/events-9ZuUx-9S.js                            1.66 kB │ gzip:   0.86 kB
dist/assets/SkeletonListRows-DnRLT1bW.js                  1.69 kB │ gzip:   0.53 kB
dist/assets/useLedgerNeuronCall-C7HPG81x.js               1.90 kB │ gzip:   1.04 kB
dist/assets/errors-C_oENL0S.js                            1.95 kB │ gzip:   0.97 kB
dist/assets/AnimatedNumber-Bxl0VJoE.js                    1.98 kB │ gzip:   1.13 kB
dist/assets/useCommandPaletteSettings-Hkxeox8W.js         2.12 kB │ gzip:   1.06 kB
dist/assets/addressBook-CGq4fZ7R.js                       2.14 kB │ gzip:   1.20 kB
dist/assets/useIcpIndexTransactionsPolling-DcqjQ1PN.js    2.17 kB │ gzip:   1.16 kB
dist/assets/useGovernanceAppCanister-BNyb49Jm.js          2.41 kB │ gzip:   1.07 kB
dist/assets/useShortcutSettings-CIMkGclb.js               2.41 kB │ gzip:   1.19 kB
dist/assets/useAddHotkey-B4rOsu9d.js                      2.61 kB │ gzip:   1.35 kB
dist/assets/governance-CqTKKPTj.js                        2.99 kB │ gzip:   1.15 kB
dist/assets/ToggleGroup-BpKDDXY_.js                       3.09 kB │ gzip:   1.41 kB
dist/assets/useClaimPendingDeviceStakes-tuFSirES.js       3.12 kB │ gzip:   1.43 kB
dist/assets/SkeletonText-C9PV9DoV.js                      3.71 kB │ gzip:   1.29 kB
dist/assets/useAccounts-Cs9CRgGp.js                       4.98 kB │ gzip:   2.21 kB
dist/assets/tickers-BK3qt5Hi.js                           6.54 kB │ gzip:   2.73 kB
dist/assets/AlertDialog-Bd9LZvkg.js                       7.73 kB │ gzip:   2.72 kB
dist/assets/DeviceActionDetail-CwuwNZhO.js                8.45 kB │ gzip:   3.03 kB
dist/assets/TopicFollowingAccordion-DrEssECv.js           8.55 kB │ gzip:   3.41 kB
dist/assets/routes-DbmNAmZQ.js                            8.96 kB │ gzip:   3.08 kB
dist/assets/ledgerIdentity-CbGbEww2.js                   10.16 kB │ gzip:   3.70 kB
dist/assets/MutationDialog-DZuAezGu.js                   11.55 kB │ gzip:   4.04 kB
dist/assets/spamFilter-C1ggTJ8p.js                       11.77 kB │ gzip:   5.02 kB
dist/assets/ResponsiveDialog-GYnXkXbJ.js                 14.56 kB │ gzip:   4.06 kB
dist/assets/_id-DfTmgk3Z.js                              16.61 kB │ gzip:   5.33 kB
dist/assets/AmountInput-BixPYx5l.js                      16.96 kB │ gzip:   6.77 kB
dist/assets/_auth-BNL2JF0b.js                            22.49 kB │ gzip:   8.29 kB
dist/assets/HideBalancesToggle-B4BK25dB.js               22.99 kB │ gzip:   8.58 kB
dist/assets/vendor-buffer-EX-AqChq.js                    26.95 kB │ gzip:   8.18 kB
dist/assets/accounts-Bat4TbO3.js                         32.08 kB │ gzip:  10.90 kB
dist/assets/SendICPButton-CLYif-pU.js                    37.11 kB │ gzip:  13.54 kB
dist/assets/settings-CglCarnz.js                         54.47 kB │ gzip:  15.55 kB
dist/assets/dashboard-f6HWo05J.js                        57.76 kB │ gzip:  19.10 kB
dist/assets/voting-D8_PAntw.js                           69.29 kB │ gzip:  21.74 kB
dist/assets/index-DcdYgLZl.js                            69.56 kB │ gzip:  20.58 kB
dist/assets/vendor-md-DQa12sMs.js                        73.29 kB │ gzip:  19.98 kB
dist/assets/button-DGmLHM0C.js                           86.42 kB │ gzip:  29.04 kB
dist/assets/neurons-Cjc09SCW.js                          90.51 kB │ gzip:  27.16 kB
dist/assets/DisburseModal-B8LVpZVz.js                   101.47 kB │ gzip:  29.64 kB
dist/assets/vendor-tanstack-D12Yy7ks.js                 120.02 kB │ gzip:  39.22 kB
dist/assets/vendor-jsqr-CjiBYtfG.js                     129.98 kB │ gzip:  47.50 kB
dist/assets/vendor-core-react-bRRjyX41.js               189.81 kB │ gzip:  59.76 kB
dist/assets/vendor-recharts-DQ8kALIQ.js                 280.26 kB │ gzip:  76.83 kB
dist/assets/vendor-ledger-Bz6feAP8.js                   403.26 kB │ gzip:  98.84 kB
dist/assets/vendor-icp-e5O_ocwA.js                      468.31 kB │ gzip: 117.84 kB
dist/assets/vendor-libs-BjQATLf3.js                     587.62 kB │ gzip: 189.56 kB

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

The asset range-routing change has no active review issues blocking approval.

No open issues 🎉

What changed in this PR

This PR fixes asset routing for Range requests so unchunked assets, including proposal previews, return the correct certified response instead of the wildcard fallback.

Changes:

  • Removes Range headers before serving unchunked assets.
  • Preserves range handling for chunked assets such as videos.
  • Adds regression tests for full proposal-page responses and partial chunked-asset responses.
File Description
src/​governance-app-backend/​src/​assets.rs Filters range headers based on asset chunking and adds regression tests.

Review effort: Balanced

@yhabib
yhabib enabled auto-merge November 7, 2026 12:02
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.

2 participants