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.impl.cookie;
28
29 import java.util.Locale;
30
31 import org.apache.hc.client5.http.cookie.CommonCookieAttributeHandler;
32 import org.apache.hc.client5.http.cookie.Cookie;
33 import org.apache.hc.client5.http.cookie.CookieOrigin;
34 import org.apache.hc.client5.http.cookie.CookieRestrictionViolationException;
35 import org.apache.hc.client5.http.cookie.MalformedCookieException;
36 import org.apache.hc.client5.http.cookie.SetCookie;
37 import org.apache.hc.core5.annotation.Contract;
38 import org.apache.hc.core5.annotation.ThreadingBehavior;
39 import org.apache.hc.core5.net.InetAddressUtils;
40 import org.apache.hc.core5.util.Args;
41 import org.apache.hc.core5.util.TextUtils;
42
43
44
45
46
47
48 @Contract(threading = ThreadingBehavior.STATELESS)
49 public class BasicDomainHandler implements CommonCookieAttributeHandler {
50
51
52
53
54
55
56
57 public static final BasicDomainHandler INSTANCE = new BasicDomainHandler();
58
59 public BasicDomainHandler() {
60 super();
61 }
62
63 @Override
64 public void parse(final SetCookie cookie, final String value)
65 throws MalformedCookieException {
66 Args.notNull(cookie, "Cookie");
67 if (TextUtils.isBlank(value)) {
68 throw new MalformedCookieException("Blank or null value for domain attribute");
69 }
70
71 if (value.endsWith(".")) {
72 return;
73 }
74 String domain = value;
75 if (domain.startsWith(".")) {
76 domain = domain.substring(1);
77 }
78 domain = domain.toLowerCase(Locale.ROOT);
79 cookie.setDomain(domain);
80 }
81
82 @Override
83 public void validate(final Cookie cookie, final CookieOrigin origin)
84 throws MalformedCookieException {
85 Args.notNull(cookie, "Cookie");
86 Args.notNull(origin, "Cookie origin");
87
88
89
90
91
92 final String host = origin.getHost();
93 final String domain = cookie.getDomain();
94 if (domain == null) {
95 throw new CookieRestrictionViolationException("Cookie 'domain' may not be null");
96 }
97 if (!host.equals(domain) && !domainMatch(domain, host)) {
98 throw new CookieRestrictionViolationException(
99 "Illegal 'domain' attribute \"" + domain + "\". Domain of origin: \"" + host + "\"");
100 }
101 }
102
103 static boolean domainMatch(final String domain, final String host) {
104 if (InetAddressUtils.isIPv4(host) || InetAddressUtils.isIPv6(host)) {
105 return false;
106 }
107 final String normalizedDomain = domain.startsWith(".") ? domain.substring(1) : domain;
108 if (host.endsWith(normalizedDomain)) {
109 final int prefix = host.length() - normalizedDomain.length();
110
111 if (prefix == 0) {
112 return true;
113 }
114 return prefix > 1 && host.charAt(prefix - 1) == '.';
115 }
116 return false;
117 }
118
119 @Override
120 public boolean match(final Cookie cookie, final CookieOrigin origin) {
121 Args.notNull(cookie, "Cookie");
122 Args.notNull(origin, "Cookie origin");
123 final String host = origin.getHost();
124 String domain = cookie.getDomain();
125 if (domain == null) {
126 return false;
127 }
128 if (domain.startsWith(".")) {
129 domain = domain.substring(1);
130 }
131 domain = domain.toLowerCase(Locale.ROOT);
132 if (host.equals(domain)) {
133 return true;
134 }
135 if ((cookie.containsAttribute(Cookie.DOMAIN_ATTR))) {
136 return domainMatch(domain, host);
137 }
138 return false;
139 }
140
141 @Override
142 public String getAttributeName() {
143 return Cookie.DOMAIN_ATTR;
144 }
145
146 }