Newer
Older
/**
* Request Analyzer
* Belongs to Decentraleyes.
*
* @author Thomas Rientjes
* @since 2014-05-30
* @license MPL 2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
'use strict';
/**
* Imports
*/
/**
* Resource version mappings.
* @var {object} 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 = ';';
var preferences = simplePreferences.prefs;
var whitelistedDomains = {};
simplePreferences.on('domainWhitelist', _applyWhitelistPreference);
exports.isValidCandidate = function (httpChannel) {
// See if the request is targeted at a Content Delivery Network.
if (mappings[httpChannel.URI.host] === undefined) {
return false;
}
// 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;
// If the request initiator could be determined and is whitelisted.
if (initiatorDomain && whitelistedDomains[_normalizeDomain(initiatorDomain)]) {
// 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';
exports.getLocalTarget = function (channelHost, channelPath) {
// Use the proper mappings for the targeted host.
hostMappings = mappings[channelHost];
// Resource mapping files are never locally available.
if (MAPPING_FILE_EXPRESSION.test(channelPath)) {
basePath = _matchBasePath(hostMappings, channelPath);
resourceMappings = hostMappings[basePath];
// Return either the local target's path or false.
return _findLocalTarget(resourceMappings, basePath, channelPath);
};
function _matchBasePath(hostMappings, channelPath) {
for (let basePath of Object.keys(hostMappings)) {
if (channelPath.startsWith(basePath)) {
return basePath;
function _findLocalTarget(resourceMappings, basePath, channelPath) {
var resourcePath, versionNumber, resourcePattern;
resourcePath = channelPath.replace(basePath, '');
versionNumber = resourcePath.match(VERSION_EXPRESSION);
resourcePattern = resourcePath.replace(versionNumber, VERSION_PLACEHOLDER);
for (let resourceMold of Object.keys(resourceMappings)) {
if (resourcePattern.startsWith(resourceMold)) {
// Prepare and return a local target.
return {
path: resourceMappings[resourceMold].path.replace(VERSION_PLACEHOLDER, versionNumber),
type: resourceMappings[resourceMold].type
};
domain = domain.toLowerCase().trim();
if (domain.startsWith(WEB_PREFIX_VALUE)) {
domain = domain.slice(WEB_PREFIX_LENGTH);
preferences.domainWhitelist.split(VALUE_SEPARATOR).forEach(function (domain) {
whitelistedDomains[_normalizeDomain(domain)] = true;