
org.refcodes.net.impls.ResponseCookieImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-net Show documentation
Show all versions of refcodes-net Show documentation
This artifact provides networking (TCP/IP) related definitions and types being
used by REFCODES.ORG networking related functionality and artifacts.
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