Skip to content

Commit

Permalink
fix: skip XHRs that would fail due to CORS bug
Browse files Browse the repository at this point in the history
  • Loading branch information
lidel committed Jun 4, 2018
1 parent 62d5438 commit 231df22
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
17 changes: 16 additions & 1 deletion add-on/src/lib/ipfs-request.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict'
/* eslint-env browser */
/* eslint-env browser, webextensions */

const IsIpfs = require('is-ipfs')
const { urlAtPublicGw } = require('./ipfs-path')
Expand Down Expand Up @@ -52,6 +52,21 @@ function createRequestModifier (getState, dnsLink, ipfsPathValidator) {
if (request.method === 'HEAD' && state.preloadAtPublicGateway && request.url.startsWith(state.pubGwURLString)) {
return
}
// Ignore XHR requests for which redirect would fail due to CORS bug in Firefox
// - We want the same behaviour on all browsers, so we conform to the Firefox limitation
// - More context: https://github.com/ipfs-shipyard/ipfs-companion/issues/436
if (request.type === 'xmlhttprequest') {
// XHR Origin is fuzzy right now: Firefox 60 uses request.originUrl, Chrome 63 uses request.initiator
const originUrl = request.originUrl || request.initiator
if (originUrl) {
const sourceOrigin = new URL(originUrl).origin
const targetOrigin = new URL(request.url).origin
if (sourceOrigin !== targetOrigin) {
console.warn('[ipfs-companion] skipping XHR redirect due to https://github.com/ipfs-shipyard/ipfs-companion/issues/436', request)
return
}
}
}
// Detect valid /ipfs/ and /ipns/ on any site
if (ipfsPathValidator.publicIpfsOrIpnsResource(request.url)) {
return redirectToGateway(request.url, state)
Expand Down
51 changes: 49 additions & 2 deletions test/functional/lib/ipfs-request.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,53 @@ describe('modifyRequest', function () {
})
})

describe('XHR request for a path matching /ipfs/{CIDv0}', function () {
describe('with external node', function () {
beforeEach(function () {
state.ipfsNodeType = 'external'
})
it('should be served from custom gateway if fetched from the same origin and redirect is enabled in Firefox', function () {
const xhrRequest = {url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', originUrl: 'https://google.com/'}
expect(modifyRequest(xhrRequest).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest')
})
it('should be served from custom gateway if fetched from the same origin and redirect is enabled in Chrome', function () {
const xhrRequest = {url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', initiator: 'https://google.com/'}
expect(modifyRequest(xhrRequest).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest')
})
})
describe('with embedded node', function () {
beforeEach(function () {
state.ipfsNodeType = 'embedded'
})
it('should be served from public gateway if fetched from the same origin and redirect is enabled in Firefox', function () {
const xhrRequest = {url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', originUrl: 'https://google.com/'}
expect(modifyRequest(xhrRequest).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest')
})
it('should be served from public gateway if fetched from the same origin and redirect is enabled in Chrome', function () {
const xhrRequest = {url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', initiator: 'https://google.com/'}
expect(modifyRequest(xhrRequest).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest')
})
})
describe('with every node type', function () {
// tests in which results should be the same for all node types
nodeTypes.forEach(function (nodeType) {
beforeEach(function () {
state.ipfsNodeType = nodeType
})
it(`should be left untouched if request is a cross-origin XHR (Firefox, ${nodeType} node)`, function () {
// Context: https://github.com/ipfs-shipyard/ipfs-companion/issues/436
const xhrRequest = {url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', originUrl: 'https://www.nasa.gov/foo.html'}
expect(modifyRequest(xhrRequest)).to.equal(undefined)
})
it(`should be left untouched if request is a cross-origin XHR (Chrome, ${nodeType} node)`, function () {
// Context: https://github.com/ipfs-shipyard/ipfs-companion/issues/436
const xhrRequest = {url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', initiator: 'https://www.nasa.gov/foo.html'}
expect(modifyRequest(xhrRequest)).to.equal(undefined)
})
})
})
})

describe('request for a path matching /ipns/{path}', function () {
describe('with external node', function () {
beforeEach(function () {
Expand Down Expand Up @@ -317,8 +364,8 @@ describe('modifyRequest', function () {
expect(modifyRequest(request)).to.equal(undefined)
})
it('should not be normalized if request.type != main_frame', function () {
const xhrRequest = {url: 'https://duckduckgo.com/?q=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar', type: 'xmlhttprequest'}
expect(modifyRequest(xhrRequest)).to.equal(undefined)
const mediaRequest = {url: 'https://duckduckgo.com/?q=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar', type: 'media'}
expect(modifyRequest(mediaRequest)).to.equal(undefined)
})
})

Expand Down

0 comments on commit 231df22

Please sign in to comment.