]> WPIA git - gigi.git/blob - src/org/cacert/gigi/util/PublicSuffixes.java
upd: transform existing mails into mail templates
[gigi.git] / src / org / cacert / gigi / util / PublicSuffixes.java
1 package org.cacert.gigi.util;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import java.net.IDN;
7 import java.util.HashSet;
8
9 public class PublicSuffixes {
10
11     HashSet<String> suffixes = new HashSet<>();
12
13     HashSet<String> wildcards = new HashSet<>();
14
15     HashSet<String> exceptions = new HashSet<>();
16
17     private static final String url = "https://publicsuffix.org/list/effective_tld_names.dat";
18
19     private static PublicSuffixes instance;
20
21     private static PublicSuffixes generateDefault() throws IOException {
22         try (BufferedReader br = new BufferedReader(new InputStreamReader(PublicSuffixes.class.getResourceAsStream("effective_tld_names.dat"), "UTF-8"))) {
23             return new PublicSuffixes(br);
24         }
25     }
26
27     public synchronized static PublicSuffixes getInstance() {
28         if (instance == null) {
29             try {
30                 instance = generateDefault();
31             } catch (IOException e) {
32                 throw new Error(e);
33             }
34         }
35         return instance;
36     }
37
38     private PublicSuffixes(BufferedReader br) throws IOException {
39         String line;
40         while ((line = br.readLine()) != null) {
41             if (line.startsWith("//")) {
42                 continue;
43             }
44             if (line.isEmpty()) {
45                 continue;
46             }
47             String[] lineParts = line.split("\\s", 2);
48             if (lineParts.length == 0) {
49                 throw new Error("split had strange behavior");
50             }
51             line = lineParts[0];
52             if (line.startsWith("*.")) {
53                 String data = line.substring(2);
54                 if (data.contains("*") || data.contains("!")) {
55                     System.out.println("Error! unparsable public suffix line: " + line);
56                     continue;
57                 }
58                 addWildcard(IDN.toASCII(data));
59             } else if (line.startsWith("!")) {
60                 String data = line.substring(1);
61                 if (data.contains("*") || data.contains("!")) {
62                     System.out.println("Error! unparsable public suffix line: " + line);
63                     continue;
64                 }
65                 addException(IDN.toASCII(data));
66             } else {
67                 if (line.contains("*") || line.contains("!")) {
68                     System.out.println("Error! unparsable public suffix line: " + line);
69                     continue;
70                 }
71                 addSuffix(IDN.toASCII(line));
72             }
73         }
74     }
75
76     private void addWildcard(String data) {
77         wildcards.add(data);
78     }
79
80     private void addException(String data) {
81         exceptions.add(data);
82     }
83
84     private void addSuffix(String line) {
85         suffixes.add(line);
86     }
87
88     public String getRegistrablePart(String domain) {
89         if (domain == null) {
90             return null;
91         }
92         if (domain.startsWith(".")) {
93             return null;
94         }
95         if (isSuffix(domain) && !exceptions.contains(domain)) {
96             return null;
97         }
98         return getPublicSuffix0(domain);
99     }
100
101     private String getPublicSuffix0(String domain) {
102
103         int d = domain.indexOf('.');
104         if (d == -1) {
105             return null;
106         }
107         if (exceptions.contains(domain)) {
108             return domain;
109         }
110         String nextDomain = domain.substring(d + 1);
111         if (isSuffix(nextDomain)) {
112             return domain;
113         }
114
115         return getPublicSuffix0(nextDomain);
116     }
117
118     private boolean isSuffix(String domain) {
119         if (suffixes.contains(domain)) {
120             return true;
121         }
122         if (exceptions.contains(domain)) {
123             return false;
124         }
125         int idx = domain.indexOf('.');
126         if (idx != -1 && wildcards.contains(domain.substring(idx + 1))) {
127             return true;
128         }
129         return false;
130     }
131 }