webrequest.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. md.webrequest = ({storage: {state}, detect}) => {
  2. var permissions = ['webRequest', 'webRequestBlocking']
  3. var filter = {
  4. urls: ['<all_urls>'],
  5. types: ['main_frame', 'sub_frame']
  6. }
  7. var options = ['blocking', 'responseHeaders']
  8. var onHeadersReceived = ({method, url, statusCode, responseHeaders}) => {
  9. if (method !== 'GET') {
  10. return {responseHeaders}
  11. }
  12. var header = responseHeaders.find(({name}) => /^content-type/i.test(name))
  13. var origin = detect.match(url)
  14. if (/Firefox/.test(navigator.userAgent)) {
  15. // ff: markdown `content-type` is not allowed
  16. if (header && detect.header(header.value)) {
  17. var [_, charset] = header.value.split(';')
  18. header.value = `text/plain${charset ? `; ${charset}` : ''}`
  19. }
  20. // ff: missing `content-type` is not allowed
  21. else if (!header && origin && statusCode === 200) {
  22. header = {name: 'Content-Type', value: 'text/plain'}
  23. responseHeaders.push(header)
  24. }
  25. }
  26. if (!origin) {
  27. return {responseHeaders}
  28. }
  29. if (origin.csp) {
  30. responseHeaders = responseHeaders
  31. .filter(({name}) => !/content-security-policy/i.test(name))
  32. }
  33. if (origin.encoding && header && (
  34. /charset/.test(header.value) ||
  35. // ff: won't decode correctly by default
  36. /Firefox/.test(navigator.userAgent)
  37. )) {
  38. var [media] = header.value.split(';')
  39. header.value = `${media}; charset=${origin.encoding}`
  40. }
  41. return {responseHeaders}
  42. }
  43. var onCompleted = ({ip, tabId}) => {
  44. if (ip && ip !== '127.0.0.1' && ip !== '::1') {
  45. setTimeout(() => {
  46. chrome.tabs.sendMessage(tabId, {message: 'autoreload'})
  47. }, 500)
  48. }
  49. }
  50. var events = () => {
  51. var headers = false
  52. for (var key in state.origins) {
  53. if (state.origins[key].csp || state.origins[key].encoding) {
  54. headers = true
  55. break
  56. }
  57. }
  58. // ff: webRequest is required permission
  59. if (/Firefox/.test(navigator.userAgent)) {
  60. headers = true
  61. }
  62. var completed = false
  63. if (state.content.autoreload) {
  64. completed = true
  65. }
  66. return {headers, completed}
  67. }
  68. var perm = (headers, completed, done) => {
  69. // ff: webRequest is required permission
  70. if (/Firefox/.test(navigator.userAgent)) {
  71. done()
  72. }
  73. // request permissions
  74. else if ((headers || completed) && !chrome.webRequest) {
  75. chrome.permissions.request({permissions}, done)
  76. }
  77. // remove permissions
  78. else if (!headers && !completed && chrome.webRequest) {
  79. chrome.permissions.remove({permissions}, () => {
  80. chrome.webRequest = null
  81. done()
  82. })
  83. }
  84. else {
  85. done()
  86. }
  87. }
  88. var webrequest = () => {
  89. var {headers, completed} = events()
  90. // remove listeners
  91. if (chrome.webRequest) {
  92. if (!headers && !/Firefox/.test(navigator.userAgent)) {
  93. chrome.webRequest.onHeadersReceived.removeListener(onHeadersReceived)
  94. }
  95. if (!completed) {
  96. chrome.webRequest.onCompleted.removeListener(onCompleted)
  97. }
  98. }
  99. perm(headers, completed, () => {
  100. // add listeners
  101. if (headers && !chrome.webRequest.onHeadersReceived.hasListener(onHeadersReceived)) {
  102. chrome.webRequest.onHeadersReceived.addListener(onHeadersReceived, filter, options)
  103. }
  104. if (completed && !chrome.webRequest.onCompleted.hasListener(onCompleted)) {
  105. chrome.webRequest.onCompleted.addListener(onCompleted, filter)
  106. }
  107. })
  108. }
  109. webrequest.init = () => {
  110. chrome.webRequest.onHeadersReceived.addListener(onHeadersReceived, filter, options)
  111. chrome.webRequest.onCompleted.addListener(onCompleted, filter)
  112. }
  113. return webrequest
  114. }