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.http.impl.cookie;
28
29 import java.util.Map;
30 import java.util.concurrent.ConcurrentHashMap;
31
32 import org.apache.http.annotation.Contract;
33 import org.apache.http.annotation.ThreadingBehavior;
34 import org.apache.http.conn.util.PublicSuffixList;
35 import org.apache.http.conn.util.PublicSuffixMatcher;
36 import org.apache.http.cookie.CommonCookieAttributeHandler;
37 import org.apache.http.cookie.Cookie;
38 import org.apache.http.cookie.CookieOrigin;
39 import org.apache.http.cookie.MalformedCookieException;
40 import org.apache.http.cookie.SetCookie;
41 import org.apache.http.util.Args;
42
43
44
45
46
47
48
49
50
51
52
53
54 @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
55 public class PublicSuffixDomainFilter implements CommonCookieAttributeHandler {
56
57 private final CommonCookieAttributeHandler handler;
58 private final PublicSuffixMatcher publicSuffixMatcher;
59 private final Map<String, Boolean> localDomainMap;
60
61 private static Map<String, Boolean> createLocalDomainMap() {
62 final ConcurrentHashMap<String, Boolean> map = new ConcurrentHashMap<String, Boolean>();
63 map.put(".localhost.", Boolean.TRUE);
64 map.put(".test.", Boolean.TRUE);
65 map.put(".local.", Boolean.TRUE);
66 map.put(".local", Boolean.TRUE);
67 map.put(".localdomain", Boolean.TRUE);
68 return map;
69 }
70
71 public PublicSuffixDomainFilter(
72 final CommonCookieAttributeHandler handler, final PublicSuffixMatcher publicSuffixMatcher) {
73 this.handler = Args.notNull(handler, "Cookie handler");
74 this.publicSuffixMatcher = Args.notNull(publicSuffixMatcher, "Public suffix matcher");
75 this.localDomainMap = createLocalDomainMap();
76 }
77
78 public PublicSuffixDomainFilter(
79 final CommonCookieAttributeHandler handler, final PublicSuffixList suffixList) {
80 Args.notNull(handler, "Cookie handler");
81 Args.notNull(suffixList, "Public suffix list");
82 this.handler = handler;
83 this.publicSuffixMatcher = new PublicSuffixMatcher(suffixList.getRules(), suffixList.getExceptions());
84 this.localDomainMap = createLocalDomainMap();
85 }
86
87
88
89
90 @Override
91 public boolean match(final Cookie cookie, final CookieOrigin origin) {
92 final String host = cookie.getDomain();
93 if (host == null) {
94 return false;
95 }
96 final int i = host.indexOf('.');
97 if (i >= 0) {
98 final String domain = host.substring(i);
99 if (!this.localDomainMap.containsKey(domain)) {
100 if (this.publicSuffixMatcher.matches(host)) {
101 return false;
102 }
103 }
104 } else {
105 if (!host.equalsIgnoreCase(origin.getHost())) {
106 if (this.publicSuffixMatcher.matches(host)) {
107 return false;
108 }
109 }
110 }
111 return handler.match(cookie, origin);
112 }
113
114 @Override
115 public void parse(final SetCookie cookie, final String value) throws MalformedCookieException {
116 handler.parse(cookie, value);
117 }
118
119 @Override
120 public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException {
121 handler.validate(cookie, origin);
122 }
123
124 @Override
125 public String getAttributeName() {
126 return handler.getAttributeName();
127 }
128
129 public static CommonCookieAttributeHandler decorate(
130 final CommonCookieAttributeHandler handler, final PublicSuffixMatcher publicSuffixMatcher) {
131 Args.notNull(handler, "Cookie attribute handler");
132 return publicSuffixMatcher != null ? new PublicSuffixDomainFilter(handler, publicSuffixMatcher) : handler;
133 }
134
135 }