src/java.base/share/classes/sun/security/util/DomainName.java
author xuelei
Mon, 12 Aug 2019 21:36:29 -0700
changeset 57718 a93b7b28f644
parent 52902 e3398b2e1ab0
child 59024 b046ba510bbc
permissions -rw-r--r--
8226374: Restrict TLS signature schemes and named groups Reviewed-by: mullan
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50788
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
     1
/*
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
     2
 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
     4
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    10
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    15
 * accompanied this code).
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    16
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    20
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    23
 * questions.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    24
 */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    25
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    26
package sun.security.util;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    27
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    28
import java.io.BufferedReader;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    29
import java.io.File;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    30
import java.io.FileInputStream;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    31
import java.io.FileNotFoundException;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    32
import java.io.InputStream;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    33
import java.io.InputStreamReader;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    34
import java.io.IOException;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    35
import java.security.AccessController;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    36
import java.security.PrivilegedAction;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    37
import java.util.Arrays;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    38
import java.util.HashSet;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    39
import java.util.Iterator;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    40
import java.util.LinkedList;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    41
import java.util.List;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    42
import java.util.Map;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    43
import java.util.Set;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    44
import java.util.concurrent.ConcurrentHashMap;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    45
import java.util.zip.ZipEntry;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    46
import java.util.zip.ZipInputStream;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    47
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    48
import sun.security.ssl.SSLLogger;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    49
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    50
/**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    51
 * Allows public suffixes and registered domains to be determined from a
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    52
 * string that represents a target domain name. A database of known
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    53
 * registered suffixes is used to perform the determination.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    54
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    55
 * A public suffix is defined as the rightmost part of a domain name
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    56
 * that is not owned by an individual registrant. Examples of
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    57
 * public suffixes are:
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    58
 *      com
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    59
 *      edu
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    60
 *      co.uk
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    61
 *      k12.ak.us
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    62
 *      com.tw
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    63
 *      \u7db2\u8def.tw
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    64
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    65
 * Public suffixes effectively denote registration authorities.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    66
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    67
 * A registered domain is a public suffix preceded by one domain label
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    68
 * and a ".". Examples are:
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    69
 *      oracle.com
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    70
 *      mit.edu
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    71
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    72
 * The internal database is derived from the information maintained at
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    73
 * http://publicsuffix.org. The information is fixed for a particular
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    74
 * JDK installation, but may be updated in future releases or updates.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    75
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    76
 * Because of the large number of top-level domains (TLDs) and public
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    77
 * suffix rules, we only load the rules on demand -- from a Zip file
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    78
 * containing an entry for each TLD.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    79
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    80
 * As each entry is loaded, its data is stored permanently in a cache.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    81
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    82
 * The containment hierarchy for the data is shown below:
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    83
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    84
 * Rules --> contains all the rules for a particular TLD
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    85
 *    RuleSet --> contains all the rules that match 1 label
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    86
 *    RuleSet --> contains all the rules that match 2 labels
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    87
 *    RuleSet --> contains all the rules that match 3 labels
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    88
 *      :
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    89
 *    RuleSet --> contains all the rules that match N labels
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    90
 *      HashSet of rules, where each rule is an exception rule, a "normal"
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    91
 *      rule, a wildcard rule (rules that contain a wildcard prefix only),
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    92
 *      or a LinkedList of "other" rules
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    93
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    94
 * The general matching algorithm tries to find a longest match. So, the
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    95
 * search begins at the RuleSet with the most labels, and works backwards.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    96
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    97
 * Exceptions take priority over all other rules, and if a Rule contains
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    98
 * any exceptions, then even if we find a "normal" match, we search all
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
    99
 * other RuleSets for exceptions. It is assumed that all other rules don't
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   100
 * intersect/overlap. If this happens, a match will be returned, but not
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   101
 * necessarily the expected one. For a further explanation of the rules,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   102
 * see http://publicsuffix.org/list/.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   103
 *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   104
 * The "other" rules are for the (possible future) case where wildcards
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   105
 * are located in a rule any place other than the beginning.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   106
 */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   107
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   108
class DomainName {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   109
    /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   110
     * For efficiency, the set of rules for each TLD is kept
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   111
     * in text files and only loaded if needed.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   112
     */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   113
    private static final Map<String, Rules> cache = new ConcurrentHashMap<>();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   114
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   115
    private DomainName() {}
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   116
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   117
    /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   118
     * Returns the registered domain of the specified domain.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   119
     *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   120
     * @param domain the domain name
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   121
     * @return the registered domain, or null if not known or not registerable
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   122
     * @throws NullPointerException if domain is null
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   123
     */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   124
    public static RegisteredDomain registeredDomain(String domain) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   125
        Match match = getMatch(domain);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   126
        return (match != null) ? match.registeredDomain() : null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   127
    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   128
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   129
    private static Match getMatch(String domain) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   130
        if (domain == null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   131
            throw new NullPointerException();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   132
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   133
        Rules rules = Rules.getRules(domain);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   134
        return rules == null ? null : rules.match(domain);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   135
    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   136
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   137
    /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   138
     * A Rules object contains a list of rules for a particular TLD.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   139
     *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   140
     * Rules are stored in a linked list of RuleSet objects. The list is
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   141
     * indexed according to the number of labels in the name (minus one)
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   142
     * such that all rules with the same number of labels are stored
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   143
     * in the same RuleSet.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   144
     *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   145
     * Doing this means we can find the longest match first, and also we
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   146
     * can stop comparing as soon as we find a match.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   147
     */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   148
    private static class Rules {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   149
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   150
        private final LinkedList<RuleSet> ruleSets = new LinkedList<>();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   151
        private final boolean hasExceptions;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   152
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   153
        private Rules(InputStream is) throws IOException {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   154
            InputStreamReader isr = new InputStreamReader(is, "UTF-8");
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   155
            BufferedReader reader = new BufferedReader(isr);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   156
            boolean hasExceptions = false;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   157
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   158
            String line;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   159
            int type = reader.read();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   160
            while (type != -1 && (line = reader.readLine()) != null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   161
                int numLabels = RuleSet.numLabels(line);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   162
                if (numLabels != 0) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   163
                    RuleSet ruleset = getRuleSet(numLabels - 1);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   164
                    ruleset.addRule(type, line);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   165
                    hasExceptions |= ruleset.hasExceptions;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   166
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   167
                type = reader.read();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   168
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   169
            this.hasExceptions = hasExceptions;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   170
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   171
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   172
        static Rules getRules(String domain) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   173
            String tld = getTopLevelDomain(domain);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   174
            if (tld.isEmpty()) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   175
                return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   176
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   177
            return cache.computeIfAbsent(tld, k -> createRules(tld));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   178
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   179
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   180
        private static String getTopLevelDomain(String domain) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   181
            int n = domain.lastIndexOf('.');
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   182
            if (n == -1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   183
                return domain;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   184
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   185
            return domain.substring(n + 1);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   186
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   187
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   188
        private static Rules createRules(String tld) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   189
            try (InputStream pubSuffixStream = getPubSuffixStream()) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   190
                if (pubSuffixStream == null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   191
                    return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   192
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   193
                return getRules(tld, new ZipInputStream(pubSuffixStream));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   194
            } catch (IOException e) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   195
                if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   196
                    SSLLogger.fine(
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   197
                        "cannot parse public suffix data for " + tld +
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   198
                         ": " + e.getMessage());
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   199
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   200
                return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   201
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   202
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   203
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   204
        private static InputStream getPubSuffixStream() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   205
            InputStream is = AccessController.doPrivileged(
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   206
                new PrivilegedAction<>() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   207
                    @Override
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   208
                    public InputStream run() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   209
                        File f = new File(System.getProperty("java.home"),
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   210
                            "lib/security/public_suffix_list.dat");
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   211
                        try {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   212
                            return new FileInputStream(f);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   213
                        } catch (FileNotFoundException e) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   214
                            return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   215
                        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   216
                    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   217
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   218
            );
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   219
            if (is == null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   220
                if (SSLLogger.isOn && SSLLogger.isOn("ssl") &&
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   221
                        SSLLogger.isOn("trustmanager")) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   222
                    SSLLogger.fine(
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   223
                        "lib/security/public_suffix_list.dat not found");
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   224
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   225
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   226
            return is;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   227
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   228
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   229
        private static Rules getRules(String tld,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   230
                                      ZipInputStream zis) throws IOException {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   231
            boolean found = false;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   232
            ZipEntry ze = zis.getNextEntry();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   233
            while (ze != null && !found) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   234
                if (ze.getName().equals(tld)) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   235
                    found = true;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   236
                } else {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   237
                    ze = zis.getNextEntry();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   238
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   239
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   240
            if (!found) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   241
                if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   242
                    SSLLogger.fine("Domain " + tld + " not found");
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   243
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   244
                return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   245
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   246
            return new Rules(zis);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   247
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   248
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   249
        /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   250
         * Return the requested RuleSet. If it hasn't been created yet,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   251
         * create it and any RuleSets leading up to it.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   252
         */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   253
        private RuleSet getRuleSet(int index) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   254
            if (index < ruleSets.size()) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   255
                return ruleSets.get(index);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   256
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   257
            RuleSet r = null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   258
            for (int i = ruleSets.size(); i <= index; i++) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   259
                r = new RuleSet(i + 1);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   260
                ruleSets.add(r);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   261
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   262
            return r;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   263
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   264
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   265
        /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   266
         * Find a match for the target string.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   267
         */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   268
        Match match(String domain) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   269
            // Start at the end of the rules list, looking for longest match.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   270
            // After we find a normal match, we only look for exceptions.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   271
            Match possibleMatch = null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   272
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   273
            Iterator<RuleSet> it = ruleSets.descendingIterator();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   274
            while (it.hasNext()) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   275
                RuleSet ruleSet = it.next();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   276
                Match match = ruleSet.match(domain);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   277
                if (match != null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   278
                    if (match.type() == Rule.Type.EXCEPTION || !hasExceptions) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   279
                        return match;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   280
                    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   281
                    if (possibleMatch == null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   282
                        possibleMatch = match;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   283
                    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   284
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   285
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   286
            return possibleMatch;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   287
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   288
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   289
        /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   290
         * Represents a set of rules with the same number of labels
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   291
         * and for a particular TLD.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   292
         *
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   293
         * Examples:
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   294
         *      numLabels = 2
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   295
         *      names: co.uk, ac.uk
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   296
         *      wildcards *.de (only "de" stored in HashSet)
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   297
         *      exceptions: !foo.de (stored as "foo.de")
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   298
         */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   299
        private static class RuleSet {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   300
            // the number of labels in this ruleset
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   301
            private final int numLabels;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   302
            private final Set<Rule> rules = new HashSet<>();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   303
            boolean hasExceptions = false;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   304
            private static final RegisteredDomain.Type[] AUTHS =
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   305
                RegisteredDomain.Type.values();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   306
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   307
            RuleSet(int n) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   308
                numLabels = n;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   309
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   310
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   311
            void addRule(int auth, String rule) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   312
                if (rule.startsWith("!")) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   313
                    rules.add(new Rule(rule.substring(1), Rule.Type.EXCEPTION,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   314
                                       AUTHS[auth]));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   315
                    hasExceptions = true;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   316
                } else if (rule.startsWith("*.") &&
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   317
                           rule.lastIndexOf('*') == 0) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   318
                    rules.add(new Rule(rule.substring(2), Rule.Type.WILDCARD,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   319
                                       AUTHS[auth]));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   320
                } else if (rule.indexOf('*') == -1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   321
                    // a "normal" label
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   322
                    rules.add(new Rule(rule, Rule.Type.NORMAL, AUTHS[auth]));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   323
                } else {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   324
                    // There is a wildcard in a non-leading label. This case
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   325
                    // doesn't currently exist, but we need to handle it anyway.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   326
                    rules.add(new OtherRule(rule, AUTHS[auth], split(rule)));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   327
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   328
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   329
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   330
            Match match(String domain) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   331
                Match match = null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   332
                for (Rule rule : rules) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   333
                    switch (rule.type) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   334
                        case NORMAL:
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   335
                            if (match == null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   336
                                match = matchNormal(domain, rule);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   337
                            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   338
                            break;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   339
                        case WILDCARD:
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   340
                            if (match == null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   341
                                match = matchWildcard(domain, rule);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   342
                            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   343
                            break;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   344
                        case OTHER:
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   345
                            if (match == null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   346
                                match = matchOther(domain, rule);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   347
                            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   348
                            break;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   349
                        case EXCEPTION:
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   350
                            Match excMatch = matchException(domain, rule);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   351
                            if (excMatch != null) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   352
                                return excMatch;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   353
                            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   354
                            break;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   355
                    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   356
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   357
                return match;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   358
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   359
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   360
            private static LinkedList<String> split(String rule) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   361
                String[] labels = rule.split("\\.");
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   362
                return new LinkedList<>(Arrays.asList(labels));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   363
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   364
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   365
            private static int numLabels(String rule) {
52902
e3398b2e1ab0 8214971: Replace use of string.equals("") with isEmpty()
rriggs
parents: 50788
diff changeset
   366
                if (rule.isEmpty()) {
50788
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   367
                    return 0;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   368
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   369
                int len = rule.length();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   370
                int count = 0;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   371
                int index = 0;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   372
                while (index < len) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   373
                    int pos;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   374
                    if ((pos = rule.indexOf('.', index)) == -1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   375
                        return count + 1;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   376
                    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   377
                    index = pos + 1;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   378
                    count++;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   379
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   380
                return count;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   381
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   382
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   383
            /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   384
             * Check for a match with an explicit name rule or a wildcard rule
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   385
             * (i.e., a non-exception rule).
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   386
             */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   387
            private Match matchNormal(String domain, Rule rule) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   388
                int index = labels(domain, numLabels);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   389
                if (index == -1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   390
                    return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   391
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   392
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   393
                // Check for explicit names.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   394
                String substring = domain.substring(index);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   395
                if (rule.domain.equals(substring)) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   396
                    return new CommonMatch(domain, rule, index);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   397
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   398
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   399
                return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   400
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   401
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   402
            private Match matchWildcard(String domain, Rule rule) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   403
                // Now check for wildcards. In this case, there is one fewer
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   404
                // label than numLabels.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   405
                int index = labels(domain, numLabels - 1);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   406
                if (index > 0) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   407
                    String substring = domain.substring(index);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   408
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   409
                    if (rule.domain.equals(substring)) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   410
                        return new CommonMatch(domain, rule,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   411
                                               labels(domain, numLabels));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   412
                    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   413
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   414
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   415
                return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   416
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   417
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   418
            /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   419
             * Check for a match with an exception rule.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   420
             */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   421
            private Match matchException(String domain, Rule rule) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   422
                int index = labels(domain, numLabels);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   423
                if (index == -1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   424
                    return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   425
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   426
                String substring = domain.substring(index);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   427
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   428
                if (rule.domain.equals(substring)) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   429
                    return new CommonMatch(domain, rule,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   430
                                           labels(domain, numLabels - 1));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   431
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   432
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   433
                return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   434
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   435
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   436
            /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   437
             * A left-to-right comparison of labels.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   438
             * The simplest approach to doing match() would be to
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   439
             * use a descending iterator giving a right-to-left comparison.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   440
             * But, it's more efficient to do left-to-right compares
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   441
             * because the left most labels are the ones most likely to be
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   442
             * different. We just have to figure out which label to start at.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   443
             */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   444
            private Match matchOther(String domain, Rule rule) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   445
                OtherRule otherRule = (OtherRule)rule;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   446
                LinkedList<String> target = split(domain);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   447
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   448
                int diff = target.size() - numLabels;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   449
                if (diff < 0) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   450
                    return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   451
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   452
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   453
                boolean found = true;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   454
                for (int i = 0; i < numLabels; i++) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   455
                    String ruleLabel = otherRule.labels.get(i);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   456
                    String targetLabel = target.get(i + diff);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   457
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   458
                    if (ruleLabel.charAt(0) != '*' &&
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   459
                        !ruleLabel.equalsIgnoreCase(targetLabel)) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   460
                        found = false;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   461
                        break;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   462
                    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   463
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   464
                if (found) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   465
                    return new OtherMatch(rule, numLabels, target);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   466
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   467
                return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   468
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   469
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   470
            /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   471
             * Returns a substring (index) with the n right-most labels from s.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   472
             * Returns -1 if s does not have at least n labels, 0, if the
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   473
             * substring is s.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   474
             */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   475
            private static int labels(String s, int n) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   476
                if (n < 1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   477
                    return -1;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   478
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   479
                int index = s.length();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   480
                for (int i = 0; i < n; i++) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   481
                    int next = s.lastIndexOf('.', index);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   482
                    if (next == -1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   483
                        if (i == n - 1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   484
                            return 0;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   485
                        } else {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   486
                            return -1;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   487
                        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   488
                    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   489
                    index = next - 1;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   490
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   491
                return index + 2;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   492
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   493
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   494
    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   495
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   496
    private static class Rule {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   497
        enum Type { EXCEPTION, NORMAL, OTHER, WILDCARD }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   498
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   499
        String domain;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   500
        Type type;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   501
        RegisteredDomain.Type auth;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   502
        Rule(String domain, Type type, RegisteredDomain.Type auth) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   503
            this.domain = domain;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   504
            this.type = type;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   505
            this.auth = auth;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   506
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   507
    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   508
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   509
    private static class OtherRule extends Rule {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   510
        List<String> labels;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   511
        OtherRule(String domain, RegisteredDomain.Type auth,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   512
                  List<String> labels) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   513
            super(domain, Type.OTHER, auth);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   514
            this.labels = labels;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   515
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   516
    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   517
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   518
    /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   519
     * Represents a string's match with a rule in the public suffix list.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   520
     */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   521
    private interface Match {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   522
        RegisteredDomain registeredDomain();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   523
        Rule.Type type();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   524
    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   525
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   526
    private static class RegisteredDomainImpl implements RegisteredDomain {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   527
        private final String name;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   528
        private final Type type;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   529
        private final String publicSuffix;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   530
        RegisteredDomainImpl(String name, Type type, String publicSuffix) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   531
            this.name = name;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   532
            this.type = type;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   533
            this.publicSuffix = publicSuffix;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   534
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   535
        @Override
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   536
        public String name() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   537
            return name;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   538
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   539
        @Override
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   540
        public Type type() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   541
            return type;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   542
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   543
        @Override
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   544
        public String publicSuffix() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   545
            return publicSuffix;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   546
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   547
    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   548
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   549
    /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   550
     * Represents a match against a standard rule in the public suffix list.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   551
     * A standard rule is an explicit name, a wildcard rule with a wildcard
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   552
     * only in the leading label, or an exception rule.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   553
     */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   554
    private static class CommonMatch implements Match {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   555
        private String domain;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   556
        private int publicSuffix; // index to
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   557
        private int registeredDomain; // index to
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   558
        private final Rule rule;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   559
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   560
        CommonMatch(String domain, Rule rule, int publicSuffix) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   561
            this.domain = domain;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   562
            this.publicSuffix = publicSuffix;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   563
            this.rule = rule;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   564
            // now locate the previous label
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   565
            registeredDomain = domain.lastIndexOf('.', publicSuffix - 2);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   566
            if (registeredDomain == -1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   567
                registeredDomain = 0;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   568
            } else {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   569
                registeredDomain++;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   570
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   571
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   572
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   573
        @Override
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   574
        public RegisteredDomain registeredDomain() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   575
            if (publicSuffix == 0) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   576
                return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   577
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   578
            return new RegisteredDomainImpl(domain.substring(registeredDomain),
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   579
                                            rule.auth,
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   580
                                            domain.substring(publicSuffix));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   581
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   582
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   583
        @Override
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   584
        public Rule.Type type() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   585
            return rule.type;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   586
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   587
    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   588
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   589
    /**
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   590
     * Represents a non-match with {@code NO_MATCH} or a match against
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   591
     * a non-standard rule in the public suffix list. A non-standard rule
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   592
     * is a wildcard rule that includes wildcards in a label other than
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   593
     * the leading label. The public suffix list doesn't currently have
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   594
     * such rules.
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   595
     */
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   596
    private static class OtherMatch implements Match {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   597
        private final Rule rule;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   598
        private final int numLabels;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   599
        private final LinkedList<String> target;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   600
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   601
        OtherMatch(Rule rule, int numLabels, LinkedList<String> target) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   602
            this.rule = rule;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   603
            this.numLabels = numLabels;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   604
            this.target = target;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   605
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   606
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   607
        @Override
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   608
        public RegisteredDomain registeredDomain() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   609
            int nlabels = numLabels + 1;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   610
            if (nlabels > target.size()) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   611
                // special case when registered domain is same as pub suff
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   612
                return null;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   613
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   614
            return new RegisteredDomainImpl(getSuffixes(nlabels),
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   615
                                            rule.auth, getSuffixes(numLabels));
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   616
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   617
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   618
        @Override
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   619
        public Rule.Type type() {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   620
            return rule.type;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   621
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   622
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   623
        private String getSuffixes(int n) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   624
            Iterator<String> targetIter = target.descendingIterator();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   625
            StringBuilder sb = new StringBuilder();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   626
            while (n > 0 && targetIter.hasNext()) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   627
                String s = targetIter.next();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   628
                sb.insert(0, s);
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   629
                if (n > 1) {
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   630
                    sb.insert(0, '.');
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   631
                }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   632
                n--;
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   633
            }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   634
            return sb.toString();
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   635
        }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   636
    }
6274aee1f692 8201815: Use Mozilla Public Suffix List
weijun
parents:
diff changeset
   637
}