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.Locale;
30
31 import org.apache.http.annotation.Contract;
32 import org.apache.http.annotation.ThreadingBehavior;
33 import org.apache.http.conn.util.InetAddressUtils;
34 import org.apache.http.cookie.ClientCookie;
35 import org.apache.http.cookie.CommonCookieAttributeHandler;
36 import org.apache.http.cookie.Cookie;
37 import org.apache.http.cookie.CookieOrigin;
38 import org.apache.http.cookie.CookieRestrictionViolationException;
39 import org.apache.http.cookie.MalformedCookieException;
40 import org.apache.http.cookie.SetCookie;
41 import org.apache.http.util.Args;
42 import org.apache.http.util.TextUtils;
43
44
45
46
47
48 @Contract(threading = ThreadingBehavior.IMMUTABLE)
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 if (prefix > 1 && host.charAt(prefix - 1) == '.') {
107 return true;
108 }
109 }
110 return false;
111 }
112
113 @Override
114 public boolean match(final Cookie cookie, final CookieOrigin origin) {
115 Args.notNull(cookie, "Cookie");
116 Args.notNull(origin, "Cookie origin");
117 final String host = origin.getHost();
118 String domain = cookie.getDomain();
119 if (domain == null) {
120 return false;
121 }
122 if (domain.startsWith(".")) {
123 domain = domain.substring(1);
124 }
125 domain = domain.toLowerCase(Locale.ROOT);
126 if (host.equals(domain)) {
127 return true;
128 }
129 if (cookie instanceof ClientCookie) {
130 if (((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) {
131 return domainMatch(domain, host);
132 }
133 }
134 return false;
135 }
136
137 @Override
138 public String getAttributeName() {
139 return ClientCookie.DOMAIN_ATTR;
140 }
141
142 }