All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.refcodes.net.impls.ResponseCookieImpl Maven / Gradle / Ivy

Go to download

This artifact provides networking (TCP/IP) related definitions and types being used by REFCODES.ORG networking related functionality and artifacts.

There is a newer version: 3.3.9
Show newest version
package org.refcodes.net.impls;

import java.text.ParseException;
import java.time.DateTimeException;
import java.time.Instant;
import java.util.Date;
import java.util.StringTokenizer;

import org.refcodes.collection.Property;
import org.refcodes.collection.impls.PropertyImpl;
import org.refcodes.data.Delimiter;
import org.refcodes.logger.RuntimeLogger;
import org.refcodes.logger.impls.RuntimeLoggerFactorySingleton;
import org.refcodes.net.Cookie;
import org.refcodes.net.CookieAttribute;
import org.refcodes.net.ResponseCookie;
import org.refcodes.time.DateFormat;
import org.refcodes.time.DateFormats;
import org.refcodes.time.TimeUnit;

/**
 * As of "HTTP cookies explained - NCZOnline": "... There is some confusion over
 * encoding of a cookie value. The commonly held belief is that cookie values
 * must be URL-encoded, but this is a fallacy even though it is the de facto
 * implementation. The original specification indicates that only three types of
 * characters must be encoded: semicolon, comma, and white space. The
 * specification indicates that URL encoding may be used but stops short of
 * requiring it. The RFC makes no mention of encoding whatsoever. Still, almost
 * all implementations perform some sort of URL encoding on cookie values. In
 * the case of name=value formats, the name and value are typically encoded
 * separately while the equals sign is left as is. ..."
 * 
 * Therefore we use URL encoding to make life easier and not fall into the trap
 * of unescaped values.
 * 
 * @see "https://www.nczonline.net/blog/2009/05/05/http-cookies-explained"
 */
public class ResponseCookieImpl extends PropertyImpl implements ResponseCookie {

	private static RuntimeLogger LOGGER = RuntimeLoggerFactorySingleton.createRuntimeLogger();

	// /////////////////////////////////////////////////////////////////////////
	// STATICS:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// CONSTANTS:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// VARIABLES:
	// /////////////////////////////////////////////////////////////////////////

	private Date _expiresDate = null;
	private String _domain = null;
	private String _path = null;
	private boolean _isSecure = false;
	private boolean _isHttpOnly = false;

	// /////////////////////////////////////////////////////////////////////////
	// CONSTRUCTORS:
	// /////////////////////////////////////////////////////////////////////////

	public ResponseCookieImpl() {}

	/**
	 * Constructs a {@link ResponseCookie}.
	 * 
	 * @param aCookieName The name of the cookie.
	 * @param aValue The value for the cookie.
	 */
	public ResponseCookieImpl( String aCookieName, String aValue ) {
		super( aCookieName, aValue );
	}

	/**
	 * Constructs a {@link ResponseCookie}.
	 * 
	 * @param aHttpCookie The text as being found in the according HTTP header
	 *        field.
	 * @throws ParseException Thrown in case parsing a value such as a date
	 *         failed.
	 */
	public ResponseCookieImpl( String aHttpCookie ) {
		StringTokenizer theTokenizer = new StringTokenizer( aHttpCookie, Delimiter.COOKIE_PROPERTIES_DELIMITER.getChar() + "" );
		String eTupel = theTokenizer.nextToken();
		Property eProperty = new PropertyImpl( eTupel );
		setKey( eProperty.getKey() );
		setValue( eProperty.getValue() );
		CookieAttribute eCookieKey;
		while ( theTokenizer.hasMoreTokens() ) {
			eTupel = theTokenizer.nextToken();
			if ( eTupel.equalsIgnoreCase( CookieAttribute.SECURE.getKey() ) ) eCookieKey = CookieAttribute.SECURE;
			else if ( eTupel.equalsIgnoreCase( CookieAttribute.HTTPONLY.getKey() ) ) eCookieKey = CookieAttribute.HTTPONLY;
			else {
				eProperty = new PropertyImpl( eTupel );
				eCookieKey = CookieAttribute.fromKey( eProperty.getKey() );
			}
			switch ( eCookieKey ) {
			case DOMAIN:
				_domain = eProperty.getValue();
				break;
			case EXPIRES:
				try {
					_expiresDate = DateFormats.COOKIE_DATE_FORMATS.toDate( eProperty.getValue() );
				}
				catch ( DateTimeException e ) {
					LOGGER.warn( "Ignoring unparsable date <" + eProperty.getValue() + "> for key <" + eCookieKey.getKey() + ">." );
				}
				break;
			case HTTPONLY:
				_isHttpOnly = true;
			case PATH:
				_path = eProperty.getValue();
				break;
			case SECURE:
				_isSecure = true;
				break;
			case MAX_AGE:
				int theMaxAgeInSeconds = -1;
				try {
					theMaxAgeInSeconds = Integer.parseInt( eProperty.getValue() );
					setExpiresAfter( TimeUnit.SECOND, theMaxAgeInSeconds );
					LOGGER.info( "Converting attribute <" + eCookieKey.getKey() + "> := <" + eProperty.getValue() + "> to attribute <" + CookieAttribute.EXPIRES.getKey() + "> = <" + DateFormat.NETSCAPE_COOKIE_DATE_FORMAT.getFormatter().format( Instant.ofEpochMilli( getExpiresDate().getTime() ) ) + ">." );
				}
				catch ( NumberFormatException e ) {
					LOGGER.warn( "Ignoring unparsable max-age <" + eProperty.getValue() + "> for key <" + eCookieKey.getKey() + ">." );
				}
				break;
			default:
				LOGGER.warn( "Ignoring unsupported HTTP cookie key <" + eProperty.getKey() + ">." );
				break;
			}
		}
	}

	/**
	 * Constructs a {@link ResponseCookie}.
	 * 
	 * @param aCookie The {@link Cookie} from which to take the data.
	 */
	public ResponseCookieImpl( Cookie aCookie ) {
		super( aCookie.getKey(), aCookie.getValue() );
		if ( aCookie instanceof ResponseCookie ) {
			ResponseCookie theResponseCookie = (ResponseCookie) aCookie;
			setDomain( theResponseCookie.getDomain() );
			setPath( theResponseCookie.getPath() );
			setExpiresDate( theResponseCookie.getExpiresDate() );
			setHttpOnly( theResponseCookie.isHttpOnly() );
			setSecure( theResponseCookie.isSecure() );
		}
	}

	/**
	 * Constructs a {@link ResponseCookie}.
	 * 
	 * @param aCookieName The name for the cookie
	 * @param aValue The value of the cookie
	 * @param aExpiresDate The expiration date of the cookie
	 * @param aDomain The domain of the cookie
	 * @param aPath The path of the cookie
	 * @param isSecure The secure flag of the cookie
	 * @param isHttpOnly The HTTP-only flog of the cookie
	 */
	public ResponseCookieImpl( String aCookieName, String aValue, Date aExpiresDate, String aDomain, String aPath, boolean isSecure, boolean isHttpOnly ) {
		super( aCookieName, aValue );
		_expiresDate = aExpiresDate;
		_domain = aDomain;
		_path = aPath;
		_isSecure = isSecure;
		_isHttpOnly = isHttpOnly;
	}

	// /////////////////////////////////////////////////////////////////////////
	// INJECTION:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	@Override
	public String getPath() {
		return _path;
	}

	@Override
	public void setPath( String aPath ) {
		_path = aPath;
	}

	@Override
	public Date getExpiresDate() {
		return _expiresDate;
	}

	@Override
	public void setExpiresDate( Date aExpireDate ) {
		_expiresDate = aExpireDate;
	}

	@Override
	public String getDomain() {
		return _domain;
	}

	@Override
	public void setDomain( String aDomain ) {
		_domain = aDomain;
	}

	@Override
	public void setSecure( boolean isSecure ) {
		_isSecure = isSecure;
	}

	@Override
	public boolean isSecure() {
		return _isSecure;
	}

	@Override
	public boolean isHttpOnly() {
		return _isHttpOnly;
	}

	@Override
	public void setHttpOnly( boolean isHttpOnly ) {
		_isHttpOnly = isHttpOnly;
	}

	@Override
	public void setExpiresAfter( TimeUnit aTimeUnit, long aTime ) {
		long theMilliseconds = TimeUnit.toMilliseconds( aTimeUnit, aTime );
		Date theExpiresDate = new Date();
		theExpiresDate = new Date( theExpiresDate.getTime() + theMilliseconds );
		setExpiresDate( theExpiresDate );
	}

	// /////////////////////////////////////////////////////////////////////////
	// HOOKS:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// HELPER:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// INNER CLASSES:
	// /////////////////////////////////////////////////////////////////////////

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy