diff --git a/src/chunked_stream.js b/src/chunked_stream.js index fe8388aa1..bef636147 100644 --- a/src/chunked_stream.js +++ b/src/chunked_stream.js @@ -363,7 +363,8 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() { var loadedRequests = []; for (var chunk = beginChunk; chunk < endChunk; ++chunk) { - var requestIds = this.requestsByChunk[chunk]; + // The server might return more chunks than requested + var requestIds = this.requestsByChunk[chunk] || []; delete this.requestsByChunk[chunk]; for (var i = 0; i < requestIds.length; ++i) { diff --git a/src/network.js b/src/network.js index 161833477..248cc8a0d 100644 --- a/src/network.js +++ b/src/network.js @@ -36,6 +36,10 @@ //#endif var NetworkManager = (function NetworkManagerClosure() { + + var OK_RESPONSE = 200; + var PARTIAL_CONTENT_RESPONSE = 206; + function NetworkManager(url, args) { this.url = url; args = args || {}; @@ -156,7 +160,15 @@ var NetworkManager = (function NetworkManagerClosure() { return; } - if (xhr.status !== pendingRequest.expectedStatus) { + // From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2: + // "A server MAY ignore the Range header". This means it's possible to + // get a 200 rather than a 206 response from a range request. + var ok_response_on_range_request = + xhr.status === OK_RESPONSE && + pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE; + + if (!ok_response_on_range_request && + xhr.status !== pendingRequest.expectedStatus) { if (pendingRequest.onError) { pendingRequest.onError(xhr.status); } @@ -166,18 +178,17 @@ var NetworkManager = (function NetworkManagerClosure() { this.loadedRequests[xhrId] = true; var chunk = getArrayBuffer(xhr); - if (pendingRequest.expectedStatus === 206) { + if (xhr.status === PARTIAL_CONTENT_RESPONSE) { var rangeHeader = xhr.getResponseHeader('Content-Range'); var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader); var begin = parseInt(matches[1], 10); - var end = parseInt(matches[2], 10) + 1; pendingRequest.onDone({ begin: begin, - end: end, chunk: chunk }); } else { pendingRequest.onDone({ + begin: 0, chunk: chunk }); }