Merge pull request #13945 from Snuffleupagus/network-onError

Implement `PDFNetworkStreamRangeRequestReader._onError`, to handle range request errors with XMLHttpRequest (issue 9883)
This commit is contained in:
Tim van der Meij 2021-09-01 21:18:07 +02:00 committed by GitHub
commit 2ed133bd99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -43,11 +43,10 @@ function getArrayBuffer(xhr) {
}
class NetworkManager {
constructor(url, args) {
constructor(url, args = {}) {
this.url = url;
args = args || {};
this.isHttp = /^https?:/i.test(url);
this.httpHeaders = (this.isHttp && args.httpHeaders) || {};
this.httpHeaders = (this.isHttp && args.httpHeaders) || Object.create(null);
this.withCredentials = args.withCredentials || false;
this.getXhr =
args.getXhr ||
@ -77,9 +76,7 @@ class NetworkManager {
request(args) {
const xhr = this.getXhr();
const xhrId = this.currXhrId++;
const pendingRequest = (this.pendingRequests[xhrId] = {
xhr,
});
const pendingRequest = (this.pendingRequests[xhrId] = { xhr });
xhr.open("GET", this.url);
xhr.withCredentials = this.withCredentials;
@ -119,20 +116,15 @@ class NetworkManager {
onProgress(xhrId, evt) {
const pendingRequest = this.pendingRequests[xhrId];
if (!pendingRequest) {
// Maybe abortRequest was called...
return;
}
if (pendingRequest.onProgress) {
pendingRequest.onProgress(evt);
return; // Maybe abortRequest was called...
}
pendingRequest.onProgress?.(evt);
}
onStateChange(xhrId, evt) {
const pendingRequest = this.pendingRequests[xhrId];
if (!pendingRequest) {
// Maybe abortRequest was called...
return;
return; // Maybe abortRequest was called...
}
const xhr = pendingRequest.xhr;
@ -155,9 +147,7 @@ class NetworkManager {
// Success status == 0 can be on ftp, file and other protocols.
if (xhr.status === 0 && this.isHttp) {
if (pendingRequest.onError) {
pendingRequest.onError(xhr.status);
}
pendingRequest.onError?.(xhr.status);
return;
}
const xhrStatus = xhr.status || OK_RESPONSE;
@ -173,9 +163,7 @@ class NetworkManager {
!ok_response_on_range_request &&
xhrStatus !== pendingRequest.expectedStatus
) {
if (pendingRequest.onError) {
pendingRequest.onError(xhr.status);
}
pendingRequest.onError?.(xhr.status);
return;
}
@ -192,8 +180,8 @@ class NetworkManager {
begin: 0,
chunk,
});
} else if (pendingRequest.onError) {
pendingRequest.onError(xhr.status);
} else {
pendingRequest.onError?.(xhr.status);
}
}
@ -256,9 +244,8 @@ class PDFNetworkStream {
}
cancelAllRequests(reason) {
if (this._fullRequestReader) {
this._fullRequestReader.cancel(reason);
}
this._fullRequestReader?.cancel(reason);
for (const reader of this._rangeRequestReaders.slice(0)) {
reader.cancel(reason);
}
@ -332,13 +319,13 @@ class PDFNetworkStreamFullRequestReader {
this._headersReceivedCapability.resolve();
}
_onDone(args) {
if (args) {
_onDone(data) {
if (data) {
if (this._requests.length > 0) {
const requestCapability = this._requests.shift();
requestCapability.resolve({ value: args.chunk, done: false });
requestCapability.resolve({ value: data.chunk, done: false });
} else {
this._cachedChunks.push(args.chunk);
this._cachedChunks.push(data.chunk);
}
}
this._done = true;
@ -352,24 +339,20 @@ class PDFNetworkStreamFullRequestReader {
}
_onError(status) {
const url = this._url;
const exception = createResponseStatusError(status, url);
this._storedError = exception;
this._headersReceivedCapability.reject(exception);
this._storedError = createResponseStatusError(status, this._url);
this._headersReceivedCapability.reject(this._storedError);
for (const requestCapability of this._requests) {
requestCapability.reject(exception);
requestCapability.reject(this._storedError);
}
this._requests.length = 0;
this._cachedChunks.length = 0;
}
_onProgress(data) {
if (this.onProgress) {
this.onProgress({
loaded: data.loaded,
total: data.lengthComputable ? data.total : this._contentLength,
});
}
_onProgress(evt) {
this.onProgress?.({
loaded: evt.loaded,
total: evt.lengthComputable ? evt.total : this._contentLength,
});
}
get filename() {
@ -426,23 +409,25 @@ class PDFNetworkStreamFullRequestReader {
class PDFNetworkStreamRangeRequestReader {
constructor(manager, begin, end) {
this._manager = manager;
const args = {
onDone: this._onDone.bind(this),
onError: this._onError.bind(this),
onProgress: this._onProgress.bind(this),
};
this._url = manager.url;
this._requestId = manager.requestRange(begin, end, args);
this._requests = [];
this._queuedChunk = null;
this._done = false;
this._storedError = undefined;
this.onProgress = null;
this.onClosed = null;
}
_close() {
if (this.onClosed) {
this.onClosed(this);
}
this.onClosed?.(this);
}
_onDone(data) {
@ -461,11 +446,18 @@ class PDFNetworkStreamRangeRequestReader {
this._close();
}
_onError(status) {
this._storedError = createResponseStatusError(status, this._url);
for (const requestCapability of this._requests) {
requestCapability.reject(this._storedError);
}
this._requests.length = 0;
this._queuedChunk = null;
}
_onProgress(evt) {
if (!this.isStreamingSupported && this.onProgress) {
this.onProgress({
loaded: evt.loaded,
});
if (!this.isStreamingSupported) {
this.onProgress?.({ loaded: evt.loaded });
}
}
@ -474,6 +466,9 @@ class PDFNetworkStreamRangeRequestReader {
}
async read() {
if (this._storedError) {
throw this._storedError;
}
if (this._queuedChunk !== null) {
const chunk = this._queuedChunk;
this._queuedChunk = null;