Skip to content

Serve small text-based files inline instead of redirecting to S3#314

Open
kabilar wants to merge 1 commit into
dandi:mainfrom
kabilar:zarr-metadata
Open

Serve small text-based files inline instead of redirecting to S3#314
kabilar wants to merge 1 commit into
dandi:mainfrom
kabilar:zarr-metadata

Conversation

@kabilar

@kabilar kabilar commented Jun 12, 2026

Copy link
Copy Markdown
Member

Problem

GET requests for assets such as .json, .yaml, .tsv, .md, and .bidsignore files are redirected to S3, which serves them with a Content-Type: application/octet-stream. Browsers download these files rather than displaying them inline.

Fix

dandidav now fetches small text-based files (≤ 10 MiB) itself and serves them with a browser-displayable content type instead of redirecting:

  • JSON — any .json file, plus Zarr metadata files .zattrs/.zarray/.zgroup (which have no extension) — served as application/json
  • YAML.yaml/.yml — served as text/yaml, matching the virtual dandiset.yaml files
  • Other text.tsv/.csv/.md/.txt/.bidsignore — served as text/plain, which browsers reliably display inline (more specific types like text/tab-separated-values tend to be downloaded)

Files larger than 10 MiB continue to be redirected to S3 as before, to avoid buffering large amounts of data in memory. This also covers Zarr entries served via both the Archive and the Zarr manifests.

In the HTML collection view, links for these files now point to dandidav's own path (rather than directly to the S3 download URL) so that clicking them displays the file inline.

Verification

  • Added inline_content_type unit tests covering JSON / YAML / plain-text / Zarr-metadata / non-inline cases (case-insensitive extensions included)
  • cargo test (367 passing), cargo clippy, and cargo fmt --check all clean
  • Tested end-to-end against real assets in dandisets/001412: dataset_description.jsonapplication/json and .bidsignoretext/plain, both 200 with no Content-Disposition (display inline), versus the current 307 → S3 → application/octet-stream (download)

🤖 Generated with Claude Code

Previously, GET requests for assets such as JSON, YAML, TSV, and other
text-based files were redirected to S3, which serves them with an
`application/octet-stream` content type, causing browsers to download
them rather than display them inline.

dandidav now fetches such files (when no larger than 10 MiB) and serves
them itself with a browser-displayable content type:
- JSON files (any `.json`, plus Zarr metadata `.zattrs`/`.zarray`/
  `.zgroup`) as `application/json`
- YAML files (`.yaml`/`.yml`) as `text/yaml`
- Other text files (`.tsv`/`.csv`/`.md`/`.txt`/`.bidsignore`) as
  `text/plain`

Larger files continue to be redirected to S3 as before.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kabilar kabilar requested a review from yarikoptic June 12, 2026 18:37
@kabilar

kabilar commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

cc @satra @ayendiki @balbasty

@kabilar

kabilar commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

Hi @yarikoptic, for context I would like to be able to directly display text files (zarr.json, tsv, etc.) in the browser rather than downloading. I tested the functionality locally and it works, but I relied on claude to generate the code since I don't have much experience with rust. Thanks.

@kabilar

kabilar commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

Here is a dandiset with several of those file types (tsv, json, yaml, .bidsignore) that can be used for testing: https://webdav.dandiarchive.org/dandisets/001412/draft/

@yarikoptic yarikoptic left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it might be just a matter of providing extra url options like we do on dandiarchive.org already: e.g. on https://dandiarchive.org/dandiset/001412/draft/files?location= you can

  1. open in the browser -- https://api.dandiarchive.org/api/assets/7d298d77-4bca-4a3f-91e3-ab81b22ebd48/download?content_disposition=inline
  2. download -- https://api.dandiarchive.org/api/assets/7d298d77-4bca-4a3f-91e3-ab81b22ebd48/download/

so I would have just added that [view] or just 👁 which would have the URL with the URL with ?content_disposition=inline to the download API endpoint. Or am I missing the goal here?

@kabilar

kabilar commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

Hi @yarikoptic, that's a good idea. Using content_disposition=inline worked for the .json file as you showed (and yaml currently displays inline with webdav), but it doesn't work for .bidsignore, .tsv, zarr.json. The asset still downloads. Would I need to change the DANDI download API endpoint to display inline for these asset types? Thanks.

@yarikoptic

Copy link
Copy Markdown
Member

sure -- as much as possible to centralize/formalize instead of ad-hoc solutions on webdav level. Here worth double checking (I forgot) how it is interacting with encodingFormat -- see discussion in elderly

and potentially just give it current assessment etc. Related (might be addressed by working on this)

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