Skip to content

Commit

Permalink
feat(firefox>59): no prefix for redir protocols
Browse files Browse the repository at this point in the history
  • Loading branch information
lidel committed Feb 5, 2018
1 parent 83f5028 commit 0be75e3
Show file tree
Hide file tree
Showing 5 changed files with 380 additions and 80 deletions.
29 changes: 22 additions & 7 deletions add-on/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"applications": {
"gecko": {
"id": "ipfs-firefox-addon@lidel.org",
"strict_min_version": "57.0"
"strict_min_version": "59.0"
}
},

Expand Down Expand Up @@ -63,18 +63,33 @@
"protocol_handlers": [
{
"protocol": "web+dweb",
"name": "IPFS Add-On: DWEB protocol handler",
"uriTemplate": "https://ipfs.io/%s"
"name": "IPFS Companion: DWEB Protocol Handler",
"uriTemplate": "https://ipfs.io/#redirect/%s"
},
{
"protocol": "web+ipns",
"name": "IPFS Add-On: IPNS protocol handler",
"uriTemplate": "https://ipfs.io/%s"
"name": "IPFS Companion: IPNS Protocol Handler",
"uriTemplate": "https://ipfs.io/#redirect/%s"
},
{
"protocol": "web+ipfs",
"name": "IPFS Add-On: IPFS protocol handler",
"uriTemplate": "https://ipfs.io/%s"
"name": "IPFS Companion: IPFS Protocol Handler",
"uriTemplate": "https://ipfs.io/#redirect/%s"
},
{
"protocol": "dweb",
"name": "IPFS Companion: DWEB Protocol Handler",
"uriTemplate": "https://ipfs.io/#redirect/%s"
},
{
"protocol": "ipns",
"name": "IPFS Companion: IPNS Protocol Handler",
"uriTemplate": "https://ipfs.io/#redirect/%s"
},
{
"protocol": "ipfs",
"name": "IPFS Companion: IPFS Protocol Handler",
"uriTemplate": "https://ipfs.io/#redirect/%s"
}
],

Expand Down
36 changes: 24 additions & 12 deletions add-on/src/lib/ipfs-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ function createRequestModifier (getState, dnsLink, ipfsPathValidator) {
}

// handler for protocol_handlers from manifest.json
if (webPlusProtocolRequest(request)) {
if (redirectingProtocolRequest(request)) {
// fix path passed via custom protocol
const fix = normalizedWebPlusRequest(request, state.pubGwURLString)
const fix = normalizedRedirectingProtocolRequest(request, state.pubGwURLString)
if (fix) {
return fix
}
Expand Down Expand Up @@ -63,28 +63,40 @@ function redirectToCustomGateway (requestUrl, gwUrl) {
return { redirectUrl: url.toString() }
}

// PROTOCOL HANDLERS: web+ in Firefox (protocol_handlers from manifest.json)
// REDIRECT-BASED PROTOCOL HANDLERS
// This API is available only Firefox (protocol_handlers from manifest.json)
// Background: https://github.com/ipfs-shipyard/ipfs-companion/issues/164#issuecomment-282513891
// Notes on removal of web+ in Firefox 59: https://github.com/ipfs-shipyard/ipfs-companion/issues/164#issuecomment-355708883
// ===================================================================

const webPlusProtocolHandler = 'https://ipfs.io/web%2B'
// This is just a placeholder that we had to provide -- removed in normalizedRedirectingProtocolRequest()
const redirectingProtocolHandler = 'https://ipfs.io/#redirect/'

function webPlusProtocolRequest (request) {
return request.url.startsWith(webPlusProtocolHandler)
function redirectingProtocolRequest (request) {
return request.url.startsWith(redirectingProtocolHandler)
}

function normalizedWebPlusRequest (request, pubGwUrl) {
const oldPath = decodeURIComponent(new URL(request.url).pathname)
function normalizedRedirectingProtocolRequest (request, pubGwUrl) {
const oldPath = decodeURIComponent(new URL(request.url).hash)
let path = oldPath
path = path.replace(/^\/web\+dweb:\//i, '/') // web+dweb:/ipfs/Qm → /ipfs/Qm
path = path.replace(/^\/web\+ipfs:\/\//i, '/ipfs/') // web+ipfs://Qm → /ipfs/Qm
path = path.replace(/^\/web\+ipns:\/\//i, '/ipns/') // web+ipns://Qm → /ipns/Qm
// prefixed (Firefox < 59)
path = path.replace(/^#redirect\/web\+dweb:\//i, '/') // web+dweb:/ipfs/Qm → /ipfs/Qm
path = path.replace(/^#redirect\/web\+ipfs:\/\//i, '/ipfs/') // web+ipfs://Qm → /ipfs/Qm
path = path.replace(/^#redirect\/web\+ipns:\/\//i, '/ipns/') // web+ipns://Qm → /ipns/Qm
// without prefix (Firefox >= 59)
path = path.replace(/^#redirect\/dweb:\//i, '/') // dweb:/ipfs/Qm → /ipfs/Qm
path = path.replace(/^#redirect\/ipfs:\/\//i, '/ipfs/') // ipfs://Qm → /ipfs/Qm
path = path.replace(/^#redirect\/ipns:\/\//i, '/ipns/') // ipns://Qm → /ipns/Qm
// console.log(`oldPath: '${oldPath}' new: '${path}'`)
if (oldPath !== path && IsIpfs.path(path)) {
return { redirectUrl: urlAtPublicGw(path, pubGwUrl) }
}
return null
}

// PROTOCOL HANDLERS: UNIVERSAL FALLBACK FOR UNHANDLED PROTOCOLS
// SEARCH-HIJACK HANDLERS: UNIVERSAL FALLBACK FOR UNHANDLED PROTOCOLS
// (Used in Chrome and other browsers that do not provide better alternatives)
// Background: https://github.com/ipfs-shipyard/ipfs-companion/issues/164#issuecomment-328374052
// ===================================================================

const unhandledIpfsRE = /=(?:web%2B|)(ipfs(?=%3A%2F%2F)|ipns(?=%3A%2F%2F)|dweb(?=%3A%2Fip[f|n]s))%3A(?:%2F%2F|%2F)([^&]+)/
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"sinon-chrome": "2.2.1",
"standard": "10.0.3",
"watchify": "3.9.0",
"web-ext": "2.3.2"
"web-ext": "2.4.0"
},
"dependencies": {
"choo": "6.6.1",
Expand Down
56 changes: 45 additions & 11 deletions test/functional/lib/ipfs-request.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,45 +85,79 @@ describe('modifyRequest', function () {
})
})

describe('request made via "web+" handler from manifest.json/protocol_handlers', function () {
describe('request made via redirecting handler from manifest.json/protocol_handlers', function () {
// Firefox >= 59: https://github.com/ipfs-shipyard/ipfs-companion/issues/164#issuecomment-356301174
it('should not be normalized if ipfs:/{CID}', function () {
const request = url2request('https://ipfs.io/#redirect/ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
it('should be normalized if ipfs://{CID}', function () {
const request = url2request('https://ipfs.io/#redirect/ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
expect(modifyRequest(request).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest')
})
it('should not be normalized if ipns:/{foo}', function () {
const request = url2request('https://ipfs.io/#redirect/ipns%3A%2Fipfs.io%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
it('should be normalized if ipns://{foo}', function () {
const request = url2request('https://ipfs.io/#redirect/ipns%3A%2F%2Fipfs.io%3FargTest%23hashTest')
expect(modifyRequest(request).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest')
})
it('should be normalized if dweb:/ipfs/{CID}', function () {
const request = url2request('https://ipfs.io/#redirect/dweb%3A%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
expect(modifyRequest(request).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest')
})
it('should not be normalized if dweb://ipfs/{CID}', function () {
const request = url2request('https://ipfs.io/#redirect/dweb%3A%2F%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
it('should be normalized if dweb:/ipns/{foo}', function () {
const request = url2request('https://ipfs.io/#redirect/dweb%3A%2Fipns/ipfs.io%3FargTest%23hashTest')
expect(modifyRequest(request).redirectUrl).equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest')
})
it('should not be normalized if dweb://ipns/{foo}', function () {
const request = url2request('https://ipfs.io/#redirect/dweb%3A%2F%2Fipns/ipfs.io%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
// prefixed versions (Firefox < 59)
it('should not be normalized if web+ipfs:/{CID}', function () {
const request = url2request('https://ipfs.io/web%2Bipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
it('should be normalized if web+ipfs://{CID}', function () {
const request = url2request('https://ipfs.io/web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
expect(modifyRequest(request).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest')
})
it('should not be normalized if web+ipns:/{foo}', function () {
const request = url2request('https://ipfs.io/web%2Bipns%3A%2Fipfs.io%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bipns%3A%2Fipfs.io%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
it('should be normalized if web+ipns://{foo}', function () {
const request = url2request('https://ipfs.io/web%2Bipns%3A%2F%2Fipfs.io%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bipns%3A%2F%2Fipfs.io%3FargTest%23hashTest')
expect(modifyRequest(request).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest')
})
it('should be normalized if web+dweb:/ipfs/{CID}', function () {
const request = url2request('https://ipfs.io/web%2Bdweb%3A%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bdweb%3A%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
expect(modifyRequest(request).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest')
})
it('should not be normalized if web+dweb://ipfs/{CID}', function () {
const request = url2request('https://ipfs.io/web%2Bdweb%3A%2F%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bdweb%3A%2F%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
it('should be normalized if web+dweb:/ipns/{foo}', function () {
const request = url2request('https://ipfs.io/web%2Bdweb%3A%2Fipns/ipfs.io%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bdweb%3A%2Fipns/ipfs.io%3FargTest%23hashTest')
expect(modifyRequest(request).redirectUrl).equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest')
})
it('should not be normalized if web+dweb://ipns/{foo}', function () {
const request = url2request('https://ipfs.io/web%2Bdweb%3A%2F%2Fipns/ipfs.io%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bdweb%3A%2F%2Fipns/ipfs.io%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
it('should not be normalized if web+{foo}:/bar', function () {
const request = url2request('https://ipfs.io/web%2Bfoo%3A%2Fbar%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bfoo%3A%2Fbar%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
it('should not be normalized if web+{foo}://bar', function () {
const request = url2request('https://ipfs.io/web%2Bfoo%3A%2F%2Fbar%3FargTest%23hashTest')
const request = url2request('https://ipfs.io/#redirect/web%2Bfoo%3A%2F%2Fbar%3FargTest%23hashTest')
expect(modifyRequest(request)).to.equal(undefined)
})
})
Expand Down
Loading

0 comments on commit 0be75e3

Please sign in to comment.