1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
|
/*
* 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;
/**
* Static constants for this package.
*/
public final class CookieSupport {
// --------------------------------------------------------------- Constants
/**
* If set to true, we parse cookies strictly according to the servlet,
* cookie and HTTP specs by default.
*/
public static final boolean STRICT_SERVLET_COMPLIANCE;
/**
* If true, cookie values are allowed to contain an equals character without
* being quoted.
*/
public static final boolean ALLOW_EQUALS_IN_VALUE;
/**
* If true, separators that are not explicitly dis-allowed by the v0 cookie
* spec but are disallowed by the HTTP spec will be allowed in v0 cookie
* names and values. These characters are: \"()/:<=>?@[\\]{} Note that the
* inclusion of / depends on the value of {@link #FWD_SLASH_IS_SEPARATOR}.
*/
public static final boolean ALLOW_HTTP_SEPARATORS_IN_V0;
/**
* If set to false, we don't use the IE6/7 Max-Age/Expires work around.
* Default is usually true. If STRICT_SERVLET_COMPLIANCE==true then default
* is false. Explicitly setting always takes priority.
*/
public static final boolean ALWAYS_ADD_EXPIRES;
/**
* If set to true, the <code>/</code> character will be treated as a
* separator. Default is usually false. If STRICT_SERVLET_COMPLIANCE==true
* then default is true. Explicitly setting always takes priority.
*/
public static final boolean FWD_SLASH_IS_SEPARATOR;
/**
* If true, name only cookies will be permitted.
*/
public static final boolean ALLOW_NAME_ONLY;
/**
* The list of separators that apply to version 0 cookies. To quote the
* spec, these are comma, semi-colon and white-space. The HTTP spec
* definition of linear white space is [CRLF] 1*( SP | HT )
*/
private static final char[] V0_SEPARATORS = {',', ';', ' ', '\t'};
private static final boolean[] V0_SEPARATOR_FLAGS = new boolean[128];
/**
* The list of separators that apply to version 1 cookies. This may or may
* not include '/' depending on the setting of
* {@link #FWD_SLASH_IS_SEPARATOR}.
*/
private static final char[] HTTP_SEPARATORS;
private static final boolean[] HTTP_SEPARATOR_FLAGS = new boolean[128];
static {
STRICT_SERVLET_COMPLIANCE = Boolean.valueOf(System.getProperty(
"org.apache.catalina.STRICT_SERVLET_COMPLIANCE",
"false")).booleanValue();
ALLOW_EQUALS_IN_VALUE = Boolean.valueOf(System.getProperty(
"org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE",
"false")).booleanValue();
ALLOW_HTTP_SEPARATORS_IN_V0 = Boolean.valueOf(System.getProperty(
"org.apache.tomcat.util.http.ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0",
"false")).booleanValue();
String alwaysAddExpires = System.getProperty(
"org.apache.tomcat.util.http.ServerCookie.ALWAYS_ADD_EXPIRES");
if (alwaysAddExpires == null) {
ALWAYS_ADD_EXPIRES = !STRICT_SERVLET_COMPLIANCE;
} else {
ALWAYS_ADD_EXPIRES =
Boolean.valueOf(alwaysAddExpires).booleanValue();
}
String fwdSlashIsSeparator = System.getProperty(
"org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR");
if (fwdSlashIsSeparator == null) {
FWD_SLASH_IS_SEPARATOR = STRICT_SERVLET_COMPLIANCE;
} else {
FWD_SLASH_IS_SEPARATOR =
Boolean.valueOf(fwdSlashIsSeparator).booleanValue();
}
ALLOW_NAME_ONLY = Boolean.valueOf(System.getProperty(
"org.apache.tomcat.util.http.ServerCookie.ALLOW_NAME_ONLY",
"false")).booleanValue();
/*
Excluding the '/' char by default violates the RFC, but
it looks like a lot of people put '/'
in unquoted values: '/': ; //47
'\t':9 ' ':32 '\"':34 '(':40 ')':41 ',':44 ':':58 ';':59 '<':60
'=':61 '>':62 '?':63 '@':64 '[':91 '\\':92 ']':93 '{':123 '}':125
*/
if (CookieSupport.FWD_SLASH_IS_SEPARATOR) {
HTTP_SEPARATORS = new char[] { '\t', ' ', '\"', '(', ')', ',', '/',
':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{', '}' };
} else {
HTTP_SEPARATORS = new char[] { '\t', ' ', '\"', '(', ')', ',',
':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{', '}' };
}
for (int i = 0; i < 128; i++) {
V0_SEPARATOR_FLAGS[i] = false;
HTTP_SEPARATOR_FLAGS[i] = false;
}
for (int i = 0; i < V0_SEPARATORS.length; i++) {
V0_SEPARATOR_FLAGS[V0_SEPARATORS[i]] = true;
}
for (int i = 0; i < HTTP_SEPARATORS.length; i++) {
HTTP_SEPARATOR_FLAGS[HTTP_SEPARATORS[i]] = true;
}
}
// ----------------------------------------------------------------- Methods
/**
* Returns true if the byte is a separator as defined by V0 of the cookie
* spec.
*/
public static final boolean isV0Separator(final char c) {
if (c < 0x20 || c >= 0x7f) {
if (c != 0x09) {
throw new IllegalArgumentException(
"Control character in cookie value or attribute.");
}
}
return V0_SEPARATOR_FLAGS[c];
}
public static boolean isV0Token(String value) {
if( value==null) {
return false;
}
int i = 0;
int len = value.length();
if (alreadyQuoted(value)) {
i++;
len--;
}
for (; i < len; i++) {
char c = value.charAt(i);
if (isV0Separator(c)) {
return true;
}
}
return false;
}
/**
* Returns true if the byte is a separator as defined by V1 of the cookie
* spec, RFC2109.
* @throws IllegalArgumentException if a control character was supplied as
* input
*/
public static final boolean isHttpSeparator(final char c) {
if (c < 0x20 || c >= 0x7f) {
if (c != 0x09) {
throw new IllegalArgumentException(
"Control character in cookie value or attribute.");
}
}
return HTTP_SEPARATOR_FLAGS[c];
}
public static boolean isHttpToken(String value) {
if( value==null) {
return false;
}
int i = 0;
int len = value.length();
if (alreadyQuoted(value)) {
i++;
len--;
}
for (; i < len; i++) {
char c = value.charAt(i);
if (isHttpSeparator(c)) {
return true;
}
}
return false;
}
public static boolean alreadyQuoted (String value) {
if (value==null || value.length() < 2) {
return false;
}
return (value.charAt(0)=='\"' && value.charAt(value.length()-1)=='\"');
}
// ------------------------------------------------------------- Constructor
private CookieSupport() {
// Utility class. Don't allow instances to be created.
}
}
|