Skip to content

Commit

Permalink
Support for "web+" protocol prefix
Browse files Browse the repository at this point in the history
- closes #36
- follows consensus from
  ipfs/kubo#1678 (comment)
  • Loading branch information
lidel committed Dec 27, 2015
1 parent 9b2254a commit 6187aa4
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 50 deletions.
10 changes: 3 additions & 7 deletions lib/child-main.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
'use strict';

const proto = require("./protocols.js");
const protocols = require("./protocols.js");

proto.fs.register();
proto.ipfs.register();
proto.ipns.register();
protocols.register();

require("sdk/system/unload").when(() => {
proto.fs.unregister();
proto.ipfs.unregister();
proto.ipns.unregister();
protocols.unregister();
});
10 changes: 3 additions & 7 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,19 @@

require('./gui.js');
require('./gateways.js');
var proto = require('./protocols.js');
var protocols = require('./protocols.js');

const parent = require('sdk/remote/parent');


exports.main = function(options, callbacks) { // jshint unused:false
require('./redirects.js');
proto.fs.register();
proto.ipfs.register();
proto.ipns.register();
protocols.register();
//console.log('Addon loaded.');
parent.remoteRequire("./lib/child-main.js");
};

exports.onUnload = function(reason) { // jshint unused:false
proto.fs.unregister();
proto.ipfs.unregister();
proto.ipns.unregister();
protocols.unregister();
//console.log('Addon unloaded: ' + reason);
};
64 changes: 51 additions & 13 deletions lib/protocols.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,29 @@ var gw = require('./gateways.js');
const IPFS_SCHEME = 'ipfs';
const IPNS_SCHEME = 'ipns';
const FS_SCHEME = 'fs';
const WEB_SCHEME_PREFIX = 'web+'; // https://github.com/lidel/ipfs-firefox-addon/issues/36


function CommonProtocolHandler() {}

function IpfsProtocolHandler() {}
function WebIpfsProtocolHandler() {}

function IpnsProtocolHandler() {}
function WebIpnsProtocolHandler() {}

function FsProtocolHandler() {}
function WebFsProtocolHandler() {}

const HANDLERS = {
'fs': FsProtocolHandler,
'ipfs': IpfsProtocolHandler,
'ipns': IpnsProtocolHandler,

'web+fs': WebFsProtocolHandler,
'web+ipfs': WebIpfsProtocolHandler,
'web+ipns': WebIpnsProtocolHandler
};

CommonProtocolHandler.prototype = Object.freeze({

Expand Down Expand Up @@ -47,7 +62,8 @@ CommonProtocolHandler.prototype = Object.freeze({
return uri;
*/

let ipfsPath = aSpec.replace(new RegExp('^' + this.scheme + '\\:\\/*'), '');
let schemeExp = this.scheme.replace(/\+/, '\\+'); // web+fs etc
let ipfsPath = aSpec.replace(new RegExp('^' + schemeExp + '\\:\\/*'), '');
let http = gw.publicUri().spec + this.pathPrefix + ipfsPath;
let uri = ioservice.newURI(http, aOriginCharset, null);

Expand All @@ -71,32 +87,46 @@ CommonProtocolHandler.prototype = Object.freeze({

});

// https://github.com/lidel/ipfs-firefox-addon/issues/36
function createWebVariant(target, base, uuid) {
target.prototype = Object.create(base.prototype);
target.prototype.constructor = target;
target.prototype.scheme = WEB_SCHEME_PREFIX + base.prototype.scheme;
target.prototype.classDescription = WEB_SCHEME_PREFIX + base.prototype.classDescription;
target.prototype.classID = components.ID(uuid);
target.prototype.contractID = '@mozilla.org/network/protocol;1?name=' + target.prototype.scheme;
target.prototype.QueryInterface = XPCOMUtils.generateQI([Ci.nsIProtocolHandler]);
}

IpfsProtocolHandler.prototype = Object.create(CommonProtocolHandler.prototype);
IpfsProtocolHandler.prototype.constructor = IpfsProtocolHandler;
IpfsProtocolHandler.prototype.classDescription = 'IPFS Protocol Handler';
IpfsProtocolHandler.prototype.classDescription = 'ipfs Protocol Handler';
IpfsProtocolHandler.prototype.contractID = '@mozilla.org/network/protocol;1?name=' + IPFS_SCHEME;
IpfsProtocolHandler.prototype.classID = components.ID('{34023afe-f3aa-4b3d-b546-cb66f6e14c4b}');
IpfsProtocolHandler.prototype.QueryInterface = XPCOMUtils.generateQI([Ci.nsIProtocolHandler]);
IpfsProtocolHandler.prototype.scheme = IPFS_SCHEME;
IpfsProtocolHandler.prototype.pathPrefix = IPFS_SCHEME + '/';
createWebVariant(WebIpfsProtocolHandler, IpfsProtocolHandler, '{713a4fe5-c5b8-43fa-a0c3-2742b3eea368}');

IpnsProtocolHandler.prototype = Object.create(CommonProtocolHandler.prototype);
IpnsProtocolHandler.prototype.constructor = IpnsProtocolHandler;
IpnsProtocolHandler.prototype.classDescription = 'IPNS Protocol Handler';
IpnsProtocolHandler.prototype.classDescription = 'ipns Protocol Handler';
IpnsProtocolHandler.prototype.contractID = '@mozilla.org/network/protocol;1?name=' + IPNS_SCHEME;
IpnsProtocolHandler.prototype.classID = components.ID('{33920c2c-dd6b-11e4-b9d6-1681e6b88ec1}');
IpnsProtocolHandler.prototype.QueryInterface = XPCOMUtils.generateQI([Ci.nsIProtocolHandler]);
IpnsProtocolHandler.prototype.scheme = IPNS_SCHEME;
IpnsProtocolHandler.prototype.pathPrefix = IPNS_SCHEME + '/';
createWebVariant(WebIpnsProtocolHandler, IpnsProtocolHandler, '{0f612fe4-5aa5-41ce-9fec-d827b702f5da}');

FsProtocolHandler.prototype = Object.create(CommonProtocolHandler.prototype);
FsProtocolHandler.prototype.constructor = FsProtocolHandler;
FsProtocolHandler.prototype.classDescription = 'FS Protocol Handler';
FsProtocolHandler.prototype.classDescription = 'fs Protocol Handler';
FsProtocolHandler.prototype.contractID = '@mozilla.org/network/protocol;1?name=' + FS_SCHEME;
FsProtocolHandler.prototype.classID = components.ID('{6684bdd9-41b5-4de3-ab3e-de3f3d888dcd}');
FsProtocolHandler.prototype.QueryInterface = XPCOMUtils.generateQI([Ci.nsIProtocolHandler]);
FsProtocolHandler.prototype.scheme = FS_SCHEME;
FsProtocolHandler.prototype.pathPrefix = '';
createWebVariant(WebFsProtocolHandler, FsProtocolHandler, '{82fbb59e-8349-442e-ad4e-ed3fa705c79d}');

function factory(ProtocolHandler) {
return Object.freeze({
Expand Down Expand Up @@ -125,14 +155,22 @@ function factory(ProtocolHandler) {
});
}

exports.ipfsScheme = IPFS_SCHEME;
exports.ipnsScheme = IPNS_SCHEME;
exports.fsScheme = FS_SCHEME;
// export handler factories (used in tests)
for (var scheme in HANDLERS) {
exports[scheme] = factory(HANDLERS[scheme]);
}

// register protocols
exports.register = function() {
for (var scheme in HANDLERS) {
(exports[scheme]).register();
}
};

exports.ipfsHandler = Object.freeze(IpfsProtocolHandler);
exports.ipnsHandler = Object.freeze(IpnsProtocolHandler);
exports.fsHandler = Object.freeze(FsProtocolHandler);
// unregister protocols
exports.unregister = function() {
for (var scheme in HANDLERS) {
(exports[scheme]).unregister();
}
};

exports.ipfs = factory(IpfsProtocolHandler);
exports.ipns = factory(IpnsProtocolHandler);
exports.fs = factory(FsProtocolHandler);
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"id": "ipfs-firefox-addon@lidel.org",
"description": "Access IPFS resources via custom HTTP2IPFS gateway",
"author": "Marcin Rataj",
"version": "1.3.2",
"version": "1.3.3",
"license": "CC0-1.0",
"homepage": "https://github.com/lidel/ipfs-firefox-addon",
"icon": "data/icon-on-64.png",
Expand Down
116 changes: 94 additions & 22 deletions test/test-protocols.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,70 @@ const pubGwUri = gw.publicUri();
const ipfsPath = 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/example#/ipfs/QmSsNVuALPa1TW1GDahup8fFDqo95iFyPE7E6HpqDivw3p/readme.md';
const ipnsPath = 'ipfs.git.sexy';

exports['test ipfsScheme'] = function(assert) {
assert.equal(proto.ipfsScheme, 'ipfs', 'handler scheme');
};
const ipfsHandler = proto.ipfs.createInstance();
const ipnsHandler = proto.ipns.createInstance();
const fsHandler = proto.fs.createInstance();

const webIpfsHandler = proto['web+ipfs'].createInstance();
const webIpnsHandler = proto['web+ipns'].createInstance();
const webFsHandler = proto['web+fs'].createInstance();

exports['test ipnsScheme'] = function(assert) {
assert.equal(proto.ipnsScheme, 'ipns', 'handler scheme');
exports['test ipfs: scheme'] = function(assert) {
assert.equal(ipfsHandler.scheme, 'ipfs', 'handler scheme');
};
exports['test ipns: scheme'] = function(assert) {
assert.equal(ipnsHandler.scheme, 'ipns', 'handler scheme');
};
exports['test fs: scheme'] = function(assert) {
assert.equal(fsHandler.scheme, 'fs', 'handler scheme');
};

exports['test fsScheme'] = function(assert) {
assert.equal(proto.fsScheme, 'fs', 'handler scheme');
exports['test web+ipfs scheme'] = function(assert) {
assert.equal(webIpfsHandler.scheme, 'web+ipfs', 'handler scheme');
};
exports['test web+ipns scheme'] = function(assert) {
assert.equal(webIpnsHandler.scheme, 'web+ipns', 'handler scheme');
};
exports['test web+fs scheme'] = function(assert) {
assert.equal(webFsHandler.scheme, 'web+fs', 'handler scheme');
};

// ipfs:<path> / ipns:<path> / ipfs://<path> / ipns://<path>
// should be converted to Public Gateway URL
// (which can be redirected to custom one in later steps)

exports['test newURI(ipfs:<path>)'] = function(assert) {
var newURI = proto.ipfsHandler.prototype.newURI('ipfs:' + ipfsPath, 'utf8', null);
var newURI = ipfsHandler.newURI('ipfs:' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};

exports['test newURI(ipfs://<path>)'] = function(assert) {
var newURI = proto.ipfsHandler.prototype.newURI('ipfs://' + ipfsPath, 'utf8', null);
var newURI = ipfsHandler.newURI('ipfs://' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};
exports['test newURI(web+ipfs:<path>)'] = function(assert) {
var newURI = webIpfsHandler.newURI('web+ipfs:' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};
exports['test newURI(web+ipfs://<path>)'] = function(assert) {
var newURI = webIpfsHandler.newURI('web+ipfs://' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};


exports['test newURI(ipns:<path>)'] = function(assert) {
var newURI = proto.ipnsHandler.prototype.newURI('ipns:' + ipnsPath, 'utf8', null);
var newURI = ipnsHandler.newURI('ipns:' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};

exports['test newURI(ipns:<path>)'] = function(assert) {
var newURI = proto.ipnsHandler.prototype.newURI('ipns://' + ipnsPath, 'utf8', null);
exports['test newURI(ipns://<path>)'] = function(assert) {
var newURI = ipnsHandler.newURI('ipns://' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};
exports['test newURI(web+ipns:<path>)'] = function(assert) {
var newURI = webIpnsHandler.newURI('web+ipns:' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};
exports['test newURI(web+ipns://<path>)'] = function(assert) {
var newURI = webIpnsHandler.newURI('web+ipns://' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};

Expand All @@ -46,44 +76,86 @@ exports['test newURI(ipns:<path>)'] = function(assert) {
// Discussed at length in https://github.com/ipfs/go-ipfs/issues/1678#issuecomment-142600157

exports['test newURI(fs:ipfs/<path>)'] = function(assert) {
var newURI = proto.fsHandler.prototype.newURI('fs:ipfs/' + ipfsPath, 'utf8', null);
var newURI = fsHandler.newURI('fs:ipfs/' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};

exports['test newURI(fs:/ipfs/<path>)'] = function(assert) {
var newURI = proto.fsHandler.prototype.newURI('fs:/ipfs/' + ipfsPath, 'utf8', null);
var newURI = fsHandler.newURI('fs:/ipfs/' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};

exports['test newURI(fs://ipfs/<path>)'] = function(assert) {
var newURI = proto.fsHandler.prototype.newURI('fs://ipfs/' + ipfsPath, 'utf8', null);
var newURI = fsHandler.newURI('fs://ipfs/' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};

exports['test newURI(fs:///ipfs/<path>)'] = function(assert) {
var newURI = proto.fsHandler.prototype.newURI('fs:///ipfs/' + ipfsPath, 'utf8', null);
var newURI = fsHandler.newURI('fs:///ipfs/' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};

exports['test newURI(fs:ipns/<path>)'] = function(assert) {
var newURI = proto.fsHandler.prototype.newURI('fs:ipns/' + ipnsPath, 'utf8', null);
var newURI = fsHandler.newURI('fs:ipns/' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};

exports['test newURI(fs:/ipns/<path>)'] = function(assert) {
var newURI = proto.fsHandler.prototype.newURI('fs:/ipns/' + ipnsPath, 'utf8', null);
var newURI = fsHandler.newURI('fs:/ipns/' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};

exports['test newURI(fs://ipns/<path>)'] = function(assert) {
var newURI = proto.fsHandler.prototype.newURI('fs://ipns/' + ipnsPath, 'utf8', null);
var newURI = fsHandler.newURI('fs://ipns/' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};

exports['test newURI(fs:///ipns/<path>)'] = function(assert) {
var newURI = proto.fsHandler.prototype.newURI('fs:///ipns/' + ipnsPath, 'utf8', null);
var newURI = fsHandler.newURI('fs:///ipns/' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};

// web+ variant (https://github.com/lidel/ipfs-firefox-addon/issues/36)
exports['test newURI(web+fs:ipfs/<path>)'] = function(assert) {
var newURI = webFsHandler.newURI('web+fs:ipfs/' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};

exports['test newURI(web+fs:/ipfs/<path>)'] = function(assert) {
var newURI = webFsHandler.newURI('web+fs:/ipfs/' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};

exports['test newURI(web+fs://ipfs/<path>)'] = function(assert) {
var newURI = webFsHandler.newURI('web+fs://ipfs/' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};

exports['test newURI(web+fs:///ipfs/<path>)'] = function(assert) {
var newURI = webFsHandler.newURI('web+fs:///ipfs/' + ipfsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipfs/' + ipfsPath, 'newURI spec');
};

exports['test newURI(web+fs:ipns/<path>)'] = function(assert) {
var newURI = webFsHandler.newURI('web+fs:ipns/' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};

exports['test newURI(web+fs:/ipns/<path>)'] = function(assert) {
var newURI = webFsHandler.newURI('web+fs:/ipns/' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};

exports['test newURI(web+fs://ipns/<path>)'] = function(assert) {
var newURI = webFsHandler.newURI('web+fs://ipns/' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};

exports['test newURI(web+fs:///ipns/<path>)'] = function(assert) {
var newURI = webFsHandler.newURI('web+fs:///ipns/' + ipnsPath, 'utf8', null);
assert.equal(newURI.spec, pubGwUri.spec + 'ipns/' + ipnsPath, 'newURI spec');
};



require('sdk/test').run(exports);

0 comments on commit 6187aa4

Please sign in to comment.