From 1d48e9c2017730f9fbab6267655f109b58be3f2d Mon Sep 17 00:00:00 2001 From: Mack Duan <duan.mack@gmail.com> Date: Thu, 25 Apr 2013 10:57:40 -0700 Subject: [PATCH] Handle server returning 200 for range request --- src/chunked_stream.js | 3 ++- src/network.js | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) 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 44e3847dd..b3981febd 100644 --- a/src/network.js +++ b/src/network.js @@ -40,6 +40,10 @@ function log(aMsg) { //#endif var NetworkManager = (function NetworkManagerClosure() { + + var OK_RESPONSE = 200; + var PARTIAL_CONTENT_RESPONSE = 206; + function NetworkManager(url, args) { this.url = url; args = args || {}; @@ -160,7 +164,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); } @@ -170,18 +182,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 }); }