Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.
*/
package org.apache.tomcat.util.http;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.apache.tomcat.util.buf.MessageBytes;
/**
* Server-side cookie representation.
* Allows recycling and uses MessageBytes as low-level
* representation ( and thus the byte-> char conversion can be delayed
* until we know the charset ).
*
* Tomcat.core uses this recyclable object to represent cookies,
* and the facade will convert it to the external representation.
*/
public class ServerCookie implements Serializable {
private static final long serialVersionUID = 1L;
// Version 0 (Netscape) attributes
private final MessageBytes name=MessageBytes.newInstance();
private final MessageBytes value=MessageBytes.newInstance();
// Expires - Not stored explicitly. Generated from Max-Age (see V1)
private final MessageBytes path=MessageBytes.newInstance();
private final MessageBytes domain=MessageBytes.newInstance();
private boolean secure;
// Version 1 (RFC2109) attributes
private final MessageBytes comment=MessageBytes.newInstance();
private int maxAge = -1;
private int version = 0;
// Other fields
private static final String OLD_COOKIE_PATTERN =
"EEE, dd-MMM-yyyy HH:mm:ss z";
private static final ThreadLocal OLD_COOKIE_FORMAT =
new ThreadLocal() {
@Override
protected DateFormat initialValue() {
DateFormat df =
new SimpleDateFormat(OLD_COOKIE_PATTERN, Locale.US);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df;
}
};
private static final String ancientDate;
static {
ancientDate = OLD_COOKIE_FORMAT.get().format(new Date(10000));
}
// Note: Servlet Spec =< 3.0 only refers to Netscape and RFC2109,
// not RFC2965
// Version 2 (RFC2965) attributes that would need to be added to support
// v2 cookies
// CommentURL
// Discard - implied by maxAge <0
// Port
public ServerCookie() {
// NOOP
}
public void recycle() {
name.recycle();
value.recycle();
comment.recycle();
maxAge=-1;
path.recycle();
domain.recycle();
version=0;
secure=false;
}
public MessageBytes getComment() {
return comment;
}
public MessageBytes getDomain() {
return domain;
}
public void setMaxAge(int expiry) {
maxAge = expiry;
}
public int getMaxAge() {
return maxAge;
}
public MessageBytes getPath() {
return path;
}
public void setSecure(boolean flag) {
secure = flag;
}
public boolean getSecure() {
return secure;
}
public MessageBytes getName() {
return name;
}
public MessageBytes getValue() {
return value;
}
public int getVersion() {
return version;
}
public void setVersion(int v) {
version = v;
}
// -------------------- utils --------------------
@Override
public String toString() {
return "Cookie " + getName() + "=" + getValue() + " ; "
+ getVersion() + " " + getPath() + " " + getDomain();
}
// -------------------- Cookie parsing tools
public static void appendCookieValue( StringBuffer headerBuf,
int version,
String name,
String value,
String path,
String domain,
String comment,
int maxAge,
boolean isSecure,
boolean isHttpOnly)
{
StringBuffer buf = new StringBuffer();
// Servlet implementation checks name
buf.append( name );
buf.append("=");
// Servlet implementation does not check anything else
/*
* The spec allows some latitude on when to send the version attribute
* with a Set-Cookie header. To be nice to clients, we'll make sure the
* version attribute is first. That means checking the various things
* that can cause us to switch to a v1 cookie first.
*
* Note that by checking for tokens we will also throw an exception if a
* control character is encountered.
*/
// Start by using the version we were asked for
int newVersion = version;
// If it is v0, check if we need to switch
if (newVersion == 0 &&
(!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
CookieSupport.isHttpToken(value) ||
CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
CookieSupport.isV0Token(value))) {
// HTTP token in value - need to use v1
newVersion = 1;
}
if (newVersion == 0 && comment != null) {
// Using a comment makes it a v1 cookie
newVersion = 1;
}
if (newVersion == 0 &&
(!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
CookieSupport.isHttpToken(path) ||
CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
CookieSupport.isV0Token(path))) {
// HTTP token in path - need to use v1
newVersion = 1;
}
if (newVersion == 0 &&
(!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
CookieSupport.isHttpToken(domain) ||
CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
CookieSupport.isV0Token(domain))) {
// HTTP token in domain - need to use v1
newVersion = 1;
}
// Now build the cookie header
// Value
maybeQuote(buf, value);
// Add version 1 specific information
if (newVersion == 1) {
// Version=1 ... required
buf.append ("; Version=1");
// Comment=comment
if ( comment!=null ) {
buf.append ("; Comment=");
maybeQuote(buf, comment);
}
}
// Add domain information, if present
if (domain!=null) {
buf.append("; Domain=");
maybeQuote(buf, domain);
}
// Max-Age=secs ... or use old "Expires" format
if (maxAge >= 0) {
if (newVersion > 0) {
buf.append ("; Max-Age=");
buf.append (maxAge);
}
// IE6, IE7 and possibly other browsers don't understand Max-Age.
// They do understand Expires, even with V1 cookies!
if (newVersion == 0 || CookieSupport.ALWAYS_ADD_EXPIRES) {
// Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format )
buf.append ("; Expires=");
// To expire immediately we need to set the time in past
if (maxAge == 0) {
buf.append( ancientDate );
} else {
OLD_COOKIE_FORMAT.get().format(
new Date(System.currentTimeMillis() +
maxAge*1000L),
buf, new FieldPosition(0));
}
}
}
// Path=path
if (path!=null) {
buf.append ("; Path=");
maybeQuote(buf, path);
}
// Secure
if (isSecure) {
buf.append ("; Secure");
}
// HttpOnly
if (isHttpOnly) {
buf.append("; HttpOnly");
}
headerBuf.append(buf);
}
/**
* Quotes values if required.
* @param buf
* @param value
*/
private static void maybeQuote (StringBuffer buf, String value) {
if (value==null || value.length()==0) {
buf.append("\"\"");
} else if (CookieSupport.alreadyQuoted(value)) {
buf.append('"');
buf.append(escapeDoubleQuotes(value,1,value.length()-1));
buf.append('"');
} else if (CookieSupport.isHttpToken(value) &&
!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 ||
CookieSupport.isV0Token(value) &&
CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0) {
buf.append('"');
buf.append(escapeDoubleQuotes(value,0,value.length()));
buf.append('"');
} else {
buf.append(value);
}
}
/**
* Escapes any double quotes in the given string.
*
* @param s the input string
* @param beginIndex start index inclusive
* @param endIndex exclusive
* @return The (possibly) escaped string
*/
private static String escapeDoubleQuotes(String s, int beginIndex, int endIndex) {
if (s == null || s.length() == 0 || s.indexOf('"') == -1) {
return s;
}
StringBuffer b = new StringBuffer();
for (int i = beginIndex; i < endIndex; i++) {
char c = s.charAt(i);
if (c == '\\' ) {
b.append(c);
//ignore the character after an escape, just append it
if (++i>=endIndex) {
throw new IllegalArgumentException("Invalid escape character in cookie value.");
}
b.append(s.charAt(i));
} else if (c == '"') {
b.append('\\').append('"');
} else {
b.append(c);
}
}
return b.toString();
}
}