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 public BasicDomainHandler() {
52 super();
53 }
54
55 @Override
56 public void parse(final SetCookie cookie, final String value)
57 throws MalformedCookieException {
58 Args.notNull(cookie, "Cookie");
59 if (TextUtils.isBlank(value)) {
60 throw new MalformedCookieException("Blank or null value for domain attribute");
61 }
62
63 if (value.endsWith(".")) {
64 return;
65 }
66 String domain = value;
67 if (domain.startsWith(".")) {
68 domain = domain.substring(1);
69 }
70 domain = domain.toLowerCase(Locale.ROOT);
71 cookie.setDomain(domain);
72 }
73
74 @Override
75 public void validate(final Cookie cookie, final CookieOrigin origin)
76 throws MalformedCookieException {
77 Args.notNull(cookie, "Cookie");
78 Args.notNull(origin, "Cookie origin");
79
80
81
82
83
84 final String host = origin.getHost();
85 final String domain = cookie.getDomain();
86 if (domain == null) {
87 throw new CookieRestrictionViolationException("Cookie 'domain' may not be null");
88 }
89 if (!host.equals(domain) && !domainMatch(domain, host)) {
90 throw new CookieRestrictionViolationException(
91 "Illegal 'domain' attribute \"" + domain + "\". Domain of origin: \"" + host + "\"");
92 }
93 }
94
95 static boolean domainMatch(final String domain, final String host) {
96 if (InetAddressUtils.isIPv4Address(host) || InetAddressUtils.isIPv6Address(host)) {
97 return false;
98 }
99 final String normalizedDomain = domain.startsWith(".") ? domain.substring(1) : domain;
100 if (host.endsWith(normalizedDomain)) {
101 final int prefix = host.length() - normalizedDomain.length();
102
103 if (prefix == 0) {
104 return true;
105 }
106 return prefix > 1 && host.charAt(prefix - 1) == '.';
107 }
108 return false;
109 }
110
111 @Override
112 public boolean match(final Cookie cookie, final CookieOrigin origin) {
113 Args.notNull(cookie, "Cookie");
114 Args.notNull(origin, "Cookie origin");
115 final String host = origin.getHost();
116 String domain = cookie.getDomain();
117 if (domain == null) {
118 return false;
119 }
120 if (domain.startsWith(".")) {
121 domain = domain.substring(1);
122 }
123 domain = domain.toLowerCase(Locale.ROOT);
124 if (host.equals(domain)) {
125 return true;
126 }
127 if ((cookie.containsAttribute(Cookie.DOMAIN_ATTR))) {
128 return domainMatch(domain, host);
129 }
130 return false;
131 }
132
133 @Override
134 public String getAttributeName() {
135 return Cookie.DOMAIN_ATTR;
136 }
137
138 }