Skip to content

Commit ec47b34

Browse files
committed
less strict heuristics in HEAD request
1 parent bdd62a1 commit ec47b34

File tree

1 file changed

+35
-13
lines changed

1 file changed

+35
-13
lines changed

src/lazyFile.ts

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -164,28 +164,49 @@ export class LazyUint8Array {
164164
private checkServer() {
165165
var xhr = new XMLHttpRequest();
166166
const url = this.rangeMapper(0, 0).url;
167+
// can't set Accept-Encoding header :( https://stackoverflow.com/questions/41701849/cannot-modify-accept-encoding-with-fetch
167168
xhr.open("HEAD", url, false);
169+
// maybe this will help it not use compression?
170+
xhr.setRequestHeader("Range", "bytes=" + 0 + "-" + this._chunkSize);
168171
xhr.send(null);
169172
if (!((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304))
170173
throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
171-
var datalength = Number(xhr.getResponseHeader("Content-length"));
174+
var datalength: number | null = Number(
175+
xhr.getResponseHeader("Content-length")
176+
);
172177

173178
var hasByteServing = xhr.getResponseHeader("Accept-Ranges") === "bytes";
174-
var usesGzip = xhr.getResponseHeader("Content-Encoding") === "gzip";
179+
const encoding = xhr.getResponseHeader("Content-Encoding");
180+
var usesCompression = encoding && encoding !== "identity";
175181

176182
if (!hasByteServing) {
177183
const msg =
178-
"server either does not support byte serving or does not advertise it (`Accept-Ranges: bytes` header missing), or your database is hosted on CORS and the server doesn't mark the accept-ranges header as exposed.";
179-
console.warn(msg, "seen response headers:", xhr.getAllResponseHeaders());
184+
"Warning: The server did not respond with Accept-Ranges=bytes. It either does not support byte serving or does not advertise it (`Accept-Ranges: bytes` header missing), or your database is hosted on CORS and the server doesn't mark the accept-ranges header as exposed. This may lead to incorrect results.";
185+
console.warn(
186+
msg,
187+
"(seen response headers:",
188+
xhr.getAllResponseHeaders(),
189+
")"
190+
);
180191
// throw Error(msg);
181192
}
182-
183-
if (usesGzip || !datalength) {
184-
console.error("response headers", xhr.getAllResponseHeaders());
185-
throw Error("server uses gzip or doesn't have length");
193+
if (usesCompression) {
194+
console.warn(
195+
`Warning: The server responded with ${encoding} encoding to a HEAD request. Ignoring since it may not do so for Range HTTP requests, but this will lead to incorrect results otherwise since the ranges will be based on the compressed data instead of the uncompressed data.`
196+
);
197+
}
198+
if (usesCompression) {
199+
// can't use the given data length if there's compression
200+
datalength = null;
186201
}
187202

188-
if (!this._length) this._length = datalength;
203+
if (!this._length) {
204+
if (!datalength) {
205+
console.error("response headers", xhr.getAllResponseHeaders());
206+
throw Error("Length of the file not known. It must either be supplied in the config or given by the HTTP server.");
207+
}
208+
this._length = datalength;
209+
}
189210
this.serverChecked = true;
190211
}
191212
get length() {
@@ -221,10 +242,11 @@ export class LazyUint8Array {
221242
throw new Error(
222243
"only " + this.length + " bytes available! programmer error!"
223244
);
224-
const { fromByte: from, toByte: to, url } = this.rangeMapper(
225-
absoluteFrom,
226-
absoluteTo
227-
);
245+
const {
246+
fromByte: from,
247+
toByte: to,
248+
url,
249+
} = this.rangeMapper(absoluteFrom, absoluteTo);
228250

229251
// TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
230252
var xhr = new XMLHttpRequest();

0 commit comments

Comments
 (0)