2
0

fetch_stream.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. this._filename = null;
  85. var source = stream.source;
  86. this._withCredentials = source.withCredentials;
  87. this._contentLength = source.length;
  88. this._headersCapability = (0, _util.createPromiseCapability)();
  89. this._disableRange = source.disableRange || false;
  90. this._rangeChunkSize = source.rangeChunkSize;
  91. if (!this._rangeChunkSize && !this._disableRange) {
  92. this._disableRange = true;
  93. }
  94. this._isStreamingSupported = !source.disableStream;
  95. this._isRangeSupported = !source.disableRange;
  96. this._headers = new Headers();
  97. for (var property in this._stream.httpHeaders) {
  98. var value = this._stream.httpHeaders[property];
  99. if (typeof value === 'undefined') {
  100. continue;
  101. }
  102. this._headers.append(property, value);
  103. }
  104. var url = source.url;
  105. fetch(url, createFetchOptions(this._headers, this._withCredentials)).then(function (response) {
  106. if (!(0, _network_utils.validateResponseStatus)(response.status)) {
  107. throw (0, _network_utils.createResponseStatusError)(response.status, url);
  108. }
  109. _this._reader = response.body.getReader();
  110. _this._headersCapability.resolve();
  111. var getResponseHeader = function getResponseHeader(name) {
  112. return response.headers.get(name);
  113. };
  114. var _validateRangeRequest = (0, _network_utils.validateRangeRequestCapabilities)({
  115. getResponseHeader: getResponseHeader,
  116. isHttp: _this._stream.isHttp,
  117. rangeChunkSize: _this._rangeChunkSize,
  118. disableRange: _this._disableRange
  119. }),
  120. allowRangeRequests = _validateRangeRequest.allowRangeRequests,
  121. suggestedLength = _validateRangeRequest.suggestedLength;
  122. _this._isRangeSupported = allowRangeRequests;
  123. _this._contentLength = suggestedLength || _this._contentLength;
  124. _this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);
  125. if (!_this._isStreamingSupported && _this._isRangeSupported) {
  126. _this.cancel(new _util.AbortException('streaming is disabled'));
  127. }
  128. }).catch(this._headersCapability.reject);
  129. this.onProgress = null;
  130. }
  131. _createClass(PDFFetchStreamReader, [{
  132. key: 'read',
  133. value: function read() {
  134. var _this2 = this;
  135. return this._headersCapability.promise.then(function () {
  136. return _this2._reader.read().then(function (_ref) {
  137. var value = _ref.value,
  138. done = _ref.done;
  139. if (done) {
  140. return Promise.resolve({
  141. value: value,
  142. done: done
  143. });
  144. }
  145. _this2._loaded += value.byteLength;
  146. if (_this2.onProgress) {
  147. _this2.onProgress({
  148. loaded: _this2._loaded,
  149. total: _this2._contentLength
  150. });
  151. }
  152. var buffer = new Uint8Array(value).buffer;
  153. return Promise.resolve({
  154. value: buffer,
  155. done: false
  156. });
  157. });
  158. });
  159. }
  160. }, {
  161. key: 'cancel',
  162. value: function cancel(reason) {
  163. if (this._reader) {
  164. this._reader.cancel(reason);
  165. }
  166. }
  167. }, {
  168. key: 'headersReady',
  169. get: function get() {
  170. return this._headersCapability.promise;
  171. }
  172. }, {
  173. key: 'filename',
  174. get: function get() {
  175. return this._filename;
  176. }
  177. }, {
  178. key: 'contentLength',
  179. get: function get() {
  180. return this._contentLength;
  181. }
  182. }, {
  183. key: 'isRangeSupported',
  184. get: function get() {
  185. return this._isRangeSupported;
  186. }
  187. }, {
  188. key: 'isStreamingSupported',
  189. get: function get() {
  190. return this._isStreamingSupported;
  191. }
  192. }]);
  193. return PDFFetchStreamReader;
  194. }();
  195. var PDFFetchStreamRangeReader = function () {
  196. function PDFFetchStreamRangeReader(stream, begin, end) {
  197. var _this3 = this;
  198. _classCallCheck(this, PDFFetchStreamRangeReader);
  199. this._stream = stream;
  200. this._reader = null;
  201. this._loaded = 0;
  202. var source = stream.source;
  203. this._withCredentials = source.withCredentials;
  204. this._readCapability = (0, _util.createPromiseCapability)();
  205. this._isStreamingSupported = !source.disableStream;
  206. this._headers = new Headers();
  207. for (var property in this._stream.httpHeaders) {
  208. var value = this._stream.httpHeaders[property];
  209. if (typeof value === 'undefined') {
  210. continue;
  211. }
  212. this._headers.append(property, value);
  213. }
  214. var rangeStr = begin + '-' + (end - 1);
  215. this._headers.append('Range', 'bytes=' + rangeStr);
  216. var url = source.url;
  217. fetch(url, createFetchOptions(this._headers, this._withCredentials)).then(function (response) {
  218. if (!(0, _network_utils.validateResponseStatus)(response.status)) {
  219. throw (0, _network_utils.createResponseStatusError)(response.status, url);
  220. }
  221. _this3._readCapability.resolve();
  222. _this3._reader = response.body.getReader();
  223. });
  224. this.onProgress = null;
  225. }
  226. _createClass(PDFFetchStreamRangeReader, [{
  227. key: 'read',
  228. value: function read() {
  229. var _this4 = this;
  230. return this._readCapability.promise.then(function () {
  231. return _this4._reader.read().then(function (_ref2) {
  232. var value = _ref2.value,
  233. done = _ref2.done;
  234. if (done) {
  235. return Promise.resolve({
  236. value: value,
  237. done: done
  238. });
  239. }
  240. _this4._loaded += value.byteLength;
  241. if (_this4.onProgress) {
  242. _this4.onProgress({ loaded: _this4._loaded });
  243. }
  244. var buffer = new Uint8Array(value).buffer;
  245. return Promise.resolve({
  246. value: buffer,
  247. done: false
  248. });
  249. });
  250. });
  251. }
  252. }, {
  253. key: 'cancel',
  254. value: function cancel(reason) {
  255. if (this._reader) {
  256. this._reader.cancel(reason);
  257. }
  258. }
  259. }, {
  260. key: 'isStreamingSupported',
  261. get: function get() {
  262. return this._isStreamingSupported;
  263. }
  264. }]);
  265. return PDFFetchStreamRangeReader;
  266. }();
  267. exports.PDFFetchStream = PDFFetchStream;