Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81145 views
1
/*!
2
* Copyright (c) 2015, Salesforce.com, Inc.
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
7
*
8
* 1. Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
*
11
* 2. Redistributions in binary form must reproduce the above copyright notice,
12
* this list of conditions and the following disclaimer in the documentation
13
* and/or other materials provided with the distribution.
14
*
15
* 3. Neither the name of Salesforce.com nor the names of its contributors may
16
* be used to endorse or promote products derived from this software without
17
* specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
* POSSIBILITY OF SUCH DAMAGE.
30
*/
31
'use strict';
32
var fs = require('fs');
33
var assert = require('assert');
34
var punycode = require('punycode');
35
36
fs.readFile('./public-suffix.txt', 'utf8', function(err,string) {
37
if (err) {
38
throw err;
39
}
40
var lines = string.split("\n");
41
process.nextTick(function() {
42
processList(lines);
43
});
44
});
45
46
var index = {};
47
48
var COMMENT = new RegExp('//.+');
49
function processList(lines) {
50
while (lines.length) {
51
var line = lines.shift();
52
line = line.replace(COMMENT,'').trim();
53
if (!line) {
54
continue;
55
}
56
addToIndex(index,line);
57
}
58
59
pubSufTest();
60
61
var w = fs.createWriteStream('./lib/pubsuffix.js',{
62
flags: 'w',
63
encoding: 'utf8',
64
mode: parseInt('644',8)
65
});
66
w.on('end', process.exit);
67
w.write("/****************************************************\n");
68
w.write(" * AUTOMATICALLY GENERATED by generate-pubsuffix.js *\n");
69
w.write(" * DO NOT EDIT! *\n");
70
w.write(" ****************************************************/\n\n");
71
72
w.write('"use strict";\n\n');
73
w.write("var punycode = require('punycode');\n\n");
74
75
w.write("module.exports.getPublicSuffix = ");
76
w.write(getPublicSuffix.toString());
77
w.write(";\n\n");
78
79
w.write("// The following generated structure is used under the MPL version 1.1\n");
80
w.write("// See public-suffix.txt for more information\n\n");
81
w.write("var index = module.exports.index = Object.freeze(\n");
82
w.write(JSON.stringify(index));
83
w.write(");\n\n");
84
w.write("// END of automatically generated file\n");
85
86
w.end();
87
}
88
89
function addToIndex(index,line) {
90
var prefix = '';
91
if (line.replace(/^(!|\*\.)/)) {
92
prefix = RegExp.$1;
93
line = line.slice(prefix.length);
94
}
95
line = prefix + punycode.toASCII(line);
96
97
if (line.substr(0,1) == '!') {
98
index[line.substr(1)] = false;
99
} else {
100
index[line] = true;
101
}
102
}
103
104
// include the licence in the function since it gets written to pubsuffix.js
105
function getPublicSuffix(domain) {
106
/*!
107
* Copyright (c) 2015, Salesforce.com, Inc.
108
* All rights reserved.
109
*
110
* Redistribution and use in source and binary forms, with or without
111
* modification, are permitted provided that the following conditions are met:
112
*
113
* 1. Redistributions of source code must retain the above copyright notice,
114
* this list of conditions and the following disclaimer.
115
*
116
* 2. Redistributions in binary form must reproduce the above copyright notice,
117
* this list of conditions and the following disclaimer in the documentation
118
* and/or other materials provided with the distribution.
119
*
120
* 3. Neither the name of Salesforce.com nor the names of its contributors may
121
* be used to endorse or promote products derived from this software without
122
* specific prior written permission.
123
*
124
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
125
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
126
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
127
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
128
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
129
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
130
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
131
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
132
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
133
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
134
* POSSIBILITY OF SUCH DAMAGE.
135
*/
136
if (!domain) {
137
return null;
138
}
139
if (domain.match(/^\./)) {
140
return null;
141
}
142
var asciiDomain = punycode.toASCII(domain);
143
var converted = false;
144
if (asciiDomain !== domain) {
145
domain = asciiDomain;
146
converted = true;
147
}
148
if (index[domain]) {
149
return null;
150
}
151
152
domain = domain.toLowerCase();
153
var parts = domain.split('.').reverse();
154
155
var suffix = '';
156
var suffixLen = 0;
157
for (var i=0; i<parts.length; i++) {
158
var part = parts[i];
159
var starstr = '*'+suffix;
160
var partstr = part+suffix;
161
162
if (index[starstr]) { // star rule matches
163
suffixLen = i+1;
164
if (index[partstr] === false) { // exception rule matches (NB: false, not undefined)
165
suffixLen--;
166
}
167
} else if (index[partstr]) { // exact match, not exception
168
suffixLen = i+1;
169
}
170
171
suffix = '.'+partstr;
172
}
173
174
if (index['*'+suffix]) { // *.domain exists (e.g. *.kyoto.jp for domain='kyoto.jp');
175
return null;
176
}
177
178
suffixLen = suffixLen || 1;
179
if (parts.length > suffixLen) {
180
var publicSuffix = parts.slice(0,suffixLen+1).reverse().join('.');
181
return converted ? punycode.toUnicode(publicSuffix) : publicSuffix;
182
}
183
184
return null;
185
}
186
187
function checkPublicSuffix(give,get) {
188
var got = getPublicSuffix(give);
189
assert.equal(got, get, give+' should be '+(get==null?'NULL':get)+' but got '+got);
190
}
191
192
// pubSufTest() was converted to JavaScript from http://mxr.mozilla.org/mozilla-central/source/netwerk/test/unit/data/test_psl.txt?raw=1
193
function pubSufTest() {
194
// For this function-scope and this function-scope ONLY:
195
// Any copyright is dedicated to the Public Domain.
196
// http://creativecommons.org/publicdomain/zero/1.0/
197
198
// NULL input.
199
checkPublicSuffix(null, null);
200
// Mixed case.
201
checkPublicSuffix('COM', null);
202
checkPublicSuffix('example.COM', 'example.com');
203
checkPublicSuffix('WwW.example.COM', 'example.com');
204
// Leading dot.
205
checkPublicSuffix('.com', null);
206
checkPublicSuffix('.example', null);
207
checkPublicSuffix('.example.com', null);
208
checkPublicSuffix('.example.example', null);
209
// Unlisted TLD.
210
checkPublicSuffix('example', null);
211
checkPublicSuffix('example.example', 'example.example');
212
checkPublicSuffix('b.example.example', 'example.example');
213
checkPublicSuffix('a.b.example.example', 'example.example');
214
// Listed, but non-Internet, TLD.
215
//checkPublicSuffix('local', null);
216
//checkPublicSuffix('example.local', null);
217
//checkPublicSuffix('b.example.local', null);
218
//checkPublicSuffix('a.b.example.local', null);
219
// TLD with only 1 rule.
220
checkPublicSuffix('biz', null);
221
checkPublicSuffix('domain.biz', 'domain.biz');
222
checkPublicSuffix('b.domain.biz', 'domain.biz');
223
checkPublicSuffix('a.b.domain.biz', 'domain.biz');
224
// TLD with some 2-level rules.
225
checkPublicSuffix('com', null);
226
checkPublicSuffix('example.com', 'example.com');
227
checkPublicSuffix('b.example.com', 'example.com');
228
checkPublicSuffix('a.b.example.com', 'example.com');
229
checkPublicSuffix('uk.com', null);
230
checkPublicSuffix('example.uk.com', 'example.uk.com');
231
checkPublicSuffix('b.example.uk.com', 'example.uk.com');
232
checkPublicSuffix('a.b.example.uk.com', 'example.uk.com');
233
checkPublicSuffix('test.ac', 'test.ac');
234
// TLD with only 1 (wildcard) rule.
235
checkPublicSuffix('cy', null);
236
checkPublicSuffix('c.cy', null);
237
checkPublicSuffix('b.c.cy', 'b.c.cy');
238
checkPublicSuffix('a.b.c.cy', 'b.c.cy');
239
// More complex TLD.
240
checkPublicSuffix('jp', null);
241
checkPublicSuffix('test.jp', 'test.jp');
242
checkPublicSuffix('www.test.jp', 'test.jp');
243
checkPublicSuffix('ac.jp', null);
244
checkPublicSuffix('test.ac.jp', 'test.ac.jp');
245
checkPublicSuffix('www.test.ac.jp', 'test.ac.jp');
246
checkPublicSuffix('kyoto.jp', null);
247
checkPublicSuffix('test.kyoto.jp', 'test.kyoto.jp');
248
checkPublicSuffix('ide.kyoto.jp', null);
249
checkPublicSuffix('b.ide.kyoto.jp', 'b.ide.kyoto.jp');
250
checkPublicSuffix('a.b.ide.kyoto.jp', 'b.ide.kyoto.jp');
251
checkPublicSuffix('c.kobe.jp', null);
252
checkPublicSuffix('b.c.kobe.jp', 'b.c.kobe.jp');
253
checkPublicSuffix('a.b.c.kobe.jp', 'b.c.kobe.jp');
254
checkPublicSuffix('city.kobe.jp', 'city.kobe.jp');
255
checkPublicSuffix('www.city.kobe.jp', 'city.kobe.jp');
256
// TLD with a wildcard rule and exceptions.
257
checkPublicSuffix('ck', null);
258
checkPublicSuffix('test.ck', null);
259
checkPublicSuffix('b.test.ck', 'b.test.ck');
260
checkPublicSuffix('a.b.test.ck', 'b.test.ck');
261
checkPublicSuffix('www.ck', 'www.ck');
262
checkPublicSuffix('www.www.ck', 'www.ck');
263
// US K12.
264
checkPublicSuffix('us', null);
265
checkPublicSuffix('test.us', 'test.us');
266
checkPublicSuffix('www.test.us', 'test.us');
267
checkPublicSuffix('ak.us', null);
268
checkPublicSuffix('test.ak.us', 'test.ak.us');
269
checkPublicSuffix('www.test.ak.us', 'test.ak.us');
270
checkPublicSuffix('k12.ak.us', null);
271
checkPublicSuffix('test.k12.ak.us', 'test.k12.ak.us');
272
checkPublicSuffix('www.test.k12.ak.us', 'test.k12.ak.us');
273
// IDN labels.
274
checkPublicSuffix('食狮.com.cn', '食狮.com.cn');
275
checkPublicSuffix('食狮.公司.cn', '食狮.公司.cn');
276
checkPublicSuffix('www.食狮.公司.cn', '食狮.公司.cn');
277
checkPublicSuffix('shishi.公司.cn', 'shishi.公司.cn');
278
checkPublicSuffix('公司.cn', null);
279
checkPublicSuffix('食狮.中国', '食狮.中国');
280
checkPublicSuffix('www.食狮.中国', '食狮.中国');
281
checkPublicSuffix('shishi.中国', 'shishi.中国');
282
checkPublicSuffix('中国', null);
283
// Same as above, but punycoded.
284
checkPublicSuffix('xn--85x722f.com.cn', 'xn--85x722f.com.cn');
285
checkPublicSuffix('xn--85x722f.xn--55qx5d.cn', 'xn--85x722f.xn--55qx5d.cn');
286
checkPublicSuffix('www.xn--85x722f.xn--55qx5d.cn', 'xn--85x722f.xn--55qx5d.cn');
287
checkPublicSuffix('shishi.xn--55qx5d.cn', 'shishi.xn--55qx5d.cn');
288
checkPublicSuffix('xn--55qx5d.cn', null);
289
checkPublicSuffix('xn--85x722f.xn--fiqs8s', 'xn--85x722f.xn--fiqs8s');
290
checkPublicSuffix('www.xn--85x722f.xn--fiqs8s', 'xn--85x722f.xn--fiqs8s');
291
checkPublicSuffix('shishi.xn--fiqs8s', 'shishi.xn--fiqs8s');
292
checkPublicSuffix('xn--fiqs8s', null);
293
}
294
295