1 /* 2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965DomainAttributeHandler.java $ 3 * $Revision: 653041 $ 4 * $Date: 2008-05-03 03:39:28 -0700 (Sat, 03 May 2008) $ 5 * 6 * ==================================================================== 7 * Licensed to the Apache Software Foundation (ASF) under one 8 * or more contributor license agreements. See the NOTICE file 9 * distributed with this work for additional information 10 * regarding copyright ownership. The ASF licenses this file 11 * to you under the Apache License, Version 2.0 (the 12 * "License"); you may not use this file except in compliance 13 * with the License. You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, 18 * software distributed under the License is distributed on an 19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20 * KIND, either express or implied. See the License for the 21 * specific language governing permissions and limitations 22 * under the License. 23 * ==================================================================== 24 * 25 * This software consists of voluntary contributions made by many 26 * individuals on behalf of the Apache Software Foundation. For more 27 * information on the Apache Software Foundation, please see 28 * <http://www.apache.org/>. 29 * 30 */ 31 32 package org.apache.http.impl.cookie; 33 34 import java.util.Locale; 35 36 import org.apache.http.cookie.ClientCookie; 37 import org.apache.http.cookie.Cookie; 38 import org.apache.http.cookie.CookieAttributeHandler; 39 import org.apache.http.cookie.CookieOrigin; 40 import org.apache.http.cookie.MalformedCookieException; 41 import org.apache.http.cookie.SetCookie; 42 43 /** 44 * <tt>"Domain"</tt> cookie attribute handler for RFC 2965 cookie spec. 45 * 46 * @author jain.samit@gmail.com (Samit Jain) 47 * 48 * @since 3.1 49 * 50 * @deprecated Please use {@link java.net.URL#openConnection} instead. 51 * Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 52 * for further details. 53 */ 54 @Deprecated 55 public class RFC2965DomainAttributeHandler implements CookieAttributeHandler { 56 RFC2965DomainAttributeHandler()57 public RFC2965DomainAttributeHandler() { 58 super(); 59 } 60 61 /** 62 * Parse cookie domain attribute. 63 */ parse(final SetCookie cookie, String domain)64 public void parse(final SetCookie cookie, String domain) 65 throws MalformedCookieException { 66 if (cookie == null) { 67 throw new IllegalArgumentException("Cookie may not be null"); 68 } 69 if (domain == null) { 70 throw new MalformedCookieException( 71 "Missing value for domain attribute"); 72 } 73 if (domain.trim().length() == 0) { 74 throw new MalformedCookieException( 75 "Blank value for domain attribute"); 76 } 77 domain = domain.toLowerCase(Locale.ENGLISH); 78 if (!domain.startsWith(".")) { 79 // Per RFC 2965 section 3.2.2 80 // "... If an explicitly specified value does not start with 81 // a dot, the user agent supplies a leading dot ..." 82 // That effectively implies that the domain attribute 83 // MAY NOT be an IP address of a host name 84 domain = '.' + domain; 85 } 86 cookie.setDomain(domain); 87 } 88 89 /** 90 * Performs domain-match as defined by the RFC2965. 91 * <p> 92 * Host A's name domain-matches host B's if 93 * <ol> 94 * <ul>their host name strings string-compare equal; or</ul> 95 * <ul>A is a HDN string and has the form NB, where N is a non-empty 96 * name string, B has the form .B', and B' is a HDN string. (So, 97 * x.y.com domain-matches .Y.com but not Y.com.)</ul> 98 * </ol> 99 * 100 * @param host host name where cookie is received from or being sent to. 101 * @param domain The cookie domain attribute. 102 * @return true if the specified host matches the given domain. 103 */ domainMatch(String host, String domain)104 public boolean domainMatch(String host, String domain) { 105 boolean match = host.equals(domain) 106 || (domain.startsWith(".") && host.endsWith(domain)); 107 108 return match; 109 } 110 111 /** 112 * Validate cookie domain attribute. 113 */ validate(final Cookie cookie, final CookieOrigin origin)114 public void validate(final Cookie cookie, final CookieOrigin origin) 115 throws MalformedCookieException { 116 if (cookie == null) { 117 throw new IllegalArgumentException("Cookie may not be null"); 118 } 119 if (origin == null) { 120 throw new IllegalArgumentException("Cookie origin may not be null"); 121 } 122 String host = origin.getHost().toLowerCase(Locale.ENGLISH); 123 if (cookie.getDomain() == null) { 124 throw new MalformedCookieException("Invalid cookie state: " + 125 "domain not specified"); 126 } 127 String cookieDomain = cookie.getDomain().toLowerCase(Locale.ENGLISH); 128 129 if (cookie instanceof ClientCookie 130 && ((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) { 131 // Domain attribute must start with a dot 132 if (!cookieDomain.startsWith(".")) { 133 throw new MalformedCookieException("Domain attribute \"" + 134 cookie.getDomain() + "\" violates RFC 2109: domain must start with a dot"); 135 } 136 137 // Domain attribute must contain at least one embedded dot, 138 // or the value must be equal to .local. 139 int dotIndex = cookieDomain.indexOf('.', 1); 140 if (((dotIndex < 0) || (dotIndex == cookieDomain.length() - 1)) 141 && (!cookieDomain.equals(".local"))) { 142 throw new MalformedCookieException( 143 "Domain attribute \"" + cookie.getDomain() 144 + "\" violates RFC 2965: the value contains no embedded dots " 145 + "and the value is not .local"); 146 } 147 148 // The effective host name must domain-match domain attribute. 149 if (!domainMatch(host, cookieDomain)) { 150 throw new MalformedCookieException( 151 "Domain attribute \"" + cookie.getDomain() 152 + "\" violates RFC 2965: effective host name does not " 153 + "domain-match domain attribute."); 154 } 155 156 // effective host name minus domain must not contain any dots 157 String effectiveHostWithoutDomain = host.substring( 158 0, host.length() - cookieDomain.length()); 159 if (effectiveHostWithoutDomain.indexOf('.') != -1) { 160 throw new MalformedCookieException("Domain attribute \"" 161 + cookie.getDomain() + "\" violates RFC 2965: " 162 + "effective host minus domain may not contain any dots"); 163 } 164 } else { 165 // Domain was not specified in header. In this case, domain must 166 // string match request host (case-insensitive). 167 if (!cookie.getDomain().equals(host)) { 168 throw new MalformedCookieException("Illegal domain attribute: \"" 169 + cookie.getDomain() + "\"." 170 + "Domain of origin: \"" 171 + host + "\""); 172 } 173 } 174 } 175 176 /** 177 * Match cookie domain attribute. 178 */ match(final Cookie cookie, final CookieOrigin origin)179 public boolean match(final Cookie cookie, final CookieOrigin origin) { 180 if (cookie == null) { 181 throw new IllegalArgumentException("Cookie may not be null"); 182 } 183 if (origin == null) { 184 throw new IllegalArgumentException("Cookie origin may not be null"); 185 } 186 String host = origin.getHost().toLowerCase(Locale.ENGLISH); 187 String cookieDomain = cookie.getDomain(); 188 189 // The effective host name MUST domain-match the Domain 190 // attribute of the cookie. 191 if (!domainMatch(host, cookieDomain)) { 192 return false; 193 } 194 // effective host name minus domain must not contain any dots 195 String effectiveHostWithoutDomain = host.substring( 196 0, host.length() - cookieDomain.length()); 197 return effectiveHostWithoutDomain.indexOf('.') == -1; 198 } 199 200 }