{
  "flavors": {
    "ok": "The control, fully correct: Accept-Ranges, strong ETag, Last-Modified; single, suffix, open-ended and multiple ranges (multipart/byteranges), 416 with \"bytes */length\" when unsatisfiable, If-Range honored (strong validators only), and the conditional headers evaluated as RFC 9110 says. HEAD ignores Range, as the spec requires. No Range gets a 200.",
    "ignore": "No range support at all: no Accept-Ranges header, and every request gets a 200 with the full body. Legal — range support is optional — and the #1 real-world case: a resuming client must notice the 200 and start over, not append.",
    "advertise-only": "Advertises Accept-Ranges: bytes on every response, then ignores every Range header and sends 200 with the full body. Aimed at segmented downloaders (aria2 and friends) that split into N connections because of the advertisement — and then receive N full bodies.",
    "off-by-one": "Treats the range end as exclusive: bytes=a-b gets bytes a..b-1, one short, while Content-Range still claims a-b. Content-Length matches the short body, so the two headers disagree — the classic fencepost, one missing byte per segment. The lie is applied to the first range; extra ranges are ignored.",
    "shifted": "Serves bytes a+1..b+1 while Content-Range claims a-b. The envelope looks right; every byte is wrong — detectable only because the body is self-describing (the offsets inside the file will not match where you put them). At the end of the document the shifted window is clamped, so the final segment also runs one byte short. First range only.",
    "suffix-as-prefix": "The naive suffix-range bug: bytes=-n is served as the FIRST n bytes of the document while Content-Range claims the last n. A client resuming \"the tail\" appends the head — silent corruption on exactly the request curl sends for a suffix. The lie applies when the first range is a suffix; any other request is served correctly, multipart included.",
    "from-zero": "Acknowledges your range with a 206 — then serves the whole document from byte zero, with an honest Content-Range: bytes 0-{length-1}/{length} that simply disagrees with what you asked. A client that appends without checking Content-Range against its request builds a file with a duplicated prefix.",
    "wrong-total": "Correct bytes, but Content-Range lies about the total: bytes a-b/{2×length}. Asking for bytes past the real end gets 416 with the same inflated total, so a download loop that trusts it never finishes. First range only.",
    "no-content-range": "A single-range 206 with the right bytes and no Content-Range header (a violation of RFC 9110 §15.3.7). What offset does your client think this is? First range only.",
    "always-206": "A request with no Range header still gets a 206 (Content-Range: bytes 0-{length-1}/{length}, full body). With a valid Range it behaves correctly; an ignored Range (malformed, or over the caps) is treated as absent, so it also gets the full-body 206. Some CDNs and proxies really do this.",
    "200-content-range": "Honors the range — right bytes, right Content-Range header — but the status is 200. A contradiction: which does your client believe, the status or the header? First range only.",
    "always-416": "Every Range request gets 416 with Content-Range: bytes */{length}; without Range, a 200. Tests give-up-and-restart logic.",
    "unknown-total": "Correct 206, but Content-Range says bytes a-b/* — total unknown, which is legal. Preallocation and progress logic that requires the total breaks. First range only.",
    "if-range-ignored": "The resource changes on every request (a generation stamp appears in the ETag and in every line of the body) and If-Range is ignored: a stale validator still gets a 206 from the new generation, where a correct server would send the full 200. Resume across it and your file mixes generations — run grep -oE \"g[0-9a-f]{16}\" file | sort -u on it: more than one value is the corruption. Nondeterministic by design."
  },
  "usage": "/range/{flavor}?length=1000",
  "document": "Deterministic and self-describing: 64-byte lines, each \"{offset:08d} {length:08d} badhttp range body {gen}\" padded with dots to 63 characters plus a newline; line 0 at length=1000 is \"00000000 00001000 badhttp range body g1\" + 24 dots. The final line is cut at ?length= (default 1000, max 1048576), so the document may end mid-line. The generation is g1 everywhere except if-range-ignored.",
  "limits": {
    "max_bytes": 1048576,
    "max_ranges_per_request": 8,
    "note": "more ranges than the cap, a total span over max_bytes, or any invalid range spec makes the whole Range header ignored — treated as if no Range was sent (a 200 with the full body at every flavor except always-206, which then sends its full-body 206, and always-416, which answers any Range header, even an ignorable one, with its 416)"
  },
  "conditionals": "ok evaluates If-Match / If-Unmodified-Since / If-None-Match / If-Modified-Since correctly and honors If-Range; the misbehaving flavors ignore conditionals entirely (their subject is ranges — /etag is the conditional-request family). HEAD ignores Range on every flavor, as RFC 9110 §14.2 requires.",
  "multipart": "Several satisfiable ranges come back as multipart/byteranges (boundary \"badhttp\"), served in request order without coalescing; when only one of several survives clamping it is served as a plain single-range 206. Responses are cache-control: no-store, no-transform — this family tests clients, not caches; point caches at /etag."
}
