1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 package org.mozilla.gecko.util.publicsuffix;
6 
7 import android.content.Context;
8 import android.util.Log;
9 
10 import org.mozilla.gecko.util.IOUtils;
11 
12 import java.io.BufferedInputStream;
13 import java.io.BufferedReader;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.io.InputStreamReader;
17 import java.util.HashSet;
18 import java.util.Set;
19 
20 class PublicSuffixPatterns {
21     /** If a hostname is contained as a key in this map, it is a public suffix. */
22     private static Set<String> EXACT = null;
23 
getExactSet(Context context)24     static synchronized Set<String> getExactSet(Context context) {
25         if (EXACT != null) {
26             return EXACT;
27         }
28 
29         EXACT = new HashSet<>();
30 
31         BufferedReader reader = null;
32         try {
33             reader = new BufferedReader(new InputStreamReader(
34                     new BufferedInputStream(context.getAssets().open("publicsuffixlist"))));
35 
36             String line;
37             while ((line = reader.readLine()) != null) {
38                 EXACT.add(line);
39             }
40 
41         } catch (IOException e) {
42             throw new IllegalStateException("resource publicsuffixlist could not be opened but is bundled with app", e);
43         } finally {
44             IOUtils.safeStreamClose(reader);
45         }
46 
47         return EXACT;
48     }
49 
50 
51     /**
52      * If a hostname is not a key in the EXCLUDE map, and if removing its
53      * leftmost component results in a name which is a key in this map, it is a
54      * public suffix.
55      */
56     static final Set<String> UNDER = new HashSet<>();
57     static {
58         UNDER.add("bd");
59         UNDER.add("magentosite.cloud");
60         UNDER.add("ke");
61         UNDER.add("triton.zone");
62         UNDER.add("compute.estate");
63         UNDER.add("ye");
64         UNDER.add("pg");
65         UNDER.add("kh");
66         UNDER.add("platform.sh");
67         UNDER.add("fj");
68         UNDER.add("ck");
69         UNDER.add("fk");
70         UNDER.add("alces.network");
71         UNDER.add("sch.uk");
72         UNDER.add("jm");
73         UNDER.add("mm");
74         UNDER.add("api.githubcloud.com");
75         UNDER.add("ext.githubcloud.com");
76         UNDER.add("0emm.com");
77         UNDER.add("githubcloudusercontent.com");
78         UNDER.add("cns.joyent.com");
79         UNDER.add("bn");
80         UNDER.add("yokohama.jp");
81         UNDER.add("nagoya.jp");
82         UNDER.add("kobe.jp");
83         UNDER.add("sendai.jp");
84         UNDER.add("kawasaki.jp");
85         UNDER.add("sapporo.jp");
86         UNDER.add("kitakyushu.jp");
87         UNDER.add("np");
88         UNDER.add("nom.br");
89         UNDER.add("er");
90         UNDER.add("cryptonomic.net");
91         UNDER.add("gu");
92         UNDER.add("kw");
93         UNDER.add("zw");
94         UNDER.add("mz");
95     }
96 
97     /**
98      * The elements in this map would pass the UNDER test, but are known not to
99      * be public suffixes and are thus excluded from consideration. Since it
100      * refers to elements in UNDER of the same type, the type is actually not
101      * important here. The map is simply used for consistency reasons.
102      */
103     static final Set<String> EXCLUDED = new HashSet<>();
104     static {
105         EXCLUDED.add("www.ck");
106         EXCLUDED.add("city.yokohama.jp");
107         EXCLUDED.add("city.nagoya.jp");
108         EXCLUDED.add("city.kobe.jp");
109         EXCLUDED.add("city.sendai.jp");
110         EXCLUDED.add("city.kawasaki.jp");
111         EXCLUDED.add("city.sapporo.jp");
112         EXCLUDED.add("city.kitakyushu.jp");
113         EXCLUDED.add("teledata.mz");
114     }
115 }
116