fetch_stream.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2017 Mozilla Foundation
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @licend The above is the entire license notice for the
  20. * Javascript code in this page
  21. */
  22. 'use strict';
  23. Object.defineProperty(exports, "__esModule", {
  24. value: true
  25. });
  26. exports.PDFFetchStream = undefined;
  27. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  28. var _util = require('../shared/util');
  29. var _network_utils = require('./network_utils');
  30. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  31. function createFetchOptions(headers, withCredentials) {
  32. return {
  33. method: 'GET',
  34. headers: headers,
  35. mode: 'cors',
  36. credentials: withCredentials ? 'include' : 'same-origin',
  37. redirect: 'follow'
  38. };
  39. }
  40. var PDFFetchStream = function () {
  41. function PDFFetchStream(source) {
  42. _classCallCheck(this, PDFFetchStream);
  43. this.source = source;
  44. this.isHttp = /^https?:/i.test(source.url);
  45. this.httpHeaders = this.isHttp && source.httpHeaders || {};
  46. this._fullRequestReader = null;
  47. this._rangeRequestReaders = [];
  48. }
  49. _createClass(PDFFetchStream, [{
  50. key: 'getFullReader',
  51. value: function getFullReader() {
  52. (0, _util.assert)(!this._fullRequestReader);
  53. this._fullRequestReader = new PDFFetchStreamReader(this);
  54. return this._fullRequestReader;
  55. }
  56. }, {
  57. key: 'getRangeReader',
  58. value: function getRangeReader(begin, end) {
  59. var reader = new PDFFetchStreamRangeReader(this, begin, end);
  60. this._rangeRequestReaders.push(reader);
  61. return reader;
  62. }
  63. }, {
  64. key: 'cancelAllRequests',
  65. value: function cancelAllRequests(reason) {
  66. if (this._fullRequestReader) {
  67. this._fullRequestReader.cancel(reason);
  68. }
  69. var readers = this._rangeRequestReaders.slice(0);
  70. readers.forEach(function (reader) {
  71. reader.cancel(reason);
  72. });
  73. }
  74. }]);
  75. return PDFFetchStream;
  76. }();
  77. var PDFFetchStreamReader = function () {
  78. function PDFFetchStreamReader(stream) {
  79. var _this = this;
  80. _classCallCheck(this, PDFFetchStreamReader);
  81. this._stream = stream;
  82. this._reader = null;
  83. this._loaded = 0;
  84. var source = stream.source;
  85. this._withCredentials = source.withCredentials;
  86. this._contentLength = source.length;
  87. this._headersCapability = (0, _util.createPromiseCapability)();
  88. this._disableRange = source.disableRange;
  89. this._rangeChunkSize = source.rangeChunkSize;
  90. if (!this._rangeChunkSize && !this._disableRange) {
  91. this._disableRange = true;
  92. }
  93. this._isRangeSupported = !source.disableRange;
  94. this._isStreamingSupported = !source.disableStream;
  95. this._headers = new Headers();
  96. for (var property in this._stream.httpHeaders) {
  97. var value = this._stream.httpHeaders[property];
  98. if (typeof value === 'undefined') {
  99. continue;
  100. }
  101. this._headers.append(property, value);
  102. }
  103. var url = source.url;
  104. fetch(url, createFetchOptions(this._headers, this._withCredentials)).then(function (response) {
  105. if (!(0, _network_utils.validateResponseStatus)(response.status)) {
  106. throw (0, _network_utils.createResponseStatusError)(response.status, url);
  107. }
  108. _this._reader = response.body.getReader();
  109. _this._headersCapability.resolve();
  110. var _validateRangeRequest = (0, _network_utils.validateRangeRequestCapabilities)({
  111. getResponseHeader: function getResponseHeader(name) {
  112. return response.headers.get(name);
  113. },
  114. isHttp: _this._stream.isHttp,
  115. rangeChunkSize: _this._rangeChunkSize,
  116. disableRange: _this._disableRange
  117. }),
  118. allowRangeRequests = _validateRangeRequest.allowRangeRequests,
  119. suggestedLength = _validateRangeRequest.suggestedLength;
  120. _this._contentLength = suggestedLength;
  121. _this._isRangeSupported = allowRangeRequests;
  122. if (!_this._isStreamingSupported && _this._isRangeSupported) {
  123. _this.cancel(new _util.AbortException('streaming is disabled'));
  124. }
  125. }).catch(this._headersCapability.reject);
  126. this.onProgress = null;
  127. }
  128. _createClass(PDFFetchStreamReader, [{
  129. key: 'read',
  130. value: function read() {
  131. var _this2 = this;
  132. return this._headersCapability.promise.then(function () {
  133. return _this2._reader.read().then(function (_ref) {
  134. var value = _ref.value,
  135. done = _ref.done;
  136. if (done) {
  137. return Promise.resolve({
  138. value: value,
  139. done: done
  140. });
  141. }
  142. _this2._loaded += value.byteLength;
  143. if (_this2.onProgress) {
  144. _this2.onProgress({
  145. loaded: _this2._loaded,
  146. total: _this2._contentLength
  147. });
  148. }
  149. var buffer = new Uint8Array(value).buffer;
  150. return Promise.resolve({
  151. value: buffer,
  152. done: false
  153. });
  154. });
  155. });
  156. }
  157. }, {
  158. key: 'cancel',
  159. value: function cancel(reason) {
  160. if (this._reader) {
  161. this._reader.cancel(reason);
  162. }
  163. }
  164. }, {
  165. key: 'headersReady',
  166. get: function get() {
  167. return this._headersCapability.promise;
  168. }
  169. }, {
  170. key: 'contentLength',
  171. get: function get() {
  172. return this._contentLength;
  173. }
  174. }, {
  175. key: 'isRangeSupported',
  176. get: function get() {
  177. return this._isRangeSupported;
  178. }
  179. }, {
  180. key: 'isStreamingSupported',
  181. get: function get() {
  182. return this._isStreamingSupported;
  183. }
  184. }]);
  185. return PDFFetchStreamReader;
  186. }();
  187. var PDFFetchStreamRangeReader = function () {
  188. function PDFFetchStreamRangeReader(stream, begin, end) {
  189. var _this3 = this;
  190. _classCallCheck(this, PDFFetchStreamRangeReader);
  191. this._stream = stream;
  192. this._reader = null;
  193. this._loaded = 0;
  194. var source = stream.source;
  195. this._withCredentials = source.withCredentials;
  196. this._readCapability = (0, _util.createPromiseCapability)();
  197. this._isStreamingSupported = !source.disableStream;
  198. this._headers = new Headers();
  199. for (var property in this._stream.httpHeaders) {
  200. var value = this._stream.httpHeaders[property];
  201. if (typeof value === 'undefined') {
  202. continue;
  203. }
  204. this._headers.append(property, value);
  205. }
  206. var rangeStr = begin + '-' + (end - 1);
  207. this._headers.append('Range', 'bytes=' + rangeStr);
  208. var url = source.url;
  209. fetch(url, createFetchOptions(this._headers, this._withCredentials)).then(function (response) {
  210. if (!(0, _network_utils.validateResponseStatus)(response.status)) {
  211. throw (0, _network_utils.createResponseStatusError)(response.status, url);
  212. }
  213. _this3._readCapability.resolve();
  214. _this3._reader = response.body.getReader();
  215. });
  216. this.onProgress = null;
  217. }
  218. _createClass(PDFFetchStreamRangeReader, [{
  219. key: 'read',
  220. value: function read() {
  221. var _this4 = this;
  222. return this._readCapability.promise.then(function () {
  223. return _this4._reader.read().then(function (_ref2) {
  224. var value = _ref2.value,
  225. done = _ref2.done;
  226. if (done) {
  227. return Promise.resolve({
  228. value: value,
  229. done: done
  230. });
  231. }
  232. _this4._loaded += value.byteLength;
  233. if (_this4.onProgress) {
  234. _this4.onProgress({ loaded: _this4._loaded });
  235. }
  236. var buffer = new Uint8Array(value).buffer;
  237. return Promise.resolve({
  238. value: buffer,
  239. done: false
  240. });
  241. });
  242. });
  243. }
  244. }, {
  245. key: 'cancel',
  246. value: function cancel(reason) {
  247. if (this._reader) {
  248. this._reader.cancel(reason);
  249. }
  250. }
  251. }, {
  252. key: 'isStreamingSupported',
  253. get: function get() {
  254. return this._isStreamingSupported;
  255. }
  256. }]);
  257. return PDFFetchStreamRangeReader;
  258. }();
  259. exports.PDFFetchStream = PDFFetchStream;