requests.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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, singlefile, */
  24. singlefile.extension.core.bg.requests = (() => {
  25. const REQUEST_ID_HEADER_NAME = "x-single-file-request-id";
  26. const referrers = new Map();
  27. let referrerOnErrorEnabled = false;
  28. return {
  29. REQUEST_ID_HEADER_NAME,
  30. onMessage,
  31. setReferrer,
  32. enableReferrerOnError
  33. };
  34. function onMessage(message) {
  35. if (message.method.endsWith(".enableReferrerOnError")) {
  36. enableReferrerOnError();
  37. return {};
  38. }
  39. if (message.method.endsWith(".disableReferrerOnError")) {
  40. disableReferrerOnError();
  41. return {};
  42. }
  43. }
  44. function setReferrer(requestId, referrer) {
  45. referrers.set(requestId, referrer);
  46. }
  47. function injectRefererHeader(details) {
  48. if (referrerOnErrorEnabled) {
  49. let requestIdHeader = details.requestHeaders.find(header => header.name === REQUEST_ID_HEADER_NAME);
  50. if (requestIdHeader) {
  51. details.requestHeaders = details.requestHeaders.filter(header => header.name !== REQUEST_ID_HEADER_NAME);
  52. const referrer = referrers.get(requestIdHeader.value);
  53. if (referrer) {
  54. referrers.delete(requestIdHeader.value);
  55. const header = details.requestHeaders.find(header => header.name.toLowerCase() === "referer");
  56. if (!header) {
  57. details.requestHeaders.push({ name: "Referer", value: referrer });
  58. return { requestHeaders: details.requestHeaders };
  59. }
  60. }
  61. }
  62. }
  63. }
  64. function enableReferrerOnError() {
  65. if (!referrerOnErrorEnabled) {
  66. try {
  67. browser.webRequest.onBeforeSendHeaders.addListener(injectRefererHeader, { urls: ["<all_urls>"] }, ["blocking", "requestHeaders", "extraHeaders"]);
  68. } catch (error) {
  69. browser.webRequest.onBeforeSendHeaders.addListener(injectRefererHeader, { urls: ["<all_urls>"] }, ["blocking", "requestHeaders"]);
  70. }
  71. referrerOnErrorEnabled = true;
  72. }
  73. }
  74. function disableReferrerOnError() {
  75. try {
  76. browser.webRequest.onBeforeSendHeaders.removeListener(injectRefererHeader);
  77. } catch (error) {
  78. // ignored
  79. }
  80. referrerOnErrorEnabled = false;
  81. }
  82. })();