Skip to content

[Feature] Utilize Range, If-Range, Accept-Range, etc for Partial Downloads Support #3501

Description

@Spinnich

Is your feature request related to a problem? Please describe.

When a large download from RomM gets interrupted — Wi-Fi drops, the browser is closed, a VPN reconnects, the server restarts — there is no way to pick up where it left off. You have to start the whole thing over from the beginning. For a large game that can mean re-downloading several gigabytes you'd already pulled down.

This is most painful for the downloads that are already big and slow: multi-file / multi-disc games (which RomM packs into a .zip on the fly) and the "download multiple files" bulk action (also a .zip).

What's actually happening (the "why")

RomM hands the real transfer off to the web server (nginx) it ships with, and there are two different paths:

  • Single files (e.g. one .nes or .gba) are served as plain static files. The web server already advertises that partial/resumable downloads are allowed (Accept-Ranges), so in most browsers and download managers these should already be resumable.
  • Multi-file games and bulk "download N ROMs" are zipped up on the fly by nginx's mod_zip module. Here's the catch: mod_zip does support resuming interrupted downloads (via standard HTTP Range/If-Range requests) — but only if RomM gives it a CRC-32 checksum for each file inside the archive. RomM currently sends - (no checksum) for every file, and per mod_zip's own documentation, leaving the checksum out disables resume support entirely for that archive.

So the archives that are the biggest and most worth resuming are exactly the ones that can't be.

Relevant spots in the code:

  • ZIP manifest lines are built with crc32=None → rendered as -:
    • per-game multi-file download (get_rom_content)
    • bulk download (download_roms)
  • mod_zip requirement: CRC-32 must be supplied up front, otherwise Range support is turned off (see the mod_zip README).

Describe the solution you'd like

Make interrupted ZIP downloads resumable by giving mod_zip what it needs:

  1. Include a correct CRC-32 for each file in the mod_zip manifest instead of -, computed over the bytes that are actually streamed from disk.
  2. Emit a Last-Modified header on the archive response so mod_zip can honor If-Range and safely refuse to resume if the library changed underneath the download.

End result: if a multi-disc or bulk ZIP download dies at 70%, the browser (or a download manager like the one in your OS, or tools like wget -c / curl -C -) can resume from 70% instead of restarting.

For single-file downloads, it would be worth a quick confirmation that resume already works as expected end-to-end (including behind a reverse proxy), since those don't go through mod_zip.

Describe alternatives you've considered

  • Pre-built archives: generate the .zip once and store it, then serve it as a static file (which supports resume for free). Simpler to make resumable, but costs disk space and a build step, and goes stale when files change — probably not worth it.
  • A smarter client-side downloader (download via JavaScript with chunking/retry into a service worker). Much more complex, fights the browser, and would have to re-implement what HTTP already does. Not preferred.
  • Do nothing / document the limitation. Acceptable short-term, but the mod_zip resume feature is already there and just needs the checksums fed to it.

Additional context

  • The known wrinkle: RomM's stored per-file CRC is described in the code as the checksum of the uncompressed content, which won't match the on-disk bytes when a library file is itself compressed/archived — that's why the current code passes -. Implementing this means computing (and ideally caching) the CRC-32 of the exact bytes streamed for each file. That's the real work here, and worth scoping before implementation.
  • This is purely a quality-of-life/reliability improvement — no new metadata or providers involved. It mainly helps people on flaky connections or downloading very large disc-based libraries.
  • Reference: mod_zip documents that Range/If-Range resumable downloads require CRC-32 checksums in the file list, and that omitting them disables Range support.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions