1 package org.cacert.gigi.util;
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
7 import java.util.HashSet;
9 public class PublicSuffixes {
11 HashSet<String> suffixes = new HashSet<>();
13 HashSet<String> wildcards = new HashSet<>();
15 HashSet<String> exceptions = new HashSet<>();
17 private static final String url = "https://publicsuffix.org/list/effective_tld_names.dat";
19 private static PublicSuffixes instance;
21 private static void generateDefault() throws IOException {
22 try (BufferedReader br = new BufferedReader(new InputStreamReader(PublicSuffixes.class.getResourceAsStream("effective_tld_names.dat"), "UTF-8"))) {
23 instance = new PublicSuffixes(br);
27 public static PublicSuffixes getInstance() {
28 if (instance == null) {
31 } catch (IOException e) {
38 private PublicSuffixes(BufferedReader br) throws IOException {
40 while ((line = br.readLine()) != null) {
41 if (line.startsWith("//")) {
47 line = line.split("\\s", 2)[0];
48 if (line.startsWith("*.")) {
49 String data = line.substring(2);
50 if (data.contains("*") || data.contains("!")) {
51 System.out.println("Error! unparsable public suffix line: " + line);
54 addWildcard(IDN.toASCII(data));
55 } else if (line.startsWith("!")) {
56 String data = line.substring(1);
57 if (data.contains("*") || data.contains("!")) {
58 System.out.println("Error! unparsable public suffix line: " + line);
61 addException(IDN.toASCII(data));
63 if (line.contains("*") || line.contains("!")) {
64 System.out.println("Error! unparsable public suffix line: " + line);
67 addSuffix(IDN.toASCII(line));
72 private void addWildcard(String data) {
76 private void addException(String data) {
80 private void addSuffix(String line) {
84 public String getRegistrablePart(String domain) {
88 if (domain.startsWith(".")) {
91 if (isSuffix(domain) && !exceptions.contains(domain)) {
94 return getPublicSuffix0(domain);
97 private String getPublicSuffix0(String domain) {
99 int d = domain.indexOf('.');
103 if (exceptions.contains(domain)) {
106 String nextDomain = domain.substring(d + 1);
107 if (isSuffix(nextDomain)) {
111 return getPublicSuffix0(nextDomain);
114 private boolean isSuffix(String domain) {
115 if (suffixes.contains(domain)) {
118 if (exceptions.contains(domain)) {
121 int idx = domain.indexOf('.');
122 if (idx != -1 && wildcards.contains(domain.substring(idx + 1))) {