Skip to content
Snippets Groups Projects
Commit 2559457d authored by Thomas Rientjes's avatar Thomas Rientjes
Browse files

Refactor existing code

parent f1577855
No related branches found
No related tags found
No related merge requests found
......@@ -18,10 +18,7 @@
*/
var { Cc, Ci } = require('chrome');
var self = require('sdk/self');
var resourceData = self.data;
var version = self.version;
//noinspection JSUnresolvedFunction
var ioService = Cc['@mozilla.org/network/io-service;1']
......@@ -33,6 +30,18 @@ var ioService = Cc['@mozilla.org/network/io-service;1']
*/
var files = require('./files');
/**
* Constants
*/
const DELIVERY_NOTICE = '/**\n * Local delivery by Decentraleyes (' + self.version + ').\n */\n\n';
/**
* Variables
*/
var resourceData = self.data;
/**
* Public Methods
*/
......@@ -41,8 +50,8 @@ function getRedirectionURI(targetPath, characterSet, type) {
var data, dataURI, redirectionURI;
data = loadResource(targetPath);
dataURI = buildDataURI(type, characterSet, data);
data = _loadResource(targetPath);
dataURI = _buildDataURI(type, characterSet, data);
redirectionURI = ioService.newURI(dataURI, null, null);
return redirectionURI;
......@@ -58,39 +67,31 @@ exports.getRedirectionURI = getRedirectionURI;
* Private Methods
*/
function loadResource(targetPath) {
function _loadResource(targetPath) {
var resource;
// Find the result inside a static path index.
if (files.indexOf(targetPath) == -1) {
if (!files[targetPath]) {
throw 'The requested resource is missing.';
}
// Attempt to load resource contents.
try {
resource = resourceData.load(targetPath);
} catch (exception) {
throw exception;
}
return resource;
return resource = resourceData.load(targetPath);
}
function buildDataURI(type, characterSet, data) {
function _buildDataURI(type, characterSet, data) {
var addNotice, dataURI, notice;
var addNotice, dataURI;
//noinspection JSUnresolvedVariable
addNotice = require('sdk/simple-prefs').prefs.addNotice;
dataURI = 'data:' + type + ';charset=' + characterSet + ',';
notice = '/**\n * Local delivery by Decentraleyes (' + version + ').\n */\n\n';
if (!addNotice) {
dataURI = dataURI + encodeURIComponent(data);
} else {
dataURI = dataURI + encodeURIComponent(notice + data);
dataURI = dataURI + encodeURIComponent(DELIVERY_NOTICE + data);
}
return dataURI;
......
This diff is collapsed.
......@@ -48,6 +48,10 @@ var Interceptor = new Class({
observerService.removeObserver(this, this.topic);
},
/**
* Called whenever an HTTP request is made.
* @param httpChannel
*/
observe: function (httpChannel) {
var validCandidate, target, characterSet, redirectionURI;
......@@ -65,27 +69,21 @@ var Interceptor = new Class({
// Remove referer header from request.
httpChannel.setRequestHeader('Referer', null, false);
// Temporary fix for reported issues with the Play Store website.
// Temporary fix for reported issues with the Report URI website.
var requestDomain = null;
// Temporary fixes for reported edge-case issues with specific websites.
var initiatorDomain =
httpChannel.loadInfo && httpChannel.loadInfo.loadingDocument && httpChannel.loadInfo.loadingDocument.domain ||
httpChannel.referrer && httpChannel.referrer.host;
if (httpChannel.loadInfo && httpChannel.loadInfo.loadingDocument && httpChannel.loadInfo.loadingDocument.domain) {
requestDomain = httpChannel.loadInfo.loadingDocument.domain;
} else if (httpChannel.referrer && httpChannel.referrer.host) {
requestDomain = httpChannel.referrer.host;
}
if (requestDomain === 'play.google.com' || requestDomain === 'report-uri.io') {
this.handleMissingCandidate(httpChannel);
return;
if (initiatorDomain === 'play.google.com' || initiatorDomain === 'passport.twitch.tv' || initiatorDomain === 'report-uri.io'
|| initiatorDomain === 'minigames.mail.ru' || initiatorDomain === 'stefansundin.github.io') {
return this.handleMissingCandidate(httpChannel);
}
// Convert the original request URI to a local target.
target = requestAnalyzer.getLocalTarget(httpChannel.URI.host, httpChannel.URI.path);
if (!target) {
this.handleMissingCandidate(httpChannel);
return;
return this.handleMissingCandidate(httpChannel);
}
characterSet = httpChannel.URI.originCharset;
......@@ -94,8 +92,7 @@ var Interceptor = new Class({
try {
redirectionURI = dataHandler.getRedirectionURI(target.path, characterSet, target.type);
} catch (exception) {
this.handleMissingCandidate(httpChannel);
return;
return this.handleMissingCandidate(httpChannel);
}
httpChannel.redirectTo(redirectionURI);
......@@ -104,6 +101,10 @@ var Interceptor = new Class({
preferences.amountInjected++;
},
/**
* Called when a valid candidate cannot be injected.
* @param httpChannel
*/
handleMissingCandidate: function (httpChannel) {
//noinspection JSUnresolvedVariable
......
......@@ -17,172 +17,156 @@
* Imports
*/
var preferences = require('sdk/simple-prefs').prefs;
/**
* Resource version mappings.
* @var {object} mappings
*/
var mappings = require('./mappings');
/**
* Gets and sets add-on specific preferences.
* @var {object} simplePreferences
*/
var simplePreferences = require('sdk/simple-prefs');
/**
* Constants
*/
const MAPPING_FILE_EXPRESSION = new RegExp('.map$', 'i');
const VERSION_EXPRESSION = /(?:\d{1,2}\.){1,3}\d{1,2}/;
const VERSION_PLACEHOLDER = '{version}';
const WEB_PREFIX_VALUE = 'www.';
const WEB_PREFIX_LENGTH = WEB_PREFIX_VALUE.length;
const VALUE_SEPARATOR = ';';
/**
* Variables
*/
var whitelistedDomains = [];
var preferences = simplePreferences.prefs;
var whitelistedDomains = {};
/**
* Initializations
*/
applyWhitelistPreference();
_applyWhitelistPreference();
/**
* Event Handlers
*/
require('sdk/simple-prefs').on('domainWhitelist', applyWhitelistPreference);
simplePreferences.on('domainWhitelist', _applyWhitelistPreference);
/**
* Public Methods
*/
function isValidCandidate(httpChannel) {
exports.isValidCandidate = function (httpChannel) {
// See if the request is targeted at a Content Delivery Network.
if (mappings[httpChannel.URI.host] === undefined) {
return false;
}
var requestDomain = null;
if (httpChannel.loadInfo && httpChannel.loadInfo.loadingDocument && httpChannel.loadInfo.loadingDocument.domain) {
requestDomain = normalizeDomain(httpChannel.loadInfo.loadingDocument.domain);
} else if (httpChannel.referrer && httpChannel.referrer.host) {
requestDomain = normalizeDomain(httpChannel.referrer.host);
}
if (whitelistedDomains.length > 0 && requestDomain !== null) {
// Attempt to determine the domain of the request initiator.
var initiatorDomain =
httpChannel.loadInfo && httpChannel.loadInfo.loadingDocument && httpChannel.loadInfo.loadingDocument.domain ||
httpChannel.referrer && httpChannel.referrer.host;
for (let domain of whitelistedDomains) {
// If the request initiator could be determined and is whitelisted.
if (initiatorDomain && whitelistedDomains[_normalizeDomain(initiatorDomain)]) {
if (domain === requestDomain) {
// Remove referer header from request.
httpChannel.setRequestHeader('Referer', null, false);
return false;
}
}
// Remove referer header from request.
httpChannel.setRequestHeader('Referer', null, false);
return false;
}
// Only requests of type GET can be valid candidates.
return httpChannel.requestMethod === 'GET';
}
};
function getLocalTarget(channelHost, channelPath) {
exports.getLocalTarget = function (channelHost, channelPath) {
var basePath, hostMappings, resourceMappings, localTarget;
var hostMappings, basePath, resourceMappings;
// Use the proper mappings for the targeted host.
hostMappings = mappings[channelHost];
// Ignore mapping files.
if (channelPath.indexOf('.min.js.map') > -1) {
return false;
}
if (channelPath.indexOf('.min.map') > -1) {
return false;
}
basePath = matchBasePath(hostMappings, channelPath);
if (!basePath) {
// Resource mapping files are never locally available.
if (MAPPING_FILE_EXPRESSION.test(channelPath)) {
return false;
}
basePath = _matchBasePath(hostMappings, channelPath);
resourceMappings = hostMappings[basePath];
localTarget = matchResourcePath(resourceMappings, basePath, channelPath);
if (!localTarget) {
if (!resourceMappings) {
return false;
}
return localTarget;
}
/**
* Exports
*/
exports.isValidCandidate = isValidCandidate;
exports.getLocalTarget = getLocalTarget;
// Return either the local target's path or false.
return _findLocalTarget(resourceMappings, basePath, channelPath);
};
/**
* Private Methods
*/
function matchBasePath(hostMappings, channelPath) {
function _matchBasePath(hostMappings, channelPath) {
for (let basePath in hostMappings) {
for (let basePath of Object.keys(hostMappings)) {
if (hostMappings.hasOwnProperty(basePath)) {
if (channelPath.startsWith(basePath)) {
return basePath;
}
if (channelPath.startsWith(basePath)) {
return basePath;
}
}
return false;
}
function matchResourcePath(resourceMappings, basePath, channelPath) {
function _findLocalTarget(resourceMappings, basePath, channelPath) {
var resourcePath, versionNumber, resourcePattern;
resourcePath = channelPath.replace(basePath, '');
versionNumber = resourcePath.match(/(?:\d{1,2}\.){1,3}\d{1,2}/);
resourcePattern = resourcePath.replace(versionNumber, '{version}');
for (let resourceMold in resourceMappings) {
if (resourceMappings.hasOwnProperty(resourceMold)) {
if (resourcePattern.startsWith(resourceMold)) {
versionNumber = resourcePath.match(VERSION_EXPRESSION);
resourcePattern = resourcePath.replace(versionNumber, VERSION_PLACEHOLDER);
var localTarget = {
path: resourceMappings[resourceMold].path,
type: resourceMappings[resourceMold].type
};
for (let resourceMold of Object.keys(resourceMappings)) {
// Fill in the appropriate version number.
localTarget.path = localTarget.path.replace('{version}', versionNumber);
if (resourcePattern.startsWith(resourceMold)) {
return localTarget;
}
// Prepare and return a local target.
return {
path: resourceMappings[resourceMold].path.replace(VERSION_PLACEHOLDER, versionNumber),
type: resourceMappings[resourceMold].type
};
}
}
return false;
}
function normalizeDomain(domain) {
function _normalizeDomain(domain) {
domain = domain.toLowerCase().trim();
if (domain.startsWith('www.')) {
domain = domain.slice(4);
if (domain.startsWith(WEB_PREFIX_VALUE)) {
domain = domain.slice(WEB_PREFIX_LENGTH);
}
return domain;
}
function applyWhitelistPreference() {
function _applyWhitelistPreference() {
whitelistedDomains = [];
whitelistedDomains = {};
//noinspection JSUnresolvedVariable
preferences.domainWhitelist.split(';').forEach(function(domain, index) {
whitelistedDomains[index] = normalizeDomain(domain);
preferences.domainWhitelist.split(VALUE_SEPARATOR).forEach(function (domain) {
whitelistedDomains[_normalizeDomain(domain)] = true;
});
}
......@@ -11,6 +11,6 @@
"engines": {
"firefox": ">=38.0a1",
"fennec": ">=38.0a1",
"seamonkey": ">=2.0"
"seamonkey": ">=2.0a1"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment