network_utils.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /* Copyright 2012 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. import {
  16. assert,
  17. MissingPDFException,
  18. UnexpectedResponseException,
  19. } from "../shared/util.js";
  20. import { getFilenameFromContentDispositionHeader } from "./content_disposition.js";
  21. import { isPdfFile } from "./display_utils.js";
  22. function validateRangeRequestCapabilities({
  23. getResponseHeader,
  24. isHttp,
  25. rangeChunkSize,
  26. disableRange,
  27. }) {
  28. if (
  29. typeof PDFJSDev === "undefined" ||
  30. PDFJSDev.test("!PRODUCTION || TESTING")
  31. ) {
  32. assert(
  33. Number.isInteger(rangeChunkSize) && rangeChunkSize > 0,
  34. "rangeChunkSize must be an integer larger than zero."
  35. );
  36. }
  37. const returnValues = {
  38. allowRangeRequests: false,
  39. suggestedLength: undefined,
  40. };
  41. const length = parseInt(getResponseHeader("Content-Length"), 10);
  42. if (!Number.isInteger(length)) {
  43. return returnValues;
  44. }
  45. returnValues.suggestedLength = length;
  46. if (length <= 2 * rangeChunkSize) {
  47. // The file size is smaller than the size of two chunks, so it does not
  48. // make any sense to abort the request and retry with a range request.
  49. return returnValues;
  50. }
  51. if (disableRange || !isHttp) {
  52. return returnValues;
  53. }
  54. if (getResponseHeader("Accept-Ranges") !== "bytes") {
  55. return returnValues;
  56. }
  57. const contentEncoding = getResponseHeader("Content-Encoding") || "identity";
  58. if (contentEncoding !== "identity") {
  59. return returnValues;
  60. }
  61. returnValues.allowRangeRequests = true;
  62. return returnValues;
  63. }
  64. function extractFilenameFromHeader(getResponseHeader) {
  65. const contentDisposition = getResponseHeader("Content-Disposition");
  66. if (contentDisposition) {
  67. let filename = getFilenameFromContentDispositionHeader(contentDisposition);
  68. if (filename.includes("%")) {
  69. try {
  70. filename = decodeURIComponent(filename);
  71. } catch (ex) {}
  72. }
  73. if (isPdfFile(filename)) {
  74. return filename;
  75. }
  76. }
  77. return null;
  78. }
  79. function createResponseStatusError(status, url) {
  80. if (status === 404 || (status === 0 && url.startsWith("file:"))) {
  81. return new MissingPDFException('Missing PDF "' + url + '".');
  82. }
  83. return new UnexpectedResponseException(
  84. `Unexpected server response (${status}) while retrieving PDF "${url}".`,
  85. status
  86. );
  87. }
  88. function validateResponseStatus(status) {
  89. return status === 200 || status === 206;
  90. }
  91. export {
  92. createResponseStatusError,
  93. extractFilenameFromHeader,
  94. validateRangeRequestCapabilities,
  95. validateResponseStatus,
  96. };