1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
"use strict";
(function(exports) {
var VERB = 1;
var DBUG = 2;
var INFO = 3;
var NOTE = 4;
var WARN = 5;
// FYI: Logging everything is /very/ slow. Chrome will log & buffer
// these console logs even when the debug tools are closed. :(
// TODO: Add an easy UI to change the log level.
// (Developers can just type DEFAULT_LOG_LEVEL=VERB in the console)
var DEFAULT_LOG_LEVEL = NOTE;
console.log("Hey developer! Want to see more verbose logging?");
console.log("Type this into the console: let util = require('./util'); util.setDefaultLogLevel(util.VERB);");
console.log("Accepted levels are VERB, DBUG, INFO, NOTE and WARN, default is NOTE");
function log(level, str) {
if (level >= DEFAULT_LOG_LEVEL) {
if (level === WARN) {
// Show warning with a little yellow icon in Chrome.
console.warn(str);
} else {
console.log(str);
}
}
}
function setDefaultLogLevel(level) {
DEFAULT_LOG_LEVEL = level;
}
function getDefaultLogLevel() {
return DEFAULT_LOG_LEVEL;
}
/**
* Load a file packaged with the extension
*
* @param url: a relative URL to local file
*/
function loadExtensionFile(url, returnType) {
var xhr = new XMLHttpRequest();
// Use blocking XHR to ensure everything is loaded by the time
// we return.
xhr.open("GET", chrome.runtime.getURL(url), false);
xhr.send(null);
// Get file contents
if (xhr.readyState !== 4) {
return;
}
if (returnType === 'xml') {
return xhr.responseXML;
}
if (returnType === 'json') {
return JSON.parse(xhr.responseText);
}
return xhr.responseText;
}
/**
* Remove tailing dots from hostname, e.g. "www.example.com."
* Preserve port numbers if they are used
*/
function getNormalisedHostname(host) {
let [ hostname, port ] = host.split(":");
while (hostname && hostname[hostname.length - 1] === '.' && hostname !== '.') {
hostname = hostname.slice(0, -1);
}
if (port) {
return `${hostname}:${port}`;
}
return hostname;
}
// Empty iterable singleton to reduce memory usage
const nullIterable = Object.create(null, {
[Symbol.iterator]: {
value: function* () {
// do nothing
}
},
size: {
value: 0
},
});
/**
* Return true if host is well-formed (RFC 1035)
*/
function isValidHostname(host) {
if (host && host.length > 0 && host.length <= 255 && host.indexOf("..") === -1) {
return true;
}
return false;
}
/**
* Return a list of wildcard expressions which support
* the host under HTTPS Everywhere's implementation
*/
function getWildcardExpressions(host) {
// Ensure host is well-formed (RFC 1035)
if (!isValidHostname(host)) {
return nullIterable;
}
// Ensure host does not contain a wildcard itself
if (host.indexOf("*") != -1) {
return nullIterable;
}
let results = [];
// Replace www.example.com with www.example.*
// eat away from the right for once and only once
let segmented = host.split(".");
if (segmented.length > 1) {
const tmp = [...segmented.slice(0, segmented.length - 1), "*"].join(".");
results.push(tmp);
}
// now eat away from the left, with *, so that for x.y.z.google.com we
// check *.y.z.google.com, *.z.google.com and *.google.com
for (let i = 1; i < segmented.length - 1; i++) {
const tmp = ["*", ...segmented.slice(i, segmented.length)].join(".");
results.push(tmp);
}
return results;
}
/**
* Convert an ArrayBuffer to string
*
* @param array: an ArrayBuffer to convert
*/
function ArrayBufferToString(ab) {
let array = new Uint8Array(ab);
let string = "";
for (let byte of array) {
string += String.fromCharCode(byte);
}
return string;
}
/**
* Convert a string to an ArrayBuffer
*
* @param string: a string to convert
*/
function StringToArrayBuffer(str) {
var byteArray = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
byteArray[i] = str.charCodeAt(i);
}
return byteArray;
}
Object.assign(exports, {
VERB,
DBUG,
INFO,
NOTE,
WARN,
log,
nullIterable,
isValidHostname,
getNormalisedHostname,
getWildcardExpressions,
setDefaultLogLevel,
getDefaultLogLevel,
loadExtensionFile,
ArrayBufferToString,
StringToArrayBuffer
});
})(typeof exports == 'undefined' ? require.scopes.util = {} : exports);
|