Skip to content

Commit e1f21d6

Browse files
author
Hector Martin
committed
Add support for browsers that don't support Exponse-Header
If the HEAD request fails or its Content-Length header is missing, fall back to a full file load instead of Range requests. This also works if the server doesn't support Range for some reason.
1 parent c331331 commit e1f21d6

File tree

2 files changed

+45
-26
lines changed

2 files changed

+45
-26
lines changed

test/index.html

+3-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
chunkSize: 300000,
3434
loop: true,
3535
autoStart: true,
36-
debug: false,
36+
debug: true,
3737
}
3838
var p = new ZipImagePlayer(options);
3939
var w = 320;
@@ -71,14 +71,13 @@
7171
$("#stop").on("click", function() { p.stop(); });
7272

7373
var options = {
74-
// no source: unzipped animation
7574
canvas: document.getElementById("canvasj"), // <canvas>
7675
source: "big_buck_bunny_jpg.zip",
7776
metadata: jpeg_meta, // TBD: json metadata format
7877
chunkSize: 300000,
7978
loop: true,
8079
autoStart: true,
81-
debug: true,
80+
debug: false,
8281
}
8382
var pj = new ZipImagePlayer(options);
8483

@@ -88,7 +87,7 @@
8887
metadata: hon_meta, // TBD: json metadata format
8988
loop: true,
9089
autoStart: true,
91-
debug: true,
90+
debug: false,
9291
}
9392
var p2 = new ZipImagePlayer(options);
9493
$(p2).on("loadProgress", function(ev, progress) {

zip_player.js

+42-22
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ ZipImagePlayer.prototype = {
122122
}
123123
},
124124
_load: function(offset, length, callback) {
125-
var end = offset + length;
126125
var _this = this;
127126
// Unfortunately JQuery doesn't support ArrayBuffer XHR
128127
var xhr = new XMLHttpRequest();
@@ -132,27 +131,40 @@ ZipImagePlayer.prototype = {
132131
}
133132
_this._debugLog("Load: " + offset + " " + length + " status=" +
134133
xhr.status);
135-
if (xhr.status != 206) {
136-
_this._error("Unexpected HTTP status " + xhr.status);
137-
}
138-
if (xhr.response.byteLength != length) {
139-
_this._error("Unexpected length " + xhr.response.byteLength +
140-
" (expected " + length + ")");
134+
if (xhr.status == 200) {
135+
_this._debugLog("Range disabled or unsupported, complete load");
136+
offset = 0;
137+
length = xhr.response.byteLength;
138+
_this._len = length;
139+
_this._buf = xhr.response;
140+
_this._bytes = new _this._Uint8Array(_this._buf);
141+
} else {
142+
if (xhr.status != 206) {
143+
_this._error("Unexpected HTTP status " + xhr.status);
144+
}
145+
if (xhr.response.byteLength != length) {
146+
_this._error("Unexpected length " +
147+
xhr.response.byteLength +
148+
" (expected " + length + ")");
149+
}
150+
_this._bytes.set(new _this._Uint8Array(xhr.response), offset);
141151
}
142-
_this._bytes.set(new _this._Uint8Array(xhr.response), offset);
143152
if (callback) {
144-
callback.apply(_this);
153+
callback.apply(_this, [offset, length]);
145154
}
146155
}, false);
147156
xhr.addEventListener("error", this._mkerr("Fetch failed"), false);
148157
xhr.open("GET", this.op.source);
149158
xhr.responseType = "arraybuffer";
150-
xhr.setRequestHeader("Range", "bytes=" + offset + "-" + (end - 1));
151-
if (this._isSafari) {
152-
// Range request caching is broken in Safari
153-
// https://bugs.webkit.org/show_bug.cgi?id=82672
154-
xhr.setRequestHeader("Cache-control", "no-cache");
155-
xhr.setRequestHeader("If-None-Match", Math.random().toString());
159+
if (offset != null && length != null) {
160+
var end = offset + length;
161+
xhr.setRequestHeader("Range", "bytes=" + offset + "-" + (end - 1));
162+
if (this._isSafari) {
163+
// Range request caching is broken in Safari
164+
// https://bugs.webkit.org/show_bug.cgi?id=82672
165+
xhr.setRequestHeader("Cache-control", "no-cache");
166+
xhr.setRequestHeader("If-None-Match", Math.random().toString());
167+
}
156168
}
157169
/*this._debugLog("Load: " + offset + " " + length);*/
158170
xhr.send();
@@ -171,9 +183,19 @@ ZipImagePlayer.prototype = {
171183
if (_this._dead) {
172184
return;
173185
}
186+
_this._pHead = 0;
187+
_this._pNextHead = 0;
188+
_this._pFetch = 0;
174189
var len = parseInt(xhr.getResponseHeader("Content-Length"));
175190
if (!len) {
176-
_this._error("Invalid file length");
191+
_this._debugLog("HEAD request failed: invalid file length.");
192+
_this._debugLog("Falling back to full file mode.");
193+
_this._load(null, null, function(off, len) {
194+
_this._pTail = 0;
195+
_this._pHead = len;
196+
_this._findCentralDirectory();
197+
});
198+
return;
177199
}
178200
_this._debugLog("Len: " + len);
179201
_this._len = len;
@@ -183,11 +205,8 @@ ZipImagePlayer.prototype = {
183205
if (off < 0) {
184206
off = 0;
185207
}
186-
_this._pHead = 0;
187-
_this._pNextHead = 0;
188208
_this._pTail = len;
189-
_this._pFetch = 0;
190-
_this._load(off, len - off, function() {
209+
_this._load(off, len - off, function(off, len) {
191210
_this._pTail = off;
192211
_this._findCentralDirectory();
193212
});
@@ -244,9 +263,10 @@ ZipImagePlayer.prototype = {
244263
this._pHead = this._len;
245264
$(this).triggerHandler("loadProgress", [this._pHead / this._len]);
246265
this._loadNextFrame();
266+
} else {
267+
this._loadNextChunk();
268+
this._loadNextChunk();
247269
}
248-
this._loadNextChunk();
249-
this._loadNextChunk();
250270
},
251271
_loadNextChunk: function() {
252272
if (this._pFetch >= this._pTail) {

0 commit comments

Comments
 (0)