requests.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright 2010-2020 Gildas Lormeau
  3. * contact : gildas.lormeau <at> gmail.com
  4. *
  5. * This file is part of SingleFile.
  6. *
  7. * The code in this file is free software: you can redistribute it and/or
  8. * modify it under the terms of the GNU Affero General Public License
  9. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  10. * of the License, or (at your option) any later version.
  11. *
  12. * The code in this file is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  15. * General Public License for more details.
  16. *
  17. * As additional permission under GNU AGPL version 3 section 7, you may
  18. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  19. * AGPL normally required by section 4, provided you include this license
  20. * notice and a URL through which recipients can access the Corresponding
  21. * Source.
  22. */
  23. /* global browser */
  24. const REQUEST_ID_HEADER_NAME = "x-single-file-request-id";
  25. const referrers = new Map();
  26. let referrerOnErrorEnabled = false;
  27. export {
  28. REQUEST_ID_HEADER_NAME,
  29. onMessage,
  30. setReferrer,
  31. enableReferrerOnError
  32. };
  33. function onMessage(message) {
  34. if (message.method.endsWith(".enableReferrerOnError")) {
  35. enableReferrerOnError();
  36. return {};
  37. }
  38. if (message.method.endsWith(".disableReferrerOnError")) {
  39. disableReferrerOnError();
  40. return {};
  41. }
  42. }
  43. function setReferrer(requestId, referrer) {
  44. referrers.set(requestId, referrer);
  45. }
  46. function injectRefererHeader(details) {
  47. if (referrerOnErrorEnabled) {
  48. let requestIdHeader = details.requestHeaders.find(header => header.name === REQUEST_ID_HEADER_NAME);
  49. if (requestIdHeader) {
  50. details.requestHeaders = details.requestHeaders.filter(header => header.name !== REQUEST_ID_HEADER_NAME);
  51. const referrer = referrers.get(requestIdHeader.value);
  52. if (referrer) {
  53. referrers.delete(requestIdHeader.value);
  54. const header = details.requestHeaders.find(header => header.name.toLowerCase() === "referer");
  55. if (!header) {
  56. details.requestHeaders.push({ name: "Referer", value: referrer });
  57. return { requestHeaders: details.requestHeaders };
  58. }
  59. }
  60. }
  61. }
  62. }
  63. function enableReferrerOnError() {
  64. if (!referrerOnErrorEnabled) {
  65. try {
  66. browser.webRequest.onBeforeSendHeaders.addListener(injectRefererHeader, { urls: ["<all_urls>"] }, ["blocking", "requestHeaders", "extraHeaders"]);
  67. } catch (error) {
  68. browser.webRequest.onBeforeSendHeaders.addListener(injectRefererHeader, { urls: ["<all_urls>"] }, ["blocking", "requestHeaders"]);
  69. }
  70. referrerOnErrorEnabled = true;
  71. }
  72. }
  73. function disableReferrerOnError() {
  74. try {
  75. browser.webRequest.onBeforeSendHeaders.removeListener(injectRefererHeader);
  76. } catch (error) {
  77. // ignored
  78. }
  79. referrerOnErrorEnabled = false;
  80. }