1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.client5.http.psl;
28
29 import java.io.BufferedReader;
30 import java.io.IOException;
31 import java.io.Reader;
32 import java.util.ArrayList;
33 import java.util.List;
34
35 import org.apache.hc.core5.annotation.Contract;
36 import org.apache.hc.core5.annotation.ThreadingBehavior;
37
38
39
40
41
42
43
44 @Contract(threading = ThreadingBehavior.STATELESS)
45 public final class PublicSuffixListParser {
46
47
48
49
50
51
52 public static final PublicSuffixListParser INSTANCE = new PublicSuffixListParser();
53
54 public PublicSuffixListParser() {
55 }
56
57
58
59
60
61
62
63
64
65
66 public PublicSuffixList parse(final Reader reader) throws IOException {
67 final List<String> rules = new ArrayList<>();
68 final List<String> exceptions = new ArrayList<>();
69 final BufferedReader r = new BufferedReader(reader);
70
71 String line;
72 while ((line = r.readLine()) != null) {
73 if (line.isEmpty()) {
74 continue;
75 }
76 if (line.startsWith("//")) {
77 continue;
78 }
79 if (line.startsWith(".")) {
80 line = line.substring(1);
81 }
82
83 final boolean isException = line.startsWith("!");
84 if (isException) {
85 line = line.substring(1);
86 }
87
88 if (isException) {
89 exceptions.add(line);
90 } else {
91 rules.add(line);
92 }
93 }
94 return new PublicSuffixList(DomainType.UNKNOWN, rules, exceptions);
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108 public List<PublicSuffixList> parseByType(final Reader reader) throws IOException {
109 final List<PublicSuffixList> result = new ArrayList<>(2);
110
111 final BufferedReader r = new BufferedReader(reader);
112
113 DomainType domainType = null;
114 List<String> rules = null;
115 List<String> exceptions = null;
116 String line;
117 while ((line = r.readLine()) != null) {
118 if (line.isEmpty()) {
119 continue;
120 }
121 if (line.startsWith("//")) {
122
123 if (domainType == null) {
124 if (line.contains("===BEGIN ICANN DOMAINS===")) {
125 domainType = DomainType.ICANN;
126 } else if (line.contains("===BEGIN PRIVATE DOMAINS===")) {
127 domainType = DomainType.PRIVATE;
128 }
129 } else {
130 if (line.contains("===END ICANN DOMAINS===") || line.contains("===END PRIVATE DOMAINS===")) {
131 if (rules != null) {
132 result.add(new PublicSuffixList(domainType, rules, exceptions));
133 }
134 domainType = null;
135 rules = null;
136 exceptions = null;
137 }
138 }
139
140 continue;
141 }
142 if (domainType == null) {
143 continue;
144 }
145
146 if (line.startsWith(".")) {
147 line = line.substring(1);
148 }
149
150 final boolean isException = line.startsWith("!");
151 if (isException) {
152 line = line.substring(1);
153 }
154
155 if (isException) {
156 if (exceptions == null) {
157 exceptions = new ArrayList<>();
158 }
159 exceptions.add(line);
160 } else {
161 if (rules == null) {
162 rules = new ArrayList<>();
163 }
164 rules.add(line);
165 }
166 }
167 return result;
168 }
169
170 }