2
0

network_utils_spec.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * JavaScript code in this page
  4. *
  5. * Copyright 2022 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. var _network_utils = require("../../display/network_utils.js");
  24. var _util = require("../../shared/util.js");
  25. describe("network_utils", function () {
  26. describe("validateRangeRequestCapabilities", function () {
  27. it("rejects invalid rangeChunkSize", function () {
  28. expect(function () {
  29. (0, _network_utils.validateRangeRequestCapabilities)({
  30. rangeChunkSize: "abc"
  31. });
  32. }).toThrow(new Error("rangeChunkSize must be an integer larger than zero."));
  33. expect(function () {
  34. (0, _network_utils.validateRangeRequestCapabilities)({
  35. rangeChunkSize: 0
  36. });
  37. }).toThrow(new Error("rangeChunkSize must be an integer larger than zero."));
  38. });
  39. it("rejects disabled or non-HTTP range requests", function () {
  40. expect((0, _network_utils.validateRangeRequestCapabilities)({
  41. disableRange: true,
  42. isHttp: true,
  43. getResponseHeader: headerName => {
  44. if (headerName === "Content-Length") {
  45. return 8;
  46. }
  47. throw new Error(`Unexpected headerName: ${headerName}`);
  48. },
  49. rangeChunkSize: 64
  50. })).toEqual({
  51. allowRangeRequests: false,
  52. suggestedLength: 8
  53. });
  54. expect((0, _network_utils.validateRangeRequestCapabilities)({
  55. disableRange: false,
  56. isHttp: false,
  57. getResponseHeader: headerName => {
  58. if (headerName === "Content-Length") {
  59. return 8;
  60. }
  61. throw new Error(`Unexpected headerName: ${headerName}`);
  62. },
  63. rangeChunkSize: 64
  64. })).toEqual({
  65. allowRangeRequests: false,
  66. suggestedLength: 8
  67. });
  68. });
  69. it("rejects invalid Accept-Ranges header values", function () {
  70. expect((0, _network_utils.validateRangeRequestCapabilities)({
  71. disableRange: false,
  72. isHttp: true,
  73. getResponseHeader: headerName => {
  74. if (headerName === "Accept-Ranges") {
  75. return "none";
  76. } else if (headerName === "Content-Length") {
  77. return 8;
  78. }
  79. throw new Error(`Unexpected headerName: ${headerName}`);
  80. },
  81. rangeChunkSize: 64
  82. })).toEqual({
  83. allowRangeRequests: false,
  84. suggestedLength: 8
  85. });
  86. });
  87. it("rejects invalid Content-Encoding header values", function () {
  88. expect((0, _network_utils.validateRangeRequestCapabilities)({
  89. disableRange: false,
  90. isHttp: true,
  91. getResponseHeader: headerName => {
  92. if (headerName === "Accept-Ranges") {
  93. return "bytes";
  94. } else if (headerName === "Content-Encoding") {
  95. return "gzip";
  96. } else if (headerName === "Content-Length") {
  97. return 8;
  98. }
  99. throw new Error(`Unexpected headerName: ${headerName}`);
  100. },
  101. rangeChunkSize: 64
  102. })).toEqual({
  103. allowRangeRequests: false,
  104. suggestedLength: 8
  105. });
  106. });
  107. it("rejects invalid Content-Length header values", function () {
  108. expect((0, _network_utils.validateRangeRequestCapabilities)({
  109. disableRange: false,
  110. isHttp: true,
  111. getResponseHeader: headerName => {
  112. if (headerName === "Accept-Ranges") {
  113. return "bytes";
  114. } else if (headerName === "Content-Encoding") {
  115. return null;
  116. } else if (headerName === "Content-Length") {
  117. return "eight";
  118. }
  119. throw new Error(`Unexpected headerName: ${headerName}`);
  120. },
  121. rangeChunkSize: 64
  122. })).toEqual({
  123. allowRangeRequests: false,
  124. suggestedLength: undefined
  125. });
  126. });
  127. it("rejects file sizes that are too small for range requests", function () {
  128. expect((0, _network_utils.validateRangeRequestCapabilities)({
  129. disableRange: false,
  130. isHttp: true,
  131. getResponseHeader: headerName => {
  132. if (headerName === "Accept-Ranges") {
  133. return "bytes";
  134. } else if (headerName === "Content-Encoding") {
  135. return null;
  136. } else if (headerName === "Content-Length") {
  137. return 8;
  138. }
  139. throw new Error(`Unexpected headerName: ${headerName}`);
  140. },
  141. rangeChunkSize: 64
  142. })).toEqual({
  143. allowRangeRequests: false,
  144. suggestedLength: 8
  145. });
  146. });
  147. it("accepts file sizes large enough for range requests", function () {
  148. expect((0, _network_utils.validateRangeRequestCapabilities)({
  149. disableRange: false,
  150. isHttp: true,
  151. getResponseHeader: headerName => {
  152. if (headerName === "Accept-Ranges") {
  153. return "bytes";
  154. } else if (headerName === "Content-Encoding") {
  155. return null;
  156. } else if (headerName === "Content-Length") {
  157. return 8192;
  158. }
  159. throw new Error(`Unexpected headerName: ${headerName}`);
  160. },
  161. rangeChunkSize: 64
  162. })).toEqual({
  163. allowRangeRequests: true,
  164. suggestedLength: 8192
  165. });
  166. });
  167. });
  168. describe("extractFilenameFromHeader", function () {
  169. it("returns null when content disposition header is blank", function () {
  170. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  171. if (headerName === "Content-Disposition") {
  172. return null;
  173. }
  174. throw new Error(`Unexpected headerName: ${headerName}`);
  175. })).toBeNull();
  176. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  177. if (headerName === "Content-Disposition") {
  178. return undefined;
  179. }
  180. throw new Error(`Unexpected headerName: ${headerName}`);
  181. })).toBeNull();
  182. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  183. if (headerName === "Content-Disposition") {
  184. return "";
  185. }
  186. throw new Error(`Unexpected headerName: ${headerName}`);
  187. })).toBeNull();
  188. });
  189. it("gets the filename from the response header", function () {
  190. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  191. if (headerName === "Content-Disposition") {
  192. return "inline";
  193. }
  194. throw new Error(`Unexpected headerName: ${headerName}`);
  195. })).toBeNull();
  196. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  197. if (headerName === "Content-Disposition") {
  198. return "attachment";
  199. }
  200. throw new Error(`Unexpected headerName: ${headerName}`);
  201. })).toBeNull();
  202. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  203. if (headerName === "Content-Disposition") {
  204. return 'attachment; filename="filename.pdf"';
  205. }
  206. throw new Error(`Unexpected headerName: ${headerName}`);
  207. })).toEqual("filename.pdf");
  208. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  209. if (headerName === "Content-Disposition") {
  210. return 'attachment; filename="filename.pdf and spaces.pdf"';
  211. }
  212. throw new Error(`Unexpected headerName: ${headerName}`);
  213. })).toEqual("filename.pdf and spaces.pdf");
  214. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  215. if (headerName === "Content-Disposition") {
  216. return 'attachment; filename="tl;dr.pdf"';
  217. }
  218. throw new Error(`Unexpected headerName: ${headerName}`);
  219. })).toEqual("tl;dr.pdf");
  220. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  221. if (headerName === "Content-Disposition") {
  222. return "attachment; filename=filename.pdf";
  223. }
  224. throw new Error(`Unexpected headerName: ${headerName}`);
  225. })).toEqual("filename.pdf");
  226. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  227. if (headerName === "Content-Disposition") {
  228. return "attachment; filename=filename.pdf someotherparam";
  229. }
  230. throw new Error(`Unexpected headerName: ${headerName}`);
  231. })).toEqual("filename.pdf");
  232. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  233. if (headerName === "Content-Disposition") {
  234. return 'attachment; filename="%e4%b8%ad%e6%96%87.pdf"';
  235. }
  236. throw new Error(`Unexpected headerName: ${headerName}`);
  237. })).toEqual("中文.pdf");
  238. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  239. if (headerName === "Content-Disposition") {
  240. return 'attachment; filename="100%.pdf"';
  241. }
  242. throw new Error(`Unexpected headerName: ${headerName}`);
  243. })).toEqual("100%.pdf");
  244. });
  245. it("gets the filename from the response header (RFC 6266)", function () {
  246. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  247. if (headerName === "Content-Disposition") {
  248. return "attachment; filename*=filename.pdf";
  249. }
  250. throw new Error(`Unexpected headerName: ${headerName}`);
  251. })).toEqual("filename.pdf");
  252. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  253. if (headerName === "Content-Disposition") {
  254. return "attachment; filename*=''filename.pdf";
  255. }
  256. throw new Error(`Unexpected headerName: ${headerName}`);
  257. })).toEqual("filename.pdf");
  258. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  259. if (headerName === "Content-Disposition") {
  260. return "attachment; filename*=utf-8''filename.pdf";
  261. }
  262. throw new Error(`Unexpected headerName: ${headerName}`);
  263. })).toEqual("filename.pdf");
  264. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  265. if (headerName === "Content-Disposition") {
  266. return "attachment; filename=no.pdf; filename*=utf-8''filename.pdf";
  267. }
  268. throw new Error(`Unexpected headerName: ${headerName}`);
  269. })).toEqual("filename.pdf");
  270. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  271. if (headerName === "Content-Disposition") {
  272. return "attachment; filename*=utf-8''filename.pdf; filename=no.pdf";
  273. }
  274. throw new Error(`Unexpected headerName: ${headerName}`);
  275. })).toEqual("filename.pdf");
  276. });
  277. it("gets the filename from the response header (RFC 2231)", function () {
  278. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  279. if (headerName === "Content-Disposition") {
  280. return "attachment; filename*0=filename; filename*1=.pdf";
  281. }
  282. throw new Error(`Unexpected headerName: ${headerName}`);
  283. })).toEqual("filename.pdf");
  284. });
  285. it("only extracts filename with pdf extension", function () {
  286. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  287. if (headerName === "Content-Disposition") {
  288. return 'attachment; filename="filename.png"';
  289. }
  290. throw new Error(`Unexpected headerName: ${headerName}`);
  291. })).toBeNull();
  292. });
  293. it("extension validation is case insensitive", function () {
  294. expect((0, _network_utils.extractFilenameFromHeader)(headerName => {
  295. if (headerName === "Content-Disposition") {
  296. return 'form-data; name="fieldName"; filename="file.PdF"';
  297. }
  298. throw new Error(`Unexpected headerName: ${headerName}`);
  299. })).toEqual("file.PdF");
  300. });
  301. });
  302. describe("createResponseStatusError", function () {
  303. it("handles missing PDF file responses", function () {
  304. expect((0, _network_utils.createResponseStatusError)(404, "https://foo.com/bar.pdf")).toEqual(new _util.MissingPDFException('Missing PDF "https://foo.com/bar.pdf".'));
  305. expect((0, _network_utils.createResponseStatusError)(0, "file://foo.pdf")).toEqual(new _util.MissingPDFException('Missing PDF "file://foo.pdf".'));
  306. });
  307. it("handles unexpected responses", function () {
  308. expect((0, _network_utils.createResponseStatusError)(302, "https://foo.com/bar.pdf")).toEqual(new _util.UnexpectedResponseException("Unexpected server response (302) while retrieving PDF " + '"https://foo.com/bar.pdf".'));
  309. expect((0, _network_utils.createResponseStatusError)(0, "https://foo.com/bar.pdf")).toEqual(new _util.UnexpectedResponseException("Unexpected server response (0) while retrieving PDF " + '"https://foo.com/bar.pdf".'));
  310. });
  311. });
  312. describe("validateResponseStatus", function () {
  313. it("accepts valid response statuses", function () {
  314. expect((0, _network_utils.validateResponseStatus)(200)).toEqual(true);
  315. expect((0, _network_utils.validateResponseStatus)(206)).toEqual(true);
  316. });
  317. it("rejects invalid response statuses", function () {
  318. expect((0, _network_utils.validateResponseStatus)(302)).toEqual(false);
  319. expect((0, _network_utils.validateResponseStatus)(404)).toEqual(false);
  320. expect((0, _network_utils.validateResponseStatus)(null)).toEqual(false);
  321. expect((0, _network_utils.validateResponseStatus)(undefined)).toEqual(false);
  322. });
  323. });
  324. });