/*
 * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/cookie/RFC2109Spec.java,v 1.21 2004/06/05 16:49:20 olegk Exp $
 * $Revision: 507134 $
 * $Date: 2007-02-13 19:18:05 +0100 (Tue, 13 Feb 2007) $
 * 
 * ====================================================================
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package org.apache.commons.httpclient.cookie;

import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.util.ParameterFormatter;

RFC 2109 specific cookie management functions

Author: B.C. Holmes, Park, Sung-Gu, Doug Sale, Rod Waldhoff, dIon Gillard, Sean C. Sullivan, John Evans, Marc A. Saegesser, Oleg Kalnichevski, Mike Bowler
Since:2.0
/** * <p>RFC 2109 specific cookie management functions * * @author B.C. Holmes * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a> * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a> * @author Rod Waldhoff * @author dIon Gillard * @author Sean C. Sullivan * @author <a href="mailto:JEvans@Cyveillance.com">John Evans</a> * @author Marc A. Saegesser * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> * * @since 2.0 */
public class RFC2109Spec extends CookieSpecBase { private final ParameterFormatter formatter;
Cookie Response Header name for cookies processed by this spec.
/** * Cookie Response Header name for cookies processed * by this spec. */
public final static String SET_COOKIE_KEY = "set-cookie";
Default constructor
/** Default constructor */
public RFC2109Spec() { super(); this.formatter = new ParameterFormatter(); this.formatter.setAlwaysUseQuotes(true); }
Parse RFC 2109 specific cookie attribute and update the corresponsing Cookie properties.
Params:
  • attribute – NameValuePair cookie attribute from the Set- Cookie
  • cookie – Cookie to be updated
Throws:
/** * Parse RFC 2109 specific cookie attribute and update the corresponsing * {@link Cookie} properties. * * @param attribute {@link NameValuePair} cookie attribute from the * <tt>Set- Cookie</tt> * @param cookie {@link Cookie} to be updated * @throws MalformedCookieException if an exception occurs during parsing */
public void parseAttribute( final NameValuePair attribute, final Cookie cookie) throws MalformedCookieException { if (attribute == null) { throw new IllegalArgumentException("Attribute may not be null."); } if (cookie == null) { throw new IllegalArgumentException("Cookie may not be null."); } final String paramName = attribute.getName().toLowerCase(); final String paramValue = attribute.getValue(); if (paramName.equals("path")) { if (paramValue == null) { throw new MalformedCookieException( "Missing value for path attribute"); } if (paramValue.trim().equals("")) { throw new MalformedCookieException( "Blank value for path attribute"); } cookie.setPath(paramValue); cookie.setPathAttributeSpecified(true); } else if (paramName.equals("version")) { if (paramValue == null) { throw new MalformedCookieException( "Missing value for version attribute"); } try { cookie.setVersion(Integer.parseInt(paramValue)); } catch (NumberFormatException e) { throw new MalformedCookieException("Invalid version: " + e.getMessage()); } } else { super.parseAttribute(attribute, cookie); } }
Performs RFC 2109 compliant Cookie validation
Params:
  • host – the host from which the Cookie was received
  • port – the port from which the Cookie was received
  • path – the path from which the Cookie was received
  • secure – true when the Cookie was received using a secure connection
  • cookie – The cookie to validate
Throws:
/** * Performs RFC 2109 compliant {@link Cookie} validation * * @param host the host from which the {@link Cookie} was received * @param port the port from which the {@link Cookie} was received * @param path the path from which the {@link Cookie} was received * @param secure <tt>true</tt> when the {@link Cookie} was received using a * secure connection * @param cookie The cookie to validate * @throws MalformedCookieException if an exception occurs during * validation */
public void validate(String host, int port, String path, boolean secure, final Cookie cookie) throws MalformedCookieException { LOG.trace("enter RFC2109Spec.validate(String, int, String, " + "boolean, Cookie)"); // Perform generic validation super.validate(host, port, path, secure, cookie); // Perform RFC 2109 specific validation if (cookie.getName().indexOf(' ') != -1) { throw new MalformedCookieException("Cookie name may not contain blanks"); } if (cookie.getName().startsWith("$")) { throw new MalformedCookieException("Cookie name may not start with $"); } if (cookie.isDomainAttributeSpecified() && (!cookie.getDomain().equals(host))) { // domain must start with dot if (!cookie.getDomain().startsWith(".")) { throw new MalformedCookieException("Domain attribute \"" + cookie.getDomain() + "\" violates RFC 2109: domain must start with a dot"); } // domain must have at least one embedded dot int dotIndex = cookie.getDomain().indexOf('.', 1); if (dotIndex < 0 || dotIndex == cookie.getDomain().length() - 1) { throw new MalformedCookieException("Domain attribute \"" + cookie.getDomain() + "\" violates RFC 2109: domain must contain an embedded dot"); } host = host.toLowerCase(); if (!host.endsWith(cookie.getDomain())) { throw new MalformedCookieException( "Illegal domain attribute \"" + cookie.getDomain() + "\". Domain of origin: \"" + host + "\""); } // host minus domain may not contain any dots String hostWithoutDomain = host.substring(0, host.length() - cookie.getDomain().length()); if (hostWithoutDomain.indexOf('.') != -1) { throw new MalformedCookieException("Domain attribute \"" + cookie.getDomain() + "\" violates RFC 2109: host minus domain may not contain any dots"); } } }
Performs domain-match as defined by the RFC2109.
Params:
  • host – The target host.
  • domain – The cookie domain attribute.
Returns:true if the specified host matches the given domain.
Since:3.0
/** * Performs domain-match as defined by the RFC2109. * @param host The target host. * @param domain The cookie domain attribute. * @return true if the specified host matches the given domain. * * @since 3.0 */
public boolean domainMatch(String host, String domain) { boolean match = host.equals(domain) || (domain.startsWith(".") && host.endsWith(domain)); return match; }
Return a name/value string suitable for sending in a "Cookie" header as defined in RFC 2109 for backward compatibility with cookie version 0
Params:
  • buffer – The string buffer to use for output
  • param – The parameter.
  • version – The cookie version
/** * Return a name/value string suitable for sending in a <tt>"Cookie"</tt> * header as defined in RFC 2109 for backward compatibility with cookie * version 0 * @param buffer The string buffer to use for output * @param param The parameter. * @param version The cookie version */
private void formatParam(final StringBuffer buffer, final NameValuePair param, int version) { if (version < 1) { buffer.append(param.getName()); buffer.append("="); if (param.getValue() != null) { buffer.append(param.getValue()); } } else { this.formatter.format(buffer, param); } }
Return a string suitable for sending in a "Cookie" header as defined in RFC 2109 for backward compatibility with cookie version 0
Params:
  • buffer – The string buffer to use for output
  • cookie – The Cookie to be formatted as string
  • version – The version to use.
/** * Return a string suitable for sending in a <tt>"Cookie"</tt> header * as defined in RFC 2109 for backward compatibility with cookie version 0 * @param buffer The string buffer to use for output * @param cookie The {@link Cookie} to be formatted as string * @param version The version to use. */
private void formatCookieAsVer(final StringBuffer buffer, final Cookie cookie, int version) { String value = cookie.getValue(); if (value == null) { value = ""; } formatParam(buffer, new NameValuePair(cookie.getName(), value), version); if ((cookie.getPath() != null) && cookie.isPathAttributeSpecified()) { buffer.append("; "); formatParam(buffer, new NameValuePair("$Path", cookie.getPath()), version); } if ((cookie.getDomain() != null) && cookie.isDomainAttributeSpecified()) { buffer.append("; "); formatParam(buffer, new NameValuePair("$Domain", cookie.getDomain()), version); } }
Return a string suitable for sending in a "Cookie" header as defined in RFC 2109
Params:
  • cookie – a Cookie to be formatted as string
Returns:a string suitable for sending in a "Cookie" header.
/** * Return a string suitable for sending in a <tt>"Cookie"</tt> header as * defined in RFC 2109 * @param cookie a {@link Cookie} to be formatted as string * @return a string suitable for sending in a <tt>"Cookie"</tt> header. */
public String formatCookie(Cookie cookie) { LOG.trace("enter RFC2109Spec.formatCookie(Cookie)"); if (cookie == null) { throw new IllegalArgumentException("Cookie may not be null"); } int version = cookie.getVersion(); StringBuffer buffer = new StringBuffer(); formatParam(buffer, new NameValuePair("$Version", Integer.toString(version)), version); buffer.append("; "); formatCookieAsVer(buffer, cookie, version); return buffer.toString(); }
Create a RFC 2109 compliant "Cookie" header value containing all Cookies in cookies suitable for sending in a "Cookie" header
Params:
  • cookies – an array of Cookies to be formatted
Returns:a string suitable for sending in a Cookie header.
/** * Create a RFC 2109 compliant <tt>"Cookie"</tt> header value containing all * {@link Cookie}s in <i>cookies</i> suitable for sending in a <tt>"Cookie" * </tt> header * @param cookies an array of {@link Cookie}s to be formatted * @return a string suitable for sending in a Cookie header. */
public String formatCookies(Cookie[] cookies) { LOG.trace("enter RFC2109Spec.formatCookieHeader(Cookie[])"); int version = Integer.MAX_VALUE; // Pick the lowerest common denominator for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; if (cookie.getVersion() < version) { version = cookie.getVersion(); } } final StringBuffer buffer = new StringBuffer(); formatParam(buffer, new NameValuePair("$Version", Integer.toString(version)), version); for (int i = 0; i < cookies.length; i++) { buffer.append("; "); formatCookieAsVer(buffer, cookies[i], version); } return buffer.toString(); } }