diff --git a/src/classes/Fetcher.coffee b/src/classes/Fetcher.coffee index 30f21e2db..af98fb141 100644 --- a/src/classes/Fetcher.coffee +++ b/src/classes/Fetcher.coffee @@ -106,13 +106,15 @@ class Fetcher archive = Redirect.data.post[@boardID] encryptionOK = /^https:\/\//.test(url) or location.protocol is 'http:' if encryptionOK or Conf['Exempt Archives from Encryption'] - CrossOrigin.json url, (response) => - {media} = response - if !encryptionOK and media then for key of media when /_link$/.test key - # Image/thumbnail URLs loaded over HTTP can be modified in transit. - # Require them to be from an HTTP host so that no referrer is sent to them from an HTTPS page. - delete media[key] unless media[key]?.match /^http:\/\// - @parseArchivedPost response, url, archive + that = @ + CrossOrigin.json url, -> + if !encryptionOK and @response?.media + {media} = @response + for key of media when /_link$/.test key + # Image/thumbnail URLs loaded over HTTP can be modified in transit. + # Require them to be from an HTTP host so that no referrer is sent to them from an HTTPS page. + delete media[key] unless media[key]?.match /^http:\/\// + that.parseArchivedPost @response, url, archive return true return false diff --git a/src/meta/eventPage.coffee b/src/meta/eventPage.coffee index de87915e4..a740cce05 100644 --- a/src/meta/eventPage.coffee +++ b/src/meta/eventPage.coffee @@ -27,15 +27,15 @@ ajax = (request, sender, sendResponse) -> xhr.open 'GET', request.url, true xhr.responseType = request.responseType xhr.addEventListener 'load', -> + {status, statusText, response} = @ if @readyState is @DONE && xhr.status is 200 - {response} = @ if request.responseType is 'arraybuffer' response = [new Uint8Array(response)...] contentType = @getResponseHeader 'Content-Type' contentDisposition = @getResponseHeader 'Content-Disposition' - chrome.tabs.sendMessage sender.tab.id, {id, response, contentType, contentDisposition} + chrome.tabs.sendMessage sender.tab.id, {id, status, statusText, response, contentType, contentDisposition} else - chrome.tabs.sendMessage sender.tab.id, {id, error: true} + chrome.tabs.sendMessage sender.tab.id, {id, status, statusText, response, error: true} , false xhr.addEventListener 'error', -> chrome.tabs.sendMessage sender.tab.id, {id, error: true} diff --git a/src/platform/CrossOrigin.coffee b/src/platform/CrossOrigin.coffee index ff0b210f9..e4390c8a6 100644 --- a/src/platform/CrossOrigin.coffee +++ b/src/platform/CrossOrigin.coffee @@ -83,45 +83,62 @@ CrossOrigin = blob.name = name cb blob + # Attempts to fetch `url` in JSON format using cross-origin privileges, if available. + # On success, calls `cb` with a `this` containing properties `status`, `statusText`, `response` and caches result. + # On error/abort, calls `cb` with a `this` of `{}`. json: do -> callbacks = {} - responses = {} + results = {} + success = (url, result) -> + for cb in callbacks[url] + $.queueTask -> cb.call result + delete callbacks[url] + results[url] = result + failure = (url) -> + for cb in callbacks[url] + $.queueTask -> cb.call {} + delete callbacks[url] + (url, cb) -> <% if (type === 'crx') { %> - if /^https:\/\//.test(url) or location.protocol is 'http:' - return $.cache url, (-> cb @response), responseType: 'json' + plainAJAX = (/^https:\/\//.test(url) or location.protocol is 'http:') <% } %> <% if (type === 'userscript') { %> - unless GM?.xmlHttpRequest? or GM_xmlhttpRequest? - return $.cache url, (-> cb @response), responseType: 'json' + plainAJAX = not (GM?.xmlHttpRequest? or GM_xmlhttpRequest?) <% } %> - if responses[url] - cb responses[url] + if plainAJAX + if (req = $.cache url, cb, responseType: 'json') + $.on req, 'abort error', -> cb.call({}) + else + cb.call {} + return + + if results[url] + cb.call results[url] return if callbacks[url] callbacks[url].push cb return callbacks[url] = [cb] + <% if (type === 'userscript') { %> (GM?.xmlHttpRequest or GM_xmlhttpRequest) method: "GET" url: url+'' onload: (xhr) -> - response = JSON.parse xhr.responseText - cb response for cb in callbacks[url] - delete callbacks[url] - responses[url] = response - onerror: -> - delete callbacks[url] - onabort: -> - delete callbacks[url] + {status, statusText} = xhr + try + response = JSON.parse(xhr.responseText) + success url, {status, statusText, response} + catch + failure url + onerror: -> failure(url) + onabort: -> failure(url) <% } %> <% if (type === 'crx') { %> - eventPageRequest url, 'json', ({response, error}) -> - if error - delete callbacks[url] + eventPageRequest url, 'json', (result) -> + if result.status + success url, result else - cb response for cb in callbacks[url] - delete callbacks[url] - responses[url] = response + failure url <% } %>