Skip to main content

Module http

Module http 

Source
Expand description

An HTTP(S)-backed RangeReader for native hosts (SPEC.md §9): point it at a URL and it fetches only the byte ranges a query needs via HTTP Range requests. Behind the http feature, because it brings a network stack; the CLI, the Python wheels and the R package all read remote files through this one implementation. The browser engine has its own readers (sync XHR and fetch), which follow the same contract.

Uses blocking ureq with rustls (the tls feature), so http:// and https:// both work — the file can live on S3, GitHub, or any CDN that honors Range, which is the format’s whole deployment story.

Remote time is round trips, not bytes, so the reader does three things:

  • One agent, kept-alive connections. Every request goes through one ureq::Agent whose pool keeps up to FetchPolicy::concurrency idle connections to the host. ureq::get builds a fresh agent per call, so each range used to open (and, on https://, TLS-handshake) its own connection: one to three extra round trips per request.
  • Batches in parallel. RangeReader::read_many (the engine’s batch of tile or dictionary-chunk faults for one query step) goes out with up to FetchPolicy::concurrency requests in flight, from a work queue, so one slow range does not hold up the ranges queued behind it.
  • Nearby ranges coalesced. Ranges of one batch at most FetchPolicy::coalesce_gap apart are fetched as one request (up to FetchPolicy::max_span long) and sliced apart again.

A transient failure (a dropped connection, a short body, 408/429/5xx) is retried with exponential backoff; a permanent one (a 404, a Content-Range for the wrong offset) fails at once. Any range of a batch failing fails the batch, and the ranges still queued are not started.

A host that ignores Range answers 200 with the whole body (a plain static server, a proxy that strips the header, a CDN serving a cached full object). That body has crossed the network by the time the reader sees it, and every later range request would download it again, so when it is the file — exactly the length the open measured — and at most FetchPolicy::whole_body_cap (WHOLE_BODY_CAP, 256 MiB, the browser readers’ cap) it is kept, and every read from then on is a slice of it. A larger body is refused by name, without being read: the reader never holds more than the cap of a body nobody asked for. Taking the first len bytes of a 200 as if they were the range is the one thing it never does.

Structs§

FetchPolicy
How HttpRangeReader fetches: fan-out, coalescing, retries, and the whole-body cap. FetchPolicy::from_env reads it once when a reader opens.
HttpRangeReader
An HTTP(S) RangeReader: kept-alive connections, parallel and coalesced batches, retries, and the bounded whole-body fallback for hosts that ignore Range (see the module docs).

Constants§

WHOLE_BODY_CAP
The largest whole body (a 200 to a range request) the reader keeps and serves reads from — the same 256 MiB the browser readers keep.