Browse Source

avoid http 416 (Range Not Satisfiable Error): when request last chunk, request a range that is beyond the available content length

pull/832/head
Jacky Jiang 5 years ago
parent
commit
658898f0d1
  1. 34
      papaparse.js

34
papaparse.js

@ -608,6 +608,9 @@ License: MIT
ChunkStreamer.call(this, config); ChunkStreamer.call(this, config);
var xhr; var xhr;
// Will update `totalContentSize` with possible total size info from Content-Range response header
// Its value will be -1 to indicate the total size info can't be retrieve from Content-Range response header (or not available)
var totalContentSize = -1;
if (IS_WORKER) if (IS_WORKER)
{ {
@ -667,6 +670,11 @@ License: MIT
if (this._config.chunkSize) if (this._config.chunkSize)
{ {
var end = this._start + this._config.chunkSize - 1; // minus one because byte range is inclusive var end = this._start + this._config.chunkSize - 1; // minus one because byte range is inclusive
if(totalContentSize > 1 && end > totalContentSize - 1) {
// if valid totalContentSize (retrieved from content-range response header) is available
// and end is beyond totalContentSize, replace end with totalContentSize - 1 (as range is inclusive)
end = totalContentSize - 1;
}
xhr.setRequestHeader('Range', 'bytes=' + this._start + '-' + end); xhr.setRequestHeader('Range', 'bytes=' + this._start + '-' + end);
} }
@ -692,8 +700,17 @@ License: MIT
return; return;
} }
// Use chunckSize as it may be a diference on reponse lentgh due to characters with more than 1 byte var size = getFileSize(xhr);
this._start += this._config.chunkSize ? this._config.chunkSize : xhr.responseText.length;
if(size !== -1) {
// we only update totalContentSize when we can get valid content range header
totalContentSize = size;
}
var chunkSize = getChunkSize(xhr);
// Use chunckSize that is retrieved from content-length header if available
this._start += chunkSize !== -1 ? chunkSize : this._config.chunkSize;
this._finished = !this._config.chunkSize || this._start >= getFileSize(xhr); this._finished = !this._config.chunkSize || this._start >= getFileSize(xhr);
this.parseChunk(xhr.responseText); this.parseChunk(xhr.responseText);
}; };
@ -704,13 +721,24 @@ License: MIT
this._sendError(new Error(errorText)); this._sendError(new Error(errorText));
}; };
function getChunkSize(xhr)
{
var contentLength = xhr.getResponseHeader('Content-Length');
if (contentLength === null) { // no content length, return -1 to indicate this
return -1;
}
var length = parseInt(contentLength);
return length > 0 ? length : -1;
}
function getFileSize(xhr) function getFileSize(xhr)
{ {
var contentRange = xhr.getResponseHeader('Content-Range'); var contentRange = xhr.getResponseHeader('Content-Range');
if (contentRange === null) { // no content range, then finish! if (contentRange === null) { // no content range, then finish!
return -1; return -1;
} }
return parseInt(contentRange.substring(contentRange.lastIndexOf('/') + 1)); var size = parseInt(contentRange.substring(contentRange.lastIndexOf('/') + 1));
return size > 0 ? size : -1; // this also exclude the situation that size is NaN
} }
} }
NetworkStreamer.prototype = Object.create(ChunkStreamer.prototype); NetworkStreamer.prototype = Object.create(ChunkStreamer.prototype);

Loading…
Cancel
Save