DEV Community

OnePassApps
OnePassApps

Posted on

Byte Ranges on app.onepassapps.com: 60 URLs Ignore Them, 11 Answer Them, and the Split Is Not Pages vs Assets

I work on OnePassApps, the team behind app.onepassapps.com, so this is our own site. Everything below was measured from outside the browser on 8 November 2026 with plain HTTPS requests - no session, no cookies, no JavaScript, one build, one edge.

The question is narrow. A client can ask for a slice of a file with a Range header, and a well-behaved server answers 206 Partial Content with just those bytes and a Content-Range header saying what it sent. Does our site do that?

It does for some files and not for others, and the dividing line is not the one you would guess from the file names.

All 56 pages ignore it

I took every URL in our own sitemap.xml - 56 of them - and sent each one Range: bytes=0-99. Every one of them answered 200 with the whole document and no Content-Range header. Not one page answered 206, not one carries Accept-Ranges, and not one carries an ETag either - all 56 answer with cache-control: public, max-age=0, must-revalidate.

A range that cannot possibly be satisfied does not change the answer on a page: Range: bytes=999999999- against the home page still comes back 200 with the whole page, never a 416.

The response length is the same either way. In 20 paired requests the home page answered 25,158 bytes with the range header and 25,158 bytes without it, every time.

The hashed assets answer it

The five hashed files every page on the site pulls in answer 206, carry Accept-Ranges: bytes on the full GET, and answer 416 with Content-Range: bytes */N and an empty body when the range cannot be satisfied:

File Bytes Full GET cache header
/assets/app-shell-shared-DCrZF6q_.js 369,609 public, max-age=31536000, immutable
/assets/index-LNYK_bk0.js 324,591 public, max-age=31536000, immutable
/assets/index-B_evf03w.css 242,648 public, max-age=31536000, immutable
/assets/react-vendor-DY6N_LXH.js 178,924 public, max-age=31536000, immutable
/assets/rolldown-runtime-QTnfLwEv.js 694 public, max-age=31536000, immutable

Three of the seven woff2 fonts the stylesheet lists behave the same way - 25,960 bytes, 18,748 bytes and 11,232 bytes, each answering 206 and then 416.

The slices are byte-exact, not approximate. I compared the 206 payload against the matching prefix of the full body twice for each of the JavaScript, the CSS, the PNG, the favicon and robots.txt - bytes 0-99 and bytes 100-199 - and every slice matched the full body exactly.

A worked example, the main JavaScript chunk, 324,591 bytes:

Range: bytes=0-99
-> 206
   content-range: bytes 0-99/324591
   content-length: 100
   etag: "cab0f31ca3f58fa271aa967504131ed3"
   cache-control: public, max-age=31536000, immutable

Range: bytes=999999999-
-> 416
   content-range: bytes */324591
   content-length: 0
Enter fullscreen mode Exit fullscreen mode

The split is not "pages versus assets"

Here is where the pattern breaks. Seven files that sit at the root of our host and are not HTML pages split across the line:

URL Bytes Honours Range? Accept-Ranges ETag
/robots.txt 160 yes, 206 then 416 bytes present
/apple-touch-icon.png 3,492 yes, 206 then 416 bytes present
/favicon.ico 3,556 yes, 206 then 416 bytes present
/llms.txt 17,965 no, 200 with the whole file absent present
/sitemap.xml 4,046 no, 200 with the whole file absent present
/site.webmanifest 876 no, 200 with the whole file absent present
/brand/sam-mark.svg 531 no, 200 with the whole file absent weak, W/

So robots.txt and the two root icon files behave like the hashed assets, while llms.txt, sitemap.xml, the web manifest and the brand mark behave like the pages - each of them ignoring the range request and answering with the entire file.

Counting everything I tested, 11 URLs honour Range and 60 do not: the 56 sitemap pages plus llms.txt, sitemap.xml, site.webmanifest and the brand SVG on one side, and the five hashed assets, three woff2 fonts, robots.txt, the PNG and the ICO on the other.

Two ranges at once

Range: bytes=0-9,20-29 against a hashed asset answers 206 with Content-Type: multipart/byteranges; boundary=... and each part inside carries its own Content-Range. The body for the main JavaScript chunk came back 236 bytes; for the CSS it was 238 bytes, because the CSS part carries its own Content-Type inside the boundary.

The boundary is a fresh random hex string on every response - six different boundaries in six requests - so two identical multi-range requests do not return byte-identical bodies even though the bytes inside them do.

The pages are not byte-stable either

This is the part I did not expect, and it came out of a different question.

Two plain GETs of the home page are not identical to each other. Over six fetches I got six different bodies, and the only text that differs is Cloudflare's rewritten form of the support email address: each response rewrites that address into a /cdn-cgi/l/email-protection#... link with a fresh random key.

The length moves with it. Forty consecutive fetches of the home page came back at 25,158 bytes every time, while an earlier fetch in the same session returned 25,124 bytes. The guide page I checked held at 30,103 bytes across six fetches, because it carries no address to rewrite.

That matters for the range story in one specific way. For a hashed asset, "the bytes" is a fixed set - that is why a slice can be compared against the whole file and match exactly. For a page, the bytes are not fixed, so there is no stable byte range to hand out in the first place.

What HEAD says

HEAD on a hashed asset answers with content-length and accept-ranges: bytes. HEAD on the home page answers with no content-length at all, and neither does HEAD on llms.txt, even though both of those files have a known length.

What I did not measure

  • One build, one edge location, one day. I did not repeat this from a second network or a second region.
  • I measured through the public host only. I did not look at the origin behind it, and I make no claim about which layer makes each decision.
  • I probed three of the seven woff2 fonts the stylesheet lists, not all of them.
  • I did not test HTTP/1.0 or HTTP/1.1 separately, nor whether a range request behaves differently for a signed-in session.
  • I did not measure the API host api.onepassapps.com, which is a different service with different headers.
  • I did not look at any user-uploaded file. There is no such route here: the Studios process a file in the browser tab, and nothing is stored for us to serve.

So the honest summary is: our pages are always whole, our hashed assets are properly sliceable, and four root files sit on one side or the other for reasons this measurement does not explain.

The site itself: https://app.onepassapps.com/?utm_source=devto&utm_medium=post&utm_campaign=byte-range-contract&utm_content=byte-range-link

And the written guides for every app: https://app.onepassapps.com/guides?utm_source=devto&utm_medium=post&utm_campaign=byte-range-contract&utm_content=guides-link

Top comments (0)