diff --git a/src/api.js b/src/api.js index 5d92ee784..e1ec31470 100644 --- a/src/api.js +++ b/src/api.js @@ -528,11 +528,14 @@ var WorkerTransport = (function WorkerTransportClosure() { } WorkerTransport.prototype = { destroy: function WorkerTransport_destroy() { - if (this.worker) - this.worker.terminate(); - this.pageCache = []; this.pagePromises = []; + var self = this; + this.messageHandler.send('Terminate', null, function () { + if (self.worker) { + self.worker.terminate(); + } + }); }, setupFakeWorker: function WorkerTransport_setupFakeWorker() { warn('Setting up fake worker.'); @@ -733,6 +736,7 @@ var WorkerTransport = (function WorkerTransportClosure() { }, fetchDocument: function WorkerTransport_fetchDocument(source) { + source.disableAutoFetch = PDFJS.disableAutoFetch; source.chunkedViewerLoading = !!this.pdfDataRangeTransport; this.messageHandler.send('GetDocRequest', { source: source, diff --git a/src/chunked_stream.js b/src/chunked_stream.js index 369ca672c..7884c60ee 100644 --- a/src/chunked_stream.js +++ b/src/chunked_stream.js @@ -198,6 +198,7 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() { this.length = length; this.chunkSize = chunkSize; this.url = url; + this.disableAutoFetch = args.disableAutoFetch; var msgHandler = this.msgHandler = args.msgHandler; if (args.chunkedViewerLoading) { @@ -382,7 +383,7 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() { // If there are no pending requests, automatically fetch the next // unfetched chunk of the PDF - if (isEmptyObj(this.requestsByChunk)) { + if (!this.disableAutoFetch && isEmptyObj(this.requestsByChunk)) { var nextEmptyChunk; if (this.stream.numChunksLoaded === 1) { // This is a special optimization so that after fetching the first diff --git a/src/pdf_manager.js b/src/pdf_manager.js index aecbd9957..2a93fe7d9 100644 --- a/src/pdf_manager.js +++ b/src/pdf_manager.js @@ -118,7 +118,8 @@ var NetworkPdfManager = (function NetworkPdfManagerClosure() { var params = { msgHandler: msgHandler, httpHeaders: args.httpHeaders, - chunkedViewerLoading: args.chunkedViewerLoading + chunkedViewerLoading: args.chunkedViewerLoading, + disableAutoFetch: args.disableAutoFetch }; this.streamManager = new ChunkedStreamManager(args.length, CHUNK_SIZE, args.url, params); diff --git a/src/worker.js b/src/worker.js index 7ccd193d2..3fa9d3e7e 100644 --- a/src/worker.js +++ b/src/worker.js @@ -292,6 +292,7 @@ var WorkerMessageHandler = { return; } + pdfManager.requestLoadedStream(); pdfManager.onLoadedStream().then(function() { loadDocument(true).then(onSuccess, onFailure); }); @@ -430,6 +431,11 @@ var WorkerMessageHandler = { }); }); }); + + handler.on('Terminate', function wphTerminate(data, promise) { + pdfManager.streamManager.networkManager.abortAllRequests(); + promise.resolve(); + }); } }; diff --git a/test/driver.js b/test/driver.js index 3a4fcef52..4483f86be 100644 --- a/test/driver.js +++ b/test/driver.js @@ -133,7 +133,8 @@ function nextTask() { } // When generating reference images in masterMode, disable range requests - PDFJS.disableRange = !task.rangeRequest || masterMode; + PDFJS.disableRange = task.disableRange || masterMode; + PDFJS.disableAutoFetch = !task.enableAutoFetch || masterMode; try { var promise = PDFJS.getDocument(absoluteUrl); promise.then(function(doc) { diff --git a/test/test.py b/test/test.py index 5e7da43c7..b5bcf75cf 100644 --- a/test/test.py +++ b/test/test.py @@ -152,10 +152,28 @@ class TestHandlerBase(BaseHTTPRequestHandler): try: BaseHTTPRequestHandler.handle_one_request(self) except socket.error, v: - # Ignoring connection reset by peer exceptions - if v[0] != errno.ECONNRESET: + if v[0] == errno.ECONNRESET: + # Ignoring connection reset by peer exceptions + print 'Detected connection reset' + elif v[0] == errno.EPIPE: + print 'Detected remote peer disconnected' + elif v[0] == 10053: + # FIXME(mack): Address this issue + print 'An established connection was aborted by the' \ + ' software in your host machine' + else: raise + def finish(self,*args,**kw): + # From http://stackoverflow.com/a/14355079/1834797 + try: + if not self.wfile.closed: + self.wfile.flush() + self.wfile.close() + except socket.error: + pass + self.rfile.close() + def sendFile(self, path, ext): self.send_response(200) self.send_header("Accept-Ranges", "bytes") @@ -173,13 +191,13 @@ class TestHandlerBase(BaseHTTPRequestHandler): self.send_error(416) return chunk_len = end - start + time.sleep(chunk_len / 1000000.0) self.send_response(206) self.send_header("Accept-Ranges", "bytes") self.send_header("Content-Type", MIMEs[ext]) self.send_header("Content-Length", chunk_len) self.send_header("Content-Range", 'bytes ' + str(start) + '-' + str(end - 1) + '/' + str(file_len)) self.end_headers() - time.sleep(chunk_len / 500000.0) with open(path, "rb") as f: f.seek(start) self.wfile.write(f.read(chunk_len)) @@ -212,15 +230,17 @@ class TestHandlerBase(BaseHTTPRequestHandler): range_re = re.compile(r"^bytes=(\d+)\-(\d+)?") parsed_range = range_re.search(self.headers.getheader("Range")) if parsed_range is None: - self.send_error(501) - return - print 'Range requested ' + parsed_range.group(1) + '-' + parsed_range.group(2) + self.send_error(501) + return + if VERBOSE: + print 'Range requested %s - %s: %s' % ( + parsed_range.group(1), parsed_range.group(2)) start = int(parsed_range.group(1)) if parsed_range.group(2) is None: - self.sendFileRange(path, ext, start, None) + self.sendFileRange(path, ext, start, None) else: - end = int(parsed_range.group(2)) + 1 - self.sendFileRange(path, ext, start, end) + end = int(parsed_range.group(2)) + 1 + self.sendFileRange(path, ext, start, end) return self.sendFile(path, ext) diff --git a/test/test_manifest.json b/test/test_manifest.json index c6be31206..875c14d0b 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -3,7 +3,6 @@ "file": "pdfs/filled-background.pdf", "md5": "2e3120255d9c3e79b96d2543b12d2589", "rounds": 1, - "rangeRequest": true, "type": "eq" }, { "id": "tracemonkey-eq", @@ -311,6 +310,14 @@ "rounds": 1, "type": "eq" }, + { "id": "usmanm-bad-auto-fetch", + "file": "pdfs/usmanm-bad.pdf", + "md5": "38afb822433aaf07fc8f54807cd4f61a", + "link": true, + "rounds": 1, + "type": "eq", + "enableAutoFetch": true + }, { "id": "vesta-bad", "file": "pdfs/vesta.pdf", "md5": "0afebc109b7c17b95619ea3fab5eafe6", @@ -1059,13 +1066,6 @@ "type": "eq", "about": "Image with indexed colorspace that has a base lab colorspace." }, - { "id": "yo01", - "file": "pdfs/yo01.pdf", - "md5": "7d42435c20fe0d32de4ea3d7e4727ac1", - "rounds": 1, - "link": true, - "type": "eq" - }, { "id": "20130226130259", "file": "pdfs/20130226130259.pdf", "md5": "c33e90a1b369c508573023d2434b950f", diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 7c71fa664..2904aa439 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -11,7 +11,7 @@ describe('api', function() { function waitsForPromise(promise) { waitsFor(function() { return promise.isResolved || promise.isRejected; - }, 4000); + }, 10000); } function expectAfterPromise(promise, successCallback) { waitsForPromise(promise); diff --git a/web/viewer.js b/web/viewer.js index eef82b36d..034f299f3 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -3103,6 +3103,10 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) { PDFJS.disableRange = (hashParams['disableRange'] === 'true'); } + if ('disableAutoFetch' in hashParams) { + PDFJS.disableAutoFetch = (hashParams['disableAutoFetch'] === 'true'); + } + //#if !(FIREFOX || MOZCENTRAL) var locale = navigator.language; if ('locale' in hashParams)