8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.webkit.network; 27 28 import java.io.BufferedReader; 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.io.InputStreamReader; 32 import java.net.IDN; 33 import java.util.Collections; 34 import java.util.LinkedHashMap; 35 import java.util.Map; 36 import java.util.logging.Level; 37 import java.util.logging.Logger; 38 39 /** 40 * A collection of static utility methods dealing with "public suffixes". 41 */ 42 final class PublicSuffixes { 43 44 private static final Logger logger = 45 Logger.getLogger(PublicSuffixes.class.getName()); 46 47 48 /** 49 * Public suffix list rule types. 50 */ 51 private enum Rule { 52 SIMPLE_RULE, 53 WILDCARD_RULE, 54 EXCEPTION_RULE, 55 } 56 57 58 /** 59 * The mapping from domain names to public suffix list rules. 60 */ 61 private static final Map<String,Rule> RULES = 62 loadRules("effective_tld_names.dat"); 63 64 65 /** 79 } 80 Rule rule = RULES.get(domain); 81 if (rule == Rule.EXCEPTION_RULE) { 82 return false; 83 } else if (rule == Rule.SIMPLE_RULE || rule == Rule.WILDCARD_RULE) { 84 return true; 85 } else { 86 int pos = domain.indexOf('.') + 1; 87 if (pos == 0) { 88 pos = domain.length(); 89 } 90 String parent = domain.substring(pos); 91 return RULES.get(parent) == Rule.WILDCARD_RULE; 92 } 93 } 94 95 /** 96 * Loads the public suffix list from a given resource. 97 */ 98 private static Map<String,Rule> loadRules(String resourceName) { 99 logger.log(Level.FINEST, "resourceName: [{0}]", resourceName); 100 Map<String,Rule> result = null; 101 102 InputStream is = PublicSuffixes.class.getResourceAsStream(resourceName); 103 if (is != null) { 104 BufferedReader reader = null; 105 try { 106 reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); 107 result = loadRules(reader); 108 } catch (IOException ex) { 109 logger.log(Level.WARNING, "Unexpected error", ex); 110 } finally { 111 try { 112 if (reader != null) { 113 reader.close(); 114 } 115 } catch (IOException ex) { 116 logger.log(Level.WARNING, "Unexpected error", ex); 117 } 118 } 119 } else { 120 logger.log(Level.WARNING, "Resource not found: [{0}]", 121 resourceName); 122 } 123 124 result = result != null 125 ? Collections.unmodifiableMap(result) 126 : Collections.<String,Rule>emptyMap(); 127 if (logger.isLoggable(Level.FINEST)) { 128 logger.log(Level.FINEST, "result: {0}", toLogString(result)); 129 } 130 return result; 131 } 132 133 /** 134 * Loads the public suffix list from a given reader. 135 */ 136 private static Map<String,Rule> loadRules(BufferedReader reader) 137 throws IOException 138 { 139 Map<String,Rule> result = new LinkedHashMap<String, Rule>(); 140 String line; 141 while ((line = reader.readLine()) != null) { 142 line = line.split("\\s+", 2)[0]; 143 if (line.length() == 0) { 144 continue; 145 } 146 if (line.startsWith("//")) { 147 continue; 148 } 149 Rule rule; 150 if (line.startsWith("!")) { 151 line = line.substring(1); 152 rule = Rule.EXCEPTION_RULE; 153 } else if (line.startsWith("*.")) { 154 line = line.substring(2); 155 rule = Rule.WILDCARD_RULE; 156 } else { 157 rule = Rule.SIMPLE_RULE; 158 } 159 try { 160 line = IDN.toASCII(line, IDN.ALLOW_UNASSIGNED); 161 } catch (Exception ex) { 162 logger.log(Level.WARNING, String.format( 163 "Error parsing rule: [%s]", line), ex); 164 continue; 165 } 166 result.put(line, rule); 167 } 168 return result; 169 } 170 171 /** 172 * Converts a map of rules to a string suitable for displaying 173 * in the log. 174 */ 175 private static String toLogString(Map<String,Rule> rules) { 176 if (rules.isEmpty()) { 177 return "{}"; 178 } 179 StringBuilder sb = new StringBuilder(); 180 for (Map.Entry<String,Rule> entry : rules.entrySet()) { 181 sb.append(String.format("%n ")); 182 sb.append(entry.getKey()); 183 sb.append(": "); | 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.webkit.network; 27 28 import com.sun.javafx.logging.PlatformLogger; 29 import com.sun.javafx.logging.PlatformLogger.Level; 30 31 import java.io.BufferedReader; 32 import java.io.IOException; 33 import java.io.InputStream; 34 import java.io.InputStreamReader; 35 import java.net.IDN; 36 import java.util.Collections; 37 import java.util.LinkedHashMap; 38 import java.util.Map; 39 40 /** 41 * A collection of static utility methods dealing with "public suffixes". 42 */ 43 final class PublicSuffixes { 44 45 private static final PlatformLogger logger = 46 PlatformLogger.getLogger(PublicSuffixes.class.getName()); 47 48 49 /** 50 * Public suffix list rule types. 51 */ 52 private enum Rule { 53 SIMPLE_RULE, 54 WILDCARD_RULE, 55 EXCEPTION_RULE, 56 } 57 58 59 /** 60 * The mapping from domain names to public suffix list rules. 61 */ 62 private static final Map<String,Rule> RULES = 63 loadRules("effective_tld_names.dat"); 64 65 66 /** 80 } 81 Rule rule = RULES.get(domain); 82 if (rule == Rule.EXCEPTION_RULE) { 83 return false; 84 } else if (rule == Rule.SIMPLE_RULE || rule == Rule.WILDCARD_RULE) { 85 return true; 86 } else { 87 int pos = domain.indexOf('.') + 1; 88 if (pos == 0) { 89 pos = domain.length(); 90 } 91 String parent = domain.substring(pos); 92 return RULES.get(parent) == Rule.WILDCARD_RULE; 93 } 94 } 95 96 /** 97 * Loads the public suffix list from a given resource. 98 */ 99 private static Map<String,Rule> loadRules(String resourceName) { 100 logger.finest("resourceName: [{0}]", resourceName); 101 Map<String,Rule> result = null; 102 103 InputStream is = PublicSuffixes.class.getResourceAsStream(resourceName); 104 if (is != null) { 105 BufferedReader reader = null; 106 try { 107 reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); 108 result = loadRules(reader); 109 } catch (IOException ex) { 110 logger.warning("Unexpected error", ex); 111 } finally { 112 try { 113 if (reader != null) { 114 reader.close(); 115 } 116 } catch (IOException ex) { 117 logger.warning("Unexpected error", ex); 118 } 119 } 120 } else { 121 logger.warning("Resource not found: [{0}]", 122 resourceName); 123 } 124 125 result = result != null 126 ? Collections.unmodifiableMap(result) 127 : Collections.<String,Rule>emptyMap(); 128 if (logger.isLoggable(Level.FINEST)) { 129 logger.finest("result: {0}", toLogString(result)); 130 } 131 return result; 132 } 133 134 /** 135 * Loads the public suffix list from a given reader. 136 */ 137 private static Map<String,Rule> loadRules(BufferedReader reader) 138 throws IOException 139 { 140 Map<String,Rule> result = new LinkedHashMap<String, Rule>(); 141 String line; 142 while ((line = reader.readLine()) != null) { 143 line = line.split("\\s+", 2)[0]; 144 if (line.length() == 0) { 145 continue; 146 } 147 if (line.startsWith("//")) { 148 continue; 149 } 150 Rule rule; 151 if (line.startsWith("!")) { 152 line = line.substring(1); 153 rule = Rule.EXCEPTION_RULE; 154 } else if (line.startsWith("*.")) { 155 line = line.substring(2); 156 rule = Rule.WILDCARD_RULE; 157 } else { 158 rule = Rule.SIMPLE_RULE; 159 } 160 try { 161 line = IDN.toASCII(line, IDN.ALLOW_UNASSIGNED); 162 } catch (Exception ex) { 163 logger.warning(String.format("Error parsing rule: [%s]", line), ex); 164 continue; 165 } 166 result.put(line, rule); 167 } 168 return result; 169 } 170 171 /** 172 * Converts a map of rules to a string suitable for displaying 173 * in the log. 174 */ 175 private static String toLogString(Map<String,Rule> rules) { 176 if (rules.isEmpty()) { 177 return "{}"; 178 } 179 StringBuilder sb = new StringBuilder(); 180 for (Map.Entry<String,Rule> entry : rules.entrySet()) { 181 sb.append(String.format("%n ")); 182 sb.append(entry.getKey()); 183 sb.append(": "); |