This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 8.5.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit f00b3b95a0fbb343a3dce17986f4866c6b485570 Author: Mark Thomas <ma...@apache.org> AuthorDate: Tue Apr 11 16:47:10 2023 +0100 Code clean-up. No functional change. --- .../tomcat/util/http/ConcurrentDateFormat.java | 5 +- .../apache/tomcat/util/http/CookieProcessor.java | 34 +-- .../tomcat/util/http/CookieProcessorBase.java | 13 +- .../tomcat/util/http/FastHttpDateFormat.java | 33 +- java/org/apache/tomcat/util/http/HeaderUtil.java | 10 +- java/org/apache/tomcat/util/http/HttpMessages.java | 79 +++-- .../tomcat/util/http/LegacyCookieProcessor.java | 331 +++++++++------------ java/org/apache/tomcat/util/http/MimeHeaders.java | 185 ++++++------ java/org/apache/tomcat/util/http/Parameters.java | 115 ++++--- java/org/apache/tomcat/util/http/RequestUtil.java | 22 +- .../tomcat/util/http/Rfc6265CookieProcessor.java | 48 ++- java/org/apache/tomcat/util/http/ServerCookie.java | 25 +- .../org/apache/tomcat/util/http/ServerCookies.java | 11 +- 13 files changed, 414 insertions(+), 497 deletions(-) diff --git a/java/org/apache/tomcat/util/http/ConcurrentDateFormat.java b/java/org/apache/tomcat/util/http/ConcurrentDateFormat.java index 02a456f20a..eb678aa5fb 100644 --- a/java/org/apache/tomcat/util/http/ConcurrentDateFormat.java +++ b/java/org/apache/tomcat/util/http/ConcurrentDateFormat.java @@ -25,9 +25,8 @@ import java.util.TimeZone; import java.util.concurrent.ConcurrentLinkedQueue; /** - * A thread safe wrapper around {@link SimpleDateFormat} that does not make use - * of ThreadLocal and - broadly - only creates enough SimpleDateFormat objects - * to satisfy the concurrency requirements. + * A thread safe wrapper around {@link SimpleDateFormat} that does not make use of ThreadLocal and - broadly - only + * creates enough SimpleDateFormat objects to satisfy the concurrency requirements. */ public class ConcurrentDateFormat { diff --git a/java/org/apache/tomcat/util/http/CookieProcessor.java b/java/org/apache/tomcat/util/http/CookieProcessor.java index ffda7b7916..e6003319b1 100644 --- a/java/org/apache/tomcat/util/http/CookieProcessor.java +++ b/java/org/apache/tomcat/util/http/CookieProcessor.java @@ -27,8 +27,7 @@ public interface CookieProcessor { * Parse the provided headers into server cookie objects. * * @param headers The HTTP headers to parse - * @param serverCookies The server cookies object to populate with the - * results of the parsing + * @param serverCookies The server cookies object to populate with the results of the parsing */ void parseCookieHeader(MimeHeaders headers, ServerCookies serverCookies); @@ -37,38 +36,31 @@ public interface CookieProcessor { * * @param cookie The cookie for which the header will be generated * - * @return The header value in a form that can be added directly to the - * response + * @return The header value in a form that can be added directly to the response * - * @deprecated This method has been replaced with - * {@link #generateHeader(Cookie, HttpServletRequest)} and will - * be removed from Tomcat 10 onwards. + * @deprecated This method has been replaced with {@link #generateHeader(Cookie, HttpServletRequest)} and will be + * removed from Tomcat 10 onwards. */ @Deprecated String generateHeader(Cookie cookie); /** - * Generate the {@code Set-Cookie} HTTP header value for the given Cookie. - * This method receives as parameter the servlet request so that it can make - * decisions based on request properties. One such use-case is decide if the - * SameSite attribute should be added to the cookie based on the User-Agent - * or other request header because there are browser versions incompatible - * with the SameSite attribute. This is described by <a - * href="https://www.chromium.org/updates/same-site/incompatible-clients">the - * Chromium project</a>. + * Generate the {@code Set-Cookie} HTTP header value for the given Cookie. This method receives as parameter the + * servlet request so that it can make decisions based on request properties. One such use-case is decide if the + * SameSite attribute should be added to the cookie based on the User-Agent or other request header because there + * are browser versions incompatible with the SameSite attribute. This is described by + * <a href="https://www.chromium.org/updates/same-site/incompatible-clients">the Chromium project</a>. * * @param request The servlet request + * @param cookie The cookie for which the header will be generated * - * @param cookie The cookie for which the header will be generated - * - * @return The header value in a form that can be added directly to the - * response + * @return The header value in a form that can be added directly to the response */ String generateHeader(Cookie cookie, HttpServletRequest request); /** - * Obtain the character set that will be used when converting between bytes - * and characters when parsing and/or generating HTTP headers for cookies. + * Obtain the character set that will be used when converting between bytes and characters when parsing and/or + * generating HTTP headers for cookies. * * @return The character set used for byte<->character conversions */ diff --git a/java/org/apache/tomcat/util/http/CookieProcessorBase.java b/java/org/apache/tomcat/util/http/CookieProcessorBase.java index 8c4dc1e449..2a7a6ff4df 100644 --- a/java/org/apache/tomcat/util/http/CookieProcessorBase.java +++ b/java/org/apache/tomcat/util/http/CookieProcessorBase.java @@ -29,12 +29,10 @@ public abstract class CookieProcessorBase implements CookieProcessor { private static final String COOKIE_DATE_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z"; - protected static final ThreadLocal<DateFormat> COOKIE_DATE_FORMAT = - new ThreadLocal<DateFormat>() { + protected static final ThreadLocal<DateFormat> COOKIE_DATE_FORMAT = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { - DateFormat df = - new SimpleDateFormat(COOKIE_DATE_PATTERN, Locale.US); + DateFormat df = new SimpleDateFormat(COOKIE_DATE_PATTERN, Locale.US); df.setTimeZone(TimeZone.getTimeZone("GMT")); return df; } @@ -59,10 +57,9 @@ public abstract class CookieProcessorBase implements CookieProcessor { /** * {@inheritDoc} * - * @deprecated This implementation calls the deprecated - * {@link #generateHeader(Cookie)} method. Implementors should - * not rely on this method as it is present only for - * transitional compatibility and will be removed in Tomcat 9. + * @deprecated This implementation calls the deprecated {@link #generateHeader(Cookie)} method. Implementors should + * not rely on this method as it is present only for transitional compatibility and will be removed + * in Tomcat 9. */ @Deprecated @Override diff --git a/java/org/apache/tomcat/util/http/FastHttpDateFormat.java b/java/org/apache/tomcat/util/http/FastHttpDateFormat.java index c1c73bd60e..6c941c984e 100644 --- a/java/org/apache/tomcat/util/http/FastHttpDateFormat.java +++ b/java/org/apache/tomcat/util/http/FastHttpDateFormat.java @@ -35,8 +35,8 @@ public final class FastHttpDateFormat { // -------------------------------------------------------------- Variables - private static final int CACHE_SIZE = - Integer.getInteger("org.apache.tomcat.util.http.FastHttpDateFormat.CACHE_SIZE", 1000).intValue(); + private static final int CACHE_SIZE = Integer + .getInteger("org.apache.tomcat.util.http.FastHttpDateFormat.CACHE_SIZE", 1000).intValue(); /** @@ -66,8 +66,8 @@ public final class FastHttpDateFormat { FORMAT_OBSOLETE_RFC850 = new ConcurrentDateFormat(DATE_OBSOLETE_RFC850, Locale.US, tz); FORMAT_OBSOLETE_ASCTIME = new ConcurrentDateFormat(DATE_OBSOLETE_ASCTIME, Locale.US, tz); - httpParseFormats = new ConcurrentDateFormat[] { - FORMAT_RFC5322, FORMAT_OBSOLETE_RFC850, FORMAT_OBSOLETE_ASCTIME }; + httpParseFormats = new ConcurrentDateFormat[] { FORMAT_RFC5322, FORMAT_OBSOLETE_RFC850, + FORMAT_OBSOLETE_ASCTIME }; } /** @@ -99,6 +99,7 @@ public final class FastHttpDateFormat { /** * Get the current date in HTTP format. + * * @return the HTTP date */ public static String getCurrentDate() { @@ -114,9 +115,10 @@ public final class FastHttpDateFormat { /** * Get the HTTP format of the specified date. - * @param value The date - * @param threadLocalformat Ignored. The local ConcurrentDateFormat will - * always be used. + * + * @param value The date + * @param threadLocalformat Ignored. The local ConcurrentDateFormat will always be used. + * * @return the HTTP date * * @deprecated Unused. This will be removed in Tomcat 10 @@ -129,7 +131,9 @@ public final class FastHttpDateFormat { /** * Get the HTTP format of the specified date. + * * @param value The date + * * @return the HTTP date */ public static String formatDate(long value) { @@ -147,13 +151,13 @@ public final class FastHttpDateFormat { /** * Try to parse the given date as an HTTP date. - * @param value The HTTP date - * @param threadLocalformats Ignored. The local array of - * ConcurrentDateFormat will always be used. + * + * @param value The HTTP date + * @param threadLocalformats Ignored. The local array of ConcurrentDateFormat will always be used. + * * @return the date as a long * - * @deprecated Unused. This will be removed in Tomcat 10 - * Use {@link #parseDate(String)} + * @deprecated Unused. This will be removed in Tomcat 10 Use {@link #parseDate(String)} */ @Deprecated public static long parseDate(String value, DateFormat[] threadLocalformats) { @@ -163,9 +167,10 @@ public final class FastHttpDateFormat { /** * Try to parse the given date as an HTTP date. + * * @param value The HTTP date - * @return the date as a long or <code>-1</code> if the value cannot be - * parsed + * + * @return the date as a long or <code>-1</code> if the value cannot be parsed */ public static long parseDate(String value) { diff --git a/java/org/apache/tomcat/util/http/HeaderUtil.java b/java/org/apache/tomcat/util/http/HeaderUtil.java index cb40cabede..59f06c4c35 100644 --- a/java/org/apache/tomcat/util/http/HeaderUtil.java +++ b/java/org/apache/tomcat/util/http/HeaderUtil.java @@ -19,17 +19,15 @@ package org.apache.tomcat.util.http; public class HeaderUtil { /** - * Converts an HTTP header line in byte form to a printable String. - * Bytes corresponding to visible ASCII characters will converted to those - * characters. All other bytes (0x00 to 0x1F, 0x7F to OxFF) will be - * represented in 0xNN form. + * Converts an HTTP header line in byte form to a printable String. Bytes corresponding to visible ASCII characters + * will converted to those characters. All other bytes (0x00 to 0x1F, 0x7F to OxFF) will be represented in 0xNN + * form. * * @param bytes Contains an HTTP header line * @param offset The start position of the header line in the array * @param len The length of the HTTP header line * - * @return A String with non-printing characters replaced by the 0xNN - * equivalent + * @return A String with non-printing characters replaced by the 0xNN equivalent */ public static String toPrintableString(byte[] bytes, int offset, int len) { StringBuilder result = new StringBuilder(); diff --git a/java/org/apache/tomcat/util/http/HttpMessages.java b/java/org/apache/tomcat/util/http/HttpMessages.java index 1e4431dbb3..dee85c18fd 100644 --- a/java/org/apache/tomcat/util/http/HttpMessages.java +++ b/java/org/apache/tomcat/util/http/HttpMessages.java @@ -33,12 +33,10 @@ import org.apache.tomcat.util.res.StringManager; */ public class HttpMessages { - private static final Map<Locale,HttpMessages> instances = - new ConcurrentHashMap<>(); + private static final Map<Locale, HttpMessages> instances = new ConcurrentHashMap<>(); private static final HttpMessages DEFAULT = new HttpMessages( - StringManager.getManager("org.apache.tomcat.util.http.res", - Locale.getDefault())); + StringManager.getManager("org.apache.tomcat.util.http.res", Locale.getDefault())); // XXX move message resources in this package @@ -56,55 +54,52 @@ public class HttpMessages { /** - * Get the status string associated with a status code. Common messages are - * cached. + * Get the status string associated with a status code. Common messages are cached. * * @param status The HTTP status code to retrieve the message for * - * @return The HTTP status string that conforms to the requirements of the - * HTTP specification + * @return The HTTP status string that conforms to the requirements of the HTTP specification */ public String getMessage(int status) { // method from Response. // Does HTTP requires/allow international messages or // are pre-defined? The user doesn't see them most of the time - switch( status ) { - case 200: - if(st_200 == null ) { - st_200 = sm.getString("sc.200"); - } - return st_200; - case 302: - if(st_302 == null ) { - st_302 = sm.getString("sc.302"); - } - return st_302; - case 400: - if(st_400 == null ) { - st_400 = sm.getString("sc.400"); - } - return st_400; - case 404: - if(st_404 == null ) { - st_404 = sm.getString("sc.404"); - } - return st_404; - case 500: - if (st_500 == null) { - st_500 = sm.getString("sc.500"); - } - return st_500; + switch (status) { + case 200: + if (st_200 == null) { + st_200 = sm.getString("sc.200"); + } + return st_200; + case 302: + if (st_302 == null) { + st_302 = sm.getString("sc.302"); + } + return st_302; + case 400: + if (st_400 == null) { + st_400 = sm.getString("sc.400"); + } + return st_400; + case 404: + if (st_404 == null) { + st_404 = sm.getString("sc.404"); + } + return st_404; + case 500: + if (st_500 == null) { + st_500 = sm.getString("sc.500"); + } + return st_500; } - return sm.getString("sc."+ status); + return sm.getString("sc." + status); } public static HttpMessages getInstance(Locale locale) { HttpMessages result = instances.get(locale); if (result == null) { - StringManager sm = StringManager.getManager( - "org.apache.tomcat.util.http.res", locale); + StringManager sm = StringManager.getManager("org.apache.tomcat.util.http.res", locale); if (Locale.getDefault().equals(sm.getLocale())) { result = DEFAULT; } else { @@ -117,12 +112,12 @@ public class HttpMessages { /** - * Is the provided message safe to use in an HTTP header. Safe messages must - * meet the requirements of RFC2616 - i.e. must consist only of TEXT. + * Is the provided message safe to use in an HTTP header. Safe messages must meet the requirements of RFC2616 - i.e. + * must consist only of TEXT. + * + * @param msg The message to test * - * @param msg The message to test - * @return <code>true</code> if the message is safe to use in an HTTP - * header else <code>false</code> + * @return <code>true</code> if the message is safe to use in an HTTP header else <code>false</code> */ public static boolean isSafeInHttpHeader(String msg) { // Nulls are fine. It is up to the calling code to address any NPE diff --git a/java/org/apache/tomcat/util/http/LegacyCookieProcessor.java b/java/org/apache/tomcat/util/http/LegacyCookieProcessor.java index 5cd78b4983..d41b829ae3 100644 --- a/java/org/apache/tomcat/util/http/LegacyCookieProcessor.java +++ b/java/org/apache/tomcat/util/http/LegacyCookieProcessor.java @@ -33,10 +33,8 @@ import org.apache.tomcat.util.log.UserDataHelper; import org.apache.tomcat.util.res.StringManager; /** - * The legacy (up to early Tomcat 8 releases) cookie parser based on RFC6265, - * RFC2109 and RFC2616. - * - * This class is not thread-safe. + * The legacy (up to early Tomcat 8 releases) cookie parser based on RFC6265, RFC2109 and RFC2616. This class is not + * thread-safe. * * @author Costin Manolache * @author kevin seguin @@ -47,17 +45,15 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { private static final UserDataHelper userDataLog = new UserDataHelper(log); - private static final StringManager sm = - StringManager.getManager("org.apache.tomcat.util.http"); + private static final StringManager sm = StringManager.getManager("org.apache.tomcat.util.http"); - private static final char[] V0_SEPARATORS = {',', ';', ' ', '\t'}; + private static final char[] V0_SEPARATORS = { ',', ';', ' ', '\t' }; private static final BitSet V0_SEPARATOR_FLAGS = new BitSet(128); // Excludes '/' since configuration controls whether or not to treat '/' as // a separator - private static final char[] HTTP_SEPARATORS = new char[] { - '\t', ' ', '\"', '(', ')', ',', ':', ';', '<', '=', '>', '?', '@', - '[', '\\', ']', '{', '}' }; + private static final char[] HTTP_SEPARATORS = new char[] { '\t', ' ', '\"', '(', ')', ',', ':', ';', '<', '=', '>', + '?', '@', '[', '\\', ']', '{', '}' }; static { for (char c : V0_SEPARATORS) { @@ -65,8 +61,8 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { } } - private final boolean STRICT_SERVLET_COMPLIANCE = - Boolean.getBoolean("org.apache.catalina.STRICT_SERVLET_COMPLIANCE"); + private final boolean STRICT_SERVLET_COMPLIANCE = Boolean + .getBoolean("org.apache.catalina.STRICT_SERVLET_COMPLIANCE"); private boolean allowEqualsInValue = false; @@ -107,11 +103,10 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { } /* - * Some browsers (e.g. IE6 and IE7) do not handle quoted Path values even - * when Version is set to 1. To allow for this, we support a property - * FWD_SLASH_IS_SEPARATOR which, when false, means a '/' character will not - * be treated as a separator, potentially avoiding quoting and the ensuing - * side effect of having the cookie upgraded to version 1. + * Some browsers (e.g. IE6 and IE7) do not handle quoted Path values even when Version is set to 1. To allow for + * this, we support a property FWD_SLASH_IS_SEPARATOR which, when false, means a '/' character will not be + * treated as a separator, potentially avoiding quoting and the ensuing side effect of having the cookie + * upgraded to version 1. * * For now, we apply this rule globally rather than just to the Path attribute. */ @@ -214,8 +209,8 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { while (pos >= 0) { MessageBytes cookieValue = headers.getValue(pos); - if (cookieValue != null && !cookieValue.isNull() ) { - if (cookieValue.getType() != MessageBytes.T_BYTES ) { + if (cookieValue != null && !cookieValue.isNull()) { + if (cookieValue.getType() != MessageBytes.T_BYTES) { Exception e = new Exception(); // TODO: Review this in light of HTTP/2 log.debug("Cookies: Parsing cookie as String. Expected bytes.", e); @@ -244,13 +239,11 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { public String generateHeader(Cookie cookie, HttpServletRequest request) { /* - * 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. + * 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. + * Note that by checking for tokens we will also throw an exception if a control character is encountered. */ int version = cookie.getVersion(); String value = cookie.getValue(); @@ -278,11 +271,11 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { // Add version 1 specific information if (version == 1) { // Version=1 ... required - buf.append ("; Version=1"); + buf.append("; Version=1"); // Comment=comment if (comment != null) { - buf.append ("; Comment="); + buf.append("; Comment="); maybeQuote(buf, comment, version); } } @@ -297,35 +290,33 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { int maxAge = cookie.getMaxAge(); if (maxAge >= 0) { if (version > 0) { - buf.append ("; Max-Age="); - buf.append (maxAge); + 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 (version == 0 || getAlwaysAddExpires()) { // Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format ) - buf.append ("; Expires="); + buf.append("; Expires="); // To expire immediately we need to set the time in past if (maxAge == 0) { - buf.append( ANCIENT_DATE ); + buf.append(ANCIENT_DATE); } else { - COOKIE_DATE_FORMAT.get().format( - new Date(System.currentTimeMillis() + maxAge * 1000L), - buf, + COOKIE_DATE_FORMAT.get().format(new Date(System.currentTimeMillis() + maxAge * 1000L), buf, new FieldPosition(0)); } } } // Path=path - if (path!=null) { - buf.append ("; Path="); + if (path != null) { + buf.append("; Path="); maybeQuote(buf, path, version); } // Secure if (cookie.getSecure()) { - buf.append ("; Secure"); + buf.append("; Secure"); } // HttpOnly @@ -349,11 +340,11 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { buf.append("\"\""); } else if (alreadyQuoted(value)) { buf.append('"'); - escapeDoubleQuotes(buf, value,1,value.length()-1); + escapeDoubleQuotes(buf, value, 1, value.length() - 1); buf.append('"'); } else if (needsQuotes(value, version)) { buf.append('"'); - escapeDoubleQuotes(buf, value,0,value.length()); + escapeDoubleQuotes(buf, value, 0, value.length()); buf.append('"'); } else { buf.append(value); @@ -369,7 +360,7 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { for (int i = beginIndex; i < endIndex; i++) { char c = s.charAt(i); - if (c == '\\' ) { + if (c == '\\') { b.append('\\').append('\\'); } else if (c == '"') { b.append('\\').append('"'); @@ -396,11 +387,9 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { for (; i < len; i++) { char c = value.charAt(i); if ((c < 0x20 && c != '\t') || c >= 0x7f) { - throw new IllegalArgumentException( - "Control character in cookie value or attribute."); + throw new IllegalArgumentException("Control character in cookie value or attribute."); } - if (version == 0 && !allowedWithoutQuotes.get(c) || - version == 1 && isHttpSeparator(c)) { + if (version == 0 && !allowedWithoutQuotes.get(c) || version == 1 && isHttpSeparator(c)) { return true; } } @@ -408,21 +397,15 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { } - private static boolean alreadyQuoted (String value) { - return value.length() >= 2 && - value.charAt(0) == '\"' && - value.charAt(value.length() - 1) == '\"'; + private static boolean alreadyQuoted(String value) { + return value.length() >= 2 && value.charAt(0) == '\"' && value.charAt(value.length() - 1) == '\"'; } /** - * Parses a cookie header after the initial "Cookie:" - * [WS][$]token[WS]=[WS](token|QV)[;|,] - * RFC 2965 / RFC 2109 - * JVK + * Parses a cookie header after the initial "Cookie:" [WS][$]token[WS]=[WS](token|QV)[;|,] RFC 2965 / RFC 2109 JVK */ - private void processCookieHeader(byte bytes[], int off, int len, - ServerCookies serverCookies) { + private void processCookieHeader(byte bytes[], int off, int len, ServerCookies serverCookies) { if (len <= 0 || bytes == null) { return; @@ -443,12 +426,10 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { isQuoted = false; // Skip whitespace and non-token characters (separators) - while (pos < end && - (isHttpSeparator((char) bytes[pos]) && - !getAllowHttpSepsInV0() || - isV0Separator((char) bytes[pos]) || - isWhiteSpace(bytes[pos]))) - {pos++; } + while (pos < end && (isHttpSeparator((char) bytes[pos]) && !getAllowHttpSepsInV0() || + isV0Separator((char) bytes[pos]) || isWhiteSpace(bytes[pos]))) { + pos++; + } if (pos >= end) { return; @@ -462,10 +443,12 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { // Get the cookie/attribute name. This must be a token valueEnd = valueStart = nameStart = pos; - pos = nameEnd = getTokenEndPosition(bytes,pos,end,version,true); + pos = nameEnd = getTokenEndPosition(bytes, pos, end, version, true); // Skip whitespace - while (pos < end && isWhiteSpace(bytes[pos])) {pos++; } + while (pos < end && isWhiteSpace(bytes[pos])) { + pos++; + } // Check for an '=' -- This could also be a name-only @@ -486,79 +469,74 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { // Determine what type of value this is, quoted value, // token, name-only with an '=', or other (bad) switch (bytes[pos]) { - case '"': // Quoted Value - isQuoted = true; - valueStart = pos + 1; // strip " - // getQuotedValue returns the position before - // at the last quote. This must be dealt with - // when the bytes are copied into the cookie - valueEnd = getQuotedValueEndPosition(bytes, valueStart, end); - // We need pos to advance - pos = valueEnd; - // Handles cases where the quoted value is - // unterminated and at the end of the header, - // e.g. [myname="value] - if (pos >= end) { - return; - } - break; - case ';': - case ',': - // Name-only cookie with an '=' after the name token - // This may not be RFC compliant - valueStart = valueEnd = -1; - // The position is OK (On a delimiter) - break; - default: - if (version == 0 && - !isV0Separator((char)bytes[pos]) && - getAllowHttpSepsInV0() || - !isHttpSeparator((char)bytes[pos]) || - bytes[pos] == '=') { - // Token - valueStart = pos; - // getToken returns the position at the delimiter - // or other non-token character - valueEnd = getTokenEndPosition(bytes, valueStart, end, version, false); + case '"': // Quoted Value + isQuoted = true; + valueStart = pos + 1; // strip " + // getQuotedValue returns the position before + // at the last quote. This must be dealt with + // when the bytes are copied into the cookie + valueEnd = getQuotedValueEndPosition(bytes, valueStart, end); // We need pos to advance pos = valueEnd; - // Edge case. If value starts with '=' but this is not - // allowed in a value make sure we treat this as no - // value being present - if (valueStart == valueEnd) { - valueStart = -1; - valueEnd = -1; + // Handles cases where the quoted value is + // unterminated and at the end of the header, + // e.g. [myname="value] + if (pos >= end) { + return; } - } else { - // INVALID COOKIE, advance to next delimiter - // The starting character of the cookie value was - // not valid. - UserDataHelper.Mode logMode = userDataLog.getNextMode(); - if (logMode != null) { - String message = sm.getString( - "cookies.invalidCookieToken"); - switch (logMode) { - case INFO_THEN_DEBUG: - message += sm.getString( - "cookies.fallToDebug"); - //$FALL-THROUGH$ - case INFO: - log.info(message); - break; - case DEBUG: - log.debug(message); + break; + case ';': + case ',': + // Name-only cookie with an '=' after the name token + // This may not be RFC compliant + valueStart = valueEnd = -1; + // The position is OK (On a delimiter) + break; + default: + if (version == 0 && !isV0Separator((char) bytes[pos]) && getAllowHttpSepsInV0() || + !isHttpSeparator((char) bytes[pos]) || bytes[pos] == '=') { + // Token + valueStart = pos; + // getToken returns the position at the delimiter + // or other non-token character + valueEnd = getTokenEndPosition(bytes, valueStart, end, version, false); + // We need pos to advance + pos = valueEnd; + // Edge case. If value starts with '=' but this is not + // allowed in a value make sure we treat this as no + // value being present + if (valueStart == valueEnd) { + valueStart = -1; + valueEnd = -1; + } + } else { + // INVALID COOKIE, advance to next delimiter + // The starting character of the cookie value was + // not valid. + UserDataHelper.Mode logMode = userDataLog.getNextMode(); + if (logMode != null) { + String message = sm.getString("cookies.invalidCookieToken"); + switch (logMode) { + case INFO_THEN_DEBUG: + message += sm.getString("cookies.fallToDebug"); + //$FALL-THROUGH$ + case INFO: + log.info(message); + break; + case DEBUG: + log.debug(message); + } + } + while (pos < end && bytes[pos] != ';' && bytes[pos] != ',') { + pos++; } + pos++; + // Make sure no special avpairs can be attributed to + // the previous cookie by setting the current cookie + // to null + sc = null; + continue; } - while (pos < end && bytes[pos] != ';' && - bytes[pos] != ',') - {pos++; } - pos++; - // Make sure no special avpairs can be attributed to - // the previous cookie by setting the current cookie - // to null - sc = null; - continue; - } } } else { // Name only cookie @@ -572,7 +550,9 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { // in a good state. // Skip whitespace - while (pos < end && isWhiteSpace(bytes[pos])) {pos++; } + while (pos < end && isWhiteSpace(bytes[pos])) { + pos++; + } // Make sure that after the cookie we have a separator. This @@ -589,11 +569,10 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { isSpecial = false; // $Version must be the first avpair in the cookie header // (sc must be null) - if (equals( "Version", bytes, nameStart, nameEnd) && - sc == null) { + if (equals("Version", bytes, nameStart, nameEnd) && sc == null) { // Set version - if( bytes[valueStart] =='1' && valueEnd == (valueStart+1)) { - version=1; + if (bytes[valueStart] == '1' && valueEnd == (valueStart + 1)) { + version = 1; } else { // unknown version (Versioning is not very strict) } @@ -606,25 +585,21 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { } // Domain is more common, so it goes first - if (equals( "Domain", bytes, nameStart, nameEnd)) { - sc.getDomain().setBytes( bytes, - valueStart, - valueEnd-valueStart); + if (equals("Domain", bytes, nameStart, nameEnd)) { + sc.getDomain().setBytes(bytes, valueStart, valueEnd - valueStart); continue; } - if (equals( "Path", bytes, nameStart, nameEnd)) { - sc.getPath().setBytes( bytes, - valueStart, - valueEnd-valueStart); + if (equals("Path", bytes, nameStart, nameEnd)) { + sc.getPath().setBytes(bytes, valueStart, valueEnd - valueStart); continue; } // v2 cookie attributes - skip them - if (equals( "Port", bytes, nameStart, nameEnd)) { + if (equals("Port", bytes, nameStart, nameEnd)) { continue; } - if (equals( "CommentURL", bytes, nameStart, nameEnd)) { + if (equals("CommentURL", bytes, nameStart, nameEnd)) { continue; } @@ -650,13 +625,11 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { } sc = serverCookies.addCookie(); - sc.setVersion( version ); - sc.getName().setBytes( bytes, nameStart, - nameEnd-nameStart); + sc.setVersion(version); + sc.getName().setBytes(bytes, nameStart, nameEnd - nameStart); if (valueStart != -1) { // Normal AVPair - sc.getValue().setBytes( bytes, valueStart, - valueEnd-valueStart); + sc.getValue().setBytes(bytes, valueStart, valueEnd - valueStart); if (isQuoted) { // We know this is a byte value so this is safe unescapeDoubleQuotes(sc.getValue().getByteChunk()); @@ -672,18 +645,14 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { /** - * Given the starting position of a token, this gets the end of the - * token, with no separator characters in between. + * Given the starting position of a token, this gets the end of the token, with no separator characters in between. * JVK */ - private int getTokenEndPosition(byte bytes[], int off, int end, - int version, boolean isName){ + private int getTokenEndPosition(byte bytes[], int off, int end, int version, boolean isName) { int pos = off; - while (pos < end && - (!isHttpSeparator((char)bytes[pos]) || - version == 0 && getAllowHttpSepsInV0() && bytes[pos] != '=' && - !isV0Separator((char)bytes[pos]) || - !isName && bytes[pos] == '=' && getAllowEqualsInValue())) { + while (pos < end && (!isHttpSeparator((char) bytes[pos]) || + version == 0 && getAllowHttpSepsInV0() && bytes[pos] != '=' && !isV0Separator((char) bytes[pos]) || + !isName && bytes[pos] == '=' && getAllowEqualsInValue())) { pos++; } @@ -697,8 +666,7 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { private boolean isHttpSeparator(final char c) { if (c < 0x20 || c >= 0x7f) { if (c != 0x09) { - throw new IllegalArgumentException( - "Control character in cookie value or attribute."); + throw new IllegalArgumentException("Control character in cookie value or attribute."); } } @@ -707,14 +675,12 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { /** - * Returns true if the byte is a separator as defined by V0 of the cookie - * spec. + * Returns true if the byte is a separator as defined by V0 of the cookie spec. */ private static boolean isV0Separator(final char c) { if (c < 0x20 || c >= 0x7f) { if (c != 0x09) { - throw new IllegalArgumentException( - "Control character in cookie value or attribute."); + throw new IllegalArgumentException("Control character in cookie value or attribute."); } } @@ -723,17 +689,16 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { /** - * Given a starting position after an initial quote character, this gets - * the position of the end quote. This escapes anything after a '\' char - * JVK RFC 2616 + * Given a starting position after an initial quote character, this gets the position of the end quote. This escapes + * anything after a '\' char JVK RFC 2616 */ - private static int getQuotedValueEndPosition(byte bytes[], int off, int end){ + private static int getQuotedValueEndPosition(byte bytes[], int off, int end) { int pos = off; while (pos < end) { if (bytes[pos] == '"') { return pos; } else if (bytes[pos] == '\\' && pos < (end - 1)) { - pos+=2; + pos += 2; } else { pos++; } @@ -744,7 +709,7 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { private static boolean equals(String s, byte b[], int start, int end) { - int blen = end-start; + int blen = end - start; if (b == null || blen != s.length()) { return false; } @@ -759,26 +724,16 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { /** - * Returns true if the byte is a whitespace character as - * defined in RFC2619 - * JVK + * Returns true if the byte is a whitespace character as defined in RFC2619 JVK */ private static boolean isWhiteSpace(final byte c) { // This switch statement is slightly slower // for my vm than the if statement. // Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-164) /* - switch (c) { - case ' ':; - case '\t':; - case '\n':; - case '\r':; - case '\f':; - return true; - default:; - return false; - } - */ + * switch (c) { case ' ':; case '\t':; case '\n':; case '\r':; case '\f':; return true; default:; return false; + * } + */ if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f') { return true; } else { @@ -810,12 +765,12 @@ public final class LegacyCookieProcessor extends CookieProcessorBase { int dest = 0; while (src < len) { - if (copy[src] == '\\' && src < len && copy[src+1] == '"') { + if (copy[src] == '\\' && src < len && copy[src + 1] == '"') { src++; } copy[dest] = copy[src]; - dest ++; - src ++; + dest++; + src++; } bc.setBytes(copy, 0, dest); } diff --git a/java/org/apache/tomcat/util/http/MimeHeaders.java b/java/org/apache/tomcat/util/http/MimeHeaders.java index 89007660a8..f0bb2aef48 100644 --- a/java/org/apache/tomcat/util/http/MimeHeaders.java +++ b/java/org/apache/tomcat/util/http/MimeHeaders.java @@ -65,26 +65,22 @@ import org.apache.tomcat.util.res.StringManager; /** - * Memory-efficient repository for Mime Headers. When the object is recycled, it - * will keep the allocated headers[] and all the MimeHeaderField - no GC is generated. - * <p> - * For input headers it is possible to use the MessageByte for Fields - so no GC - * will be generated. + * Memory-efficient repository for Mime Headers. When the object is recycled, it will keep the allocated headers[] and + * all the MimeHeaderField - no GC is generated. * <p> - * The only garbage is generated when using the String for header names/values - - * this can't be avoided when the servlet calls header methods, but is easy - * to avoid inside tomcat. The goal is to use _only_ MessageByte-based Fields, - * and reduce to 0 the memory overhead of tomcat. - * <p> - * - * TODO: - * <ul> - * <li>one-buffer parsing - for http (other protocols don't need that)</li> - * <li>remove unused methods</li> - * <li>External enumerations, with 0 GC.</li> - * <li>use HeaderName ID</li> - * </ul> - * + * For input headers it is possible to use the MessageByte for Fields - so no GC will be generated. + * <p> + * The only garbage is generated when using the String for header names/values - this can't be avoided when the servlet + * calls header methods, but is easy to avoid inside tomcat. The goal is to use _only_ MessageByte-based Fields, and + * reduce to 0 the memory overhead of tomcat. + * <p> + * TODO: + * <ul> + * <li>one-buffer parsing - for http (other protocols don't need that)</li> + * <li>remove unused methods</li> + * <li>External enumerations, with 0 GC.</li> + * <li>use HeaderName ID</li> + * </ul> * * @author d...@eng.sun.com * @author James Todd [go...@eng.sun.com] @@ -93,19 +89,17 @@ import org.apache.tomcat.util.res.StringManager; */ public class MimeHeaders { /** - * Initial size - should be == average number of headers per request - * XXX make it configurable ( fine-tuning of web-apps ) + * Initial size - should be == average number of headers per request XXX make it configurable ( fine-tuning of + * web-apps ) */ - public static final int DEFAULT_HEADER_SIZE=8; + public static final int DEFAULT_HEADER_SIZE = 8; - private static final StringManager sm = - StringManager.getManager("org.apache.tomcat.util.http"); + private static final StringManager sm = StringManager.getManager("org.apache.tomcat.util.http"); /** * The header fields. */ - private MimeHeaderField[] headers = new - MimeHeaderField[DEFAULT_HEADER_SIZE]; + private MimeHeaderField[] headers = new MimeHeaderField[DEFAULT_HEADER_SIZE]; /** * The current number of header fields. @@ -126,6 +120,7 @@ public class MimeHeaders { /** * Set limit on the number of header fields. + * * @param limit The new limit */ public void setLimit(int limit) { @@ -157,7 +152,7 @@ public class MimeHeaders { } /** - * EXPENSIVE!!! only for debugging. + * EXPENSIVE!!! only for debugging. */ @Override public String toString() { @@ -198,8 +193,9 @@ public class MimeHeaders { /** * @param n The header index - * @return the Nth header name, or null if there is no such header. - * This may be used to iterate through all header fields. + * + * @return the Nth header name, or null if there is no such header. This may be used to iterate through all header + * fields. */ public MessageBytes getName(int n) { return n >= 0 && n < count ? headers[n].getName() : null; @@ -207,8 +203,9 @@ public class MimeHeaders { /** * @param n The header index - * @return the Nth header value, or null if there is no such header. - * This may be used to iterate through all header fields. + * + * @return the Nth header value, or null if there is no such header. This may be used to iterate through all header + * fields. */ public MessageBytes getValue(int n) { return n >= 0 && n < count ? headers[n].getValue() : null; @@ -216,13 +213,15 @@ public class MimeHeaders { /** * Find the index of a header with the given name. - * @param name The header name + * + * @param name The header name * @param starting Index on which to start looking + * * @return the header index */ - public int findHeader( String name, int starting ) { + public int findHeader(String name, int starting) { // We can use a hash - but it's not clear how much - // benefit you can get - there is an overhead + // benefit you can get - there is an overhead // and the number of headers is small (4-5 ?) // Another problem is that we'll pay the overhead // of constructing the hashtable @@ -239,9 +238,9 @@ public class MimeHeaders { // -------------------- -------------------- /** - * Returns an enumeration of strings representing the header field names. - * Field names may appear multiple times in this enumeration, indicating - * that multiple fields with that name exist in this header. + * Returns an enumeration of strings representing the header field names. Field names may appear multiple times in + * this enumeration, indicating that multiple fields with that name exist in this header. + * * @return the enumeration */ public Enumeration<String> names() { @@ -256,13 +255,11 @@ public class MimeHeaders { /** - * Adds a partially constructed field to the header. This - * field has not had its name or value initialized. + * Adds a partially constructed field to the header. This field has not had its name or value initialized. */ private MimeHeaderField createHeader() { if (limit > -1 && count >= limit) { - throw new IllegalStateException(sm.getString( - "headers.maxCountFail", Integer.valueOf(limit))); + throw new IllegalStateException(sm.getString("headers.maxCountFail", Integer.valueOf(limit))); } MimeHeaderField mh; int len = headers.length; @@ -284,43 +281,46 @@ public class MimeHeaders { } /** - * Create a new named header , return the MessageBytes - * container for the new value + * Create a new named header , return the MessageBytes container for the new value + * * @param name The header name + * * @return the message bytes container for the value */ - public MessageBytes addValue( String name ) { + public MessageBytes addValue(String name) { MimeHeaderField mh = createHeader(); mh.getName().setString(name); return mh.getValue(); } /** - * Create a new named header using un-translated byte[]. - * The conversion to chars can be delayed until - * encoding is known. - * @param b The header name bytes + * Create a new named header using un-translated byte[]. The conversion to chars can be delayed until encoding is + * known. + * + * @param b The header name bytes * @param startN Offset - * @param len Length + * @param len Length + * * @return the message bytes container for the value */ public MessageBytes addValue(byte b[], int startN, int len) { - MimeHeaderField mhf=createHeader(); + MimeHeaderField mhf = createHeader(); mhf.getName().setBytes(b, startN, len); return mhf.getValue(); } /** - * Allow "set" operations, which removes all current values - * for this header. + * Allow "set" operations, which removes all current values for this header. + * * @param name The header name + * * @return the message bytes container for the value */ - public MessageBytes setValue( String name ) { - for ( int i = 0; i < count; i++ ) { - if(headers[i].getName().equalsIgnoreCase(name)) { - for ( int j=i+1; j < count; j++ ) { - if(headers[j].getName().equalsIgnoreCase(name)) { + public MessageBytes setValue(String name) { + for (int i = 0; i < count; i++) { + if (headers[i].getName().equalsIgnoreCase(name)) { + for (int j = i + 1; j < count; j++) { + if (headers[j].getName().equalsIgnoreCase(name)) { removeHeader(j--); } } @@ -332,12 +332,13 @@ public class MimeHeaders { return mh.getValue(); } - //-------------------- Getting headers -------------------- + // -------------------- Getting headers -------------------- /** - * Finds and returns a header field with the given name. If no such - * field exists, null is returned. If more than one such field is - * in the header, an arbitrary one is returned. + * Finds and returns a header field with the given name. If no such field exists, null is returned. If more than one + * such field is in the header, an arbitrary one is returned. + * * @param name The header name + * * @return the value */ public MessageBytes getValue(String name) { @@ -350,11 +351,13 @@ public class MimeHeaders { } /** - * Finds and returns a unique header field with the given name. If no such - * field exists, null is returned. If the specified header field is not - * unique then an {@link IllegalArgumentException} is thrown. + * Finds and returns a unique header field with the given name. If no such field exists, null is returned. If the + * specified header field is not unique then an {@link IllegalArgumentException} is thrown. + * * @param name The header name + * * @return the value if unique + * * @throws IllegalArgumentException if the header has multiple values */ public MessageBytes getUniqueValue(String name) { @@ -380,8 +383,8 @@ public class MimeHeaders { // -------------------- Removing -------------------- /** - * Removes a header field with the specified name. Does nothing - * if such a field could not be found. + * Removes a header field with the specified name. Does nothing if such a field could not be found. + * * @param name the name of the header field to be removed */ public void removeHeader(String name) { @@ -397,6 +400,7 @@ public class MimeHeaders { /** * Reset, move to the end and then reduce count by 1. + * * @param idx the index of the header to remove. */ public void removeHeader(int idx) { @@ -411,7 +415,7 @@ public class MimeHeaders { mh.recycle(); // Move the remaining headers - System.arraycopy(headers, idx + 1, headers, idx, count - idx -1); + System.arraycopy(headers, idx + 1, headers, idx, count - idx - 1); // Place the removed header at the end headers[count - 1] = mh; @@ -423,9 +427,8 @@ public class MimeHeaders { } /** - * Enumerate the distinct header names. Each nextElement() is O(n) ( a - * comparison is done with all previous elements ). This is less frequent than - * add() - we want to keep add O(1). + * Enumerate the distinct header names. Each nextElement() is O(n) ( a comparison is done with all previous elements ). + * This is less frequent than add() - we want to keep add O(1). */ class NamesEnumerator implements Enumeration<String> { private int pos; @@ -434,24 +437,24 @@ class NamesEnumerator implements Enumeration<String> { private final MimeHeaders headers; NamesEnumerator(MimeHeaders headers) { - this.headers=headers; - pos=0; + this.headers = headers; + pos = 0; size = headers.size(); findNext(); } private void findNext() { - next=null; - for(; pos< size; pos++ ) { - next=headers.getName( pos ).toString(); - for( int j=0; j<pos ; j++ ) { - if( headers.getName( j ).equalsIgnoreCase( next )) { + next = null; + for (; pos < size; pos++) { + next = headers.getName(pos).toString(); + for (int j = 0; j < pos; j++) { + if (headers.getName(j).equalsIgnoreCase(next)) { // duplicate. - next=null; + next = null; break; } } - if( next!=null ) { + if (next != null) { // it's not a duplicate break; } @@ -463,12 +466,12 @@ class NamesEnumerator implements Enumeration<String> { @Override public boolean hasMoreElements() { - return next!=null; + return next != null; } @Override public String nextElement() { - String current=next; + String current = next; findNext(); return current; } @@ -485,19 +488,19 @@ class ValuesEnumerator implements Enumeration<String> { private final String name; ValuesEnumerator(MimeHeaders headers, String name) { - this.name=name; - this.headers=headers; - pos=0; + this.name = name; + this.headers = headers; + pos = 0; size = headers.size(); findNext(); } private void findNext() { - next=null; - for(; pos< size; pos++ ) { - MessageBytes n1=headers.getName( pos ); - if( n1.equalsIgnoreCase( name )) { - next=headers.getValue( pos ); + next = null; + for (; pos < size; pos++) { + MessageBytes n1 = headers.getName(pos); + if (n1.equalsIgnoreCase(name)) { + next = headers.getValue(pos); break; } } @@ -506,12 +509,12 @@ class ValuesEnumerator implements Enumeration<String> { @Override public boolean hasMoreElements() { - return next!=null; + return next != null; } @Override public String nextElement() { - MessageBytes current=next; + MessageBytes current = next; findNext(); return current.toString(); } diff --git a/java/org/apache/tomcat/util/http/Parameters.java b/java/org/apache/tomcat/util/http/Parameters.java index 90b8fe0735..de99e5b190 100644 --- a/java/org/apache/tomcat/util/http/Parameters.java +++ b/java/org/apache/tomcat/util/http/Parameters.java @@ -44,12 +44,10 @@ public final class Parameters { private static final UserDataHelper maxParamCountLog = new UserDataHelper(log); - private static final StringManager sm = - StringManager.getManager("org.apache.tomcat.util.http"); + private static final StringManager sm = StringManager.getManager("org.apache.tomcat.util.http"); - private final Map<String,ArrayList<String>> paramHashValues = - new LinkedHashMap<>(); - private boolean didQueryParameters=false; + private final Map<String, ArrayList<String>> paramHashValues = new LinkedHashMap<>(); + private boolean didQueryParameters = false; private MessageBytes queryMB; @@ -63,8 +61,8 @@ public final class Parameters { private int parameterCount = 0; /** - * Set to the reason for the failure (the first failure if there is more - * than one) if there were failures during parameter parsing. + * Set to the reason for the failure (the first failure if there is more than one) if there were failures during + * parameter parsing. */ private FailReason parseFailedReason = null; @@ -72,8 +70,8 @@ public final class Parameters { // NO-OP } - public void setQuery( MessageBytes queryMB ) { - this.queryMB=queryMB; + public void setQuery(MessageBytes queryMB) { + this.queryMB = queryMB; } public void setLimit(int limit) { @@ -109,7 +107,7 @@ public final class Parameters { charset = DEFAULT_BODY_CHARSET; } this.charset = charset; - if(log.isDebugEnabled()) { + if (log.isDebugEnabled()) { log.debug("Set encoding to " + charset.name()); } } @@ -130,7 +128,7 @@ public final class Parameters { } this.queryStringCharset = queryStringCharset; - if(log.isDebugEnabled()) { + if (log.isDebugEnabled()) { log.debug("Set query string encoding to " + queryStringCharset.name()); } } @@ -187,11 +185,11 @@ public final class Parameters { return Collections.enumeration(paramHashValues.keySet()); } - public String getParameter(String name ) { + public String getParameter(String name) { handleQueryParameters(); ArrayList<String> values = paramHashValues.get(name); if (values != null) { - if(values.size() == 0) { + if (values.size() == 0) { return ""; } return values.get(0); @@ -199,6 +197,7 @@ public final class Parameters { return null; } } + // -------------------- Processing -------------------- /** * Process the query string into parameters @@ -214,7 +213,7 @@ public final class Parameters { return; } - if(log.isDebugEnabled()) { + if (log.isDebugEnabled()) { log.debug("Decoding query " + decodedQuery + " " + queryStringCharset.name()); } @@ -228,20 +227,18 @@ public final class Parameters { } - public void addParameter( String key, String value ) - throws IllegalStateException { + public void addParameter(String key, String value) throws IllegalStateException { - if( key==null ) { + if (key == null) { return; } - parameterCount ++; + parameterCount++; if (limit > -1 && parameterCount > limit) { // Processing this parameter will push us over the limit. ISE is // what Request.parseParts() uses for requests that are too big setParseFailedReason(FailReason.TOO_MANY_PARAMETERS); - throw new IllegalStateException(sm.getString( - "parameters.maxCountFail", Integer.valueOf(limit))); + throw new IllegalStateException(sm.getString("parameters.maxCountFail", Integer.valueOf(limit))); } ArrayList<String> values = paramHashValues.get(key); @@ -252,17 +249,17 @@ public final class Parameters { values.add(value); } - public void setURLDecoder( UDecoder u ) { - urlDec=u; + public void setURLDecoder(UDecoder u) { + urlDec = u; } // -------------------- Parameter parsing -------------------- // we are called from a single thread - we can do it the hard way // if needed - private final ByteChunk tmpName=new ByteChunk(); - private final ByteChunk tmpValue=new ByteChunk(); - private final ByteChunk origName=new ByteChunk(); - private final ByteChunk origValue=new ByteChunk(); + private final ByteChunk tmpName = new ByteChunk(); + private final ByteChunk tmpValue = new ByteChunk(); + private final ByteChunk origName = new ByteChunk(); + private final ByteChunk origValue = new ByteChunk(); /** * @deprecated This will be removed in Tomcat 9.0.x */ @@ -272,15 +269,14 @@ public final class Parameters { private static final Charset DEFAULT_URI_CHARSET = StandardCharsets.UTF_8; - public void processParameters( byte bytes[], int start, int len ) { + public void processParameters(byte bytes[], int start, int len) { processParameters(bytes, start, len, charset); } private void processParameters(byte bytes[], int start, int len, Charset charset) { - if(log.isDebugEnabled()) { - log.debug(sm.getString("parameters.bytes", - new String(bytes, start, len, DEFAULT_BODY_CHARSET))); + if (log.isDebugEnabled()) { + log.debug(sm.getString("parameters.bytes", new String(bytes, start, len, DEFAULT_BODY_CHARSET))); } int decodeFailCount = 0; @@ -288,7 +284,7 @@ public final class Parameters { int pos = start; int end = start + len; - while(pos < end) { + while (pos < end) { int nameStart = pos; int nameEnd = -1; int valueStart = -1; @@ -300,7 +296,7 @@ public final class Parameters { boolean parameterComplete = false; do { - switch(bytes[pos]) { + switch (bytes[pos]) { case '=': if (parsingName) { // Name finished. Value starts from next character @@ -318,7 +314,7 @@ public final class Parameters { nameEnd = pos; } else { // Value finished - valueEnd = pos; + valueEnd = pos; } parameterComplete = true; pos++; @@ -331,10 +327,10 @@ public final class Parameters { } else { decodeValue = true; } - pos ++; + pos++; break; default: - pos ++; + pos++; break; } } while (!parameterComplete && pos < end); @@ -342,18 +338,17 @@ public final class Parameters { if (pos == end) { if (nameEnd == -1) { nameEnd = pos; - } else if (valueStart > -1 && valueEnd == -1){ + } else if (valueStart > -1 && valueEnd == -1) { valueEnd = pos; } } if (log.isDebugEnabled() && valueStart == -1) { - log.debug(sm.getString("parameters.noequal", - Integer.valueOf(nameStart), Integer.valueOf(nameEnd), - new String(bytes, nameStart, nameEnd-nameStart, DEFAULT_BODY_CHARSET))); + log.debug(sm.getString("parameters.noequal", Integer.valueOf(nameStart), Integer.valueOf(nameEnd), + new String(bytes, nameStart, nameEnd - nameStart, DEFAULT_BODY_CHARSET))); } - if (nameEnd <= nameStart ) { + if (nameEnd <= nameStart) { if (valueStart == -1) { // && if (log.isDebugEnabled()) { @@ -367,13 +362,11 @@ public final class Parameters { if (logMode != null) { String extract; if (valueEnd > nameStart) { - extract = new String(bytes, nameStart, valueEnd - nameStart, - DEFAULT_BODY_CHARSET); + extract = new String(bytes, nameStart, valueEnd - nameStart, DEFAULT_BODY_CHARSET); } else { extract = ""; } - String message = sm.getString("parameters.invalidChunk", - Integer.valueOf(nameStart), + String message = sm.getString("parameters.invalidChunk", Integer.valueOf(nameStart), Integer.valueOf(valueEnd), extract); switch (logMode) { case INFO_THEN_DEBUG: @@ -445,8 +438,7 @@ public final class Parameters { String message = ise.getMessage(); switch (logMode) { case INFO_THEN_DEBUG: - message += sm.getString( - "parameters.maxCountFail.fallToDebug"); + message += sm.getString("parameters.maxCountFail.fallToDebug"); //$FALL-THROUGH$ case INFO: log.info(message); @@ -462,14 +454,14 @@ public final class Parameters { decodeFailCount++; if (decodeFailCount == 1 || log.isDebugEnabled()) { if (log.isDebugEnabled()) { - log.debug(sm.getString("parameters.decodeFail.debug", - origName.toString(), origValue.toString()), e); + log.debug( + sm.getString("parameters.decodeFail.debug", origName.toString(), origValue.toString()), + e); } else if (log.isInfoEnabled()) { UserDataHelper.Mode logMode = userDataLog.getNextMode(); if (logMode != null) { - String message = sm.getString( - "parameters.decodeFail.info", - tmpName.toString(), tmpValue.toString()); + String message = sm.getString("parameters.decodeFail.info", tmpName.toString(), + tmpValue.toString()); switch (logMode) { case INFO_THEN_DEBUG: message += sm.getString("parameters.fallToDebug"); @@ -497,9 +489,7 @@ public final class Parameters { if (decodeFailCount > 1 && !log.isDebugEnabled()) { UserDataHelper.Mode logMode = userDataLog.getNextMode(); if (logMode != null) { - String message = sm.getString( - "parameters.multipleDecodingFail", - Integer.valueOf(decodeFailCount)); + String message = sm.getString("parameters.multipleDecodingFail", Integer.valueOf(decodeFailCount)); switch (logMode) { case INFO_THEN_DEBUG: message += sm.getString("parameters.fallToDebug"); @@ -514,17 +504,16 @@ public final class Parameters { } } - private void urlDecode(ByteChunk bc) - throws IOException { - if( urlDec==null ) { - urlDec=new UDecoder(); + private void urlDecode(ByteChunk bc) throws IOException { + if (urlDec == null) { + urlDec = new UDecoder(); } urlDec.convert(bc, true); } /** - * @param data Parameter data - * @param encoding Encoding to use for encoded bytes + * @param data Parameter data + * @param encoding Encoding to use for encoded bytes * * @deprecated This method will be removed in Tomcat 9.0.x */ @@ -534,14 +523,14 @@ public final class Parameters { } public void processParameters(MessageBytes data, Charset charset) { - if( data==null || data.isNull() || data.getLength() <= 0 ) { + if (data == null || data.isNull() || data.getLength() <= 0) { return; } - if( data.getType() != MessageBytes.T_BYTES ) { + if (data.getType() != MessageBytes.T_BYTES) { data.toBytes(); } - ByteChunk bc=data.getByteChunk(); + ByteChunk bc = data.getByteChunk(); processParameters(bc.getBytes(), bc.getOffset(), bc.getLength(), charset); } diff --git a/java/org/apache/tomcat/util/http/RequestUtil.java b/java/org/apache/tomcat/util/http/RequestUtil.java index c8fb077f8a..b7a6332c36 100644 --- a/java/org/apache/tomcat/util/http/RequestUtil.java +++ b/java/org/apache/tomcat/util/http/RequestUtil.java @@ -30,15 +30,13 @@ public class RequestUtil { /** - * Normalize a relative URI path that may have relative values ("/./", - * "/../", and so on ) it it. <strong>WARNING</strong> - This method is - * useful only for normalizing application-generated paths. It does not + * Normalize a relative URI path that may have relative values ("/./", "/../", and so on ) it it. + * <strong>WARNING</strong> - This method is useful only for normalizing application-generated paths. It does not * try to perform security checks for malicious input. * * @param path Relative path to be normalized * - * @return The normalized path or <code>null</code> if the path cannot be - * normalized + * @return The normalized path or <code>null</code> if the path cannot be normalized */ public static String normalize(String path) { return normalize(path, true); @@ -46,16 +44,14 @@ public class RequestUtil { /** - * Normalize a relative URI path that may have relative values ("/./", - * "/../", and so on ) it it. <strong>WARNING</strong> - This method is - * useful only for normalizing application-generated paths. It does not + * Normalize a relative URI path that may have relative values ("/./", "/../", and so on ) it it. + * <strong>WARNING</strong> - This method is useful only for normalizing application-generated paths. It does not * try to perform security checks for malicious input. * - * @param path Relative path to be normalized + * @param path Relative path to be normalized * @param replaceBackSlash Should '\\' be replaced with '/' * - * @return The normalized path or <code>null</code> if the path cannot be - * normalized + * @return The normalized path or <code>null</code> if the path cannot be normalized */ public static String normalize(String path, boolean replaceBackSlash) { @@ -106,7 +102,7 @@ public class RequestUtil { break; } if (index == 0) { - return null; // Trying to go outside our context + return null; // Trying to go outside our context } int index2 = normalized.lastIndexOf('/', index - 1); normalized = normalized.substring(0, index2) + normalized.substring(index + 3); @@ -178,7 +174,9 @@ public class RequestUtil { * </ul> * * @param origin The origin URI + * * @return <code>true</code> if the origin was valid + * * @see <a href="http://tools.ietf.org/html/rfc952">RFC952</a> */ public static boolean isValidOrigin(String origin) { diff --git a/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java b/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java index 264dd45cf0..53339c2429 100644 --- a/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java +++ b/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java @@ -35,8 +35,8 @@ public class Rfc6265CookieProcessor extends CookieProcessorBase { private static final Log log = LogFactory.getLog(Rfc6265CookieProcessor.class); - private static final StringManager sm = - StringManager.getManager(Rfc6265CookieProcessor.class.getPackage().getName()); + private static final StringManager sm = StringManager + .getManager(Rfc6265CookieProcessor.class.getPackage().getName()); private static final BitSet domainValid = new BitSet(128); @@ -62,8 +62,7 @@ public class Rfc6265CookieProcessor extends CookieProcessorBase { @Override - public void parseCookieHeader(MimeHeaders headers, - ServerCookies serverCookies) { + public void parseCookieHeader(MimeHeaders headers, ServerCookies serverCookies) { if (headers == null) { // nothing to process @@ -75,8 +74,8 @@ public class Rfc6265CookieProcessor extends CookieProcessorBase { while (pos >= 0) { MessageBytes cookieValue = headers.getValue(pos); - if (cookieValue != null && !cookieValue.isNull() ) { - if (cookieValue.getType() != MessageBytes.T_BYTES ) { + if (cookieValue != null && !cookieValue.isNull()) { + if (cookieValue.getType() != MessageBytes.T_BYTES) { if (log.isDebugEnabled()) { Exception e = new Exception(); // TODO: Review this in light of HTTP/2 @@ -89,8 +88,7 @@ public class Rfc6265CookieProcessor extends CookieProcessorBase { } ByteChunk bc = cookieValue.getByteChunk(); - Cookie.parseCookie(bc.getBytes(), bc.getOffset(), bc.getLength(), - serverCookies); + Cookie.parseCookie(bc.getBytes(), bc.getOffset(), bc.getLength(), serverCookies); } // search from the next position @@ -111,11 +109,10 @@ public class Rfc6265CookieProcessor extends CookieProcessorBase { // Can't use StringBuilder due to DateFormat StringBuffer header = new StringBuffer(); - /* TODO: Name validation takes place in Cookie and cannot be configured - * per Context. Moving it to here would allow per Context config - * but delay validation until the header is generated. However, - * the spec requires an IllegalArgumentException on Cookie - * generation. + /* + * TODO: Name validation takes place in Cookie and cannot be configured per Context. Moving it to here would + * allow per Context config but delay validation until the header is generated. However, the spec requires an + * IllegalArgumentException on Cookie generation. */ header.append(cookie.getName()); header.append('='); @@ -137,14 +134,12 @@ public class Rfc6265CookieProcessor extends CookieProcessorBase { // browsers. See http://tomcat.markmail.org/thread/g6sipbofsjossacn // Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format ) - header.append ("; Expires="); + header.append("; Expires="); // To expire immediately we need to set the time in past if (maxAge == 0) { header.append(ANCIENT_DATE); } else { - COOKIE_DATE_FORMAT.get().format( - new Date(System.currentTimeMillis() + maxAge * 1000L), - header, + COOKIE_DATE_FORMAT.get().format(new Date(System.currentTimeMillis() + maxAge * 1000L), header, new FieldPosition(0)); } } @@ -195,8 +190,8 @@ public class Rfc6265CookieProcessor extends CookieProcessorBase { for (int i = start; i < end; i++) { char c = chars[i]; if (c < 0x21 || c == 0x22 || c == 0x2c || c == 0x3b || c == 0x5c || c == 0x7f) { - throw new IllegalArgumentException(sm.getString( - "rfc6265CookieProcessor.invalidCharInValue", Integer.toString(c))); + throw new IllegalArgumentException( + sm.getString("rfc6265CookieProcessor.invalidCharInValue", Integer.toString(c))); } } } @@ -211,25 +206,21 @@ public class Rfc6265CookieProcessor extends CookieProcessorBase { prev = cur; cur = chars[i]; if (!domainValid.get(cur)) { - throw new IllegalArgumentException(sm.getString( - "rfc6265CookieProcessor.invalidDomain", domain)); + throw new IllegalArgumentException(sm.getString("rfc6265CookieProcessor.invalidDomain", domain)); } // labels must start with a letter or number if ((prev == '.' || prev == -1) && (cur == '.' || cur == '-')) { - throw new IllegalArgumentException(sm.getString( - "rfc6265CookieProcessor.invalidDomain", domain)); + throw new IllegalArgumentException(sm.getString("rfc6265CookieProcessor.invalidDomain", domain)); } // labels must end with a letter or number if (prev == '-' && cur == '.') { - throw new IllegalArgumentException(sm.getString( - "rfc6265CookieProcessor.invalidDomain", domain)); + throw new IllegalArgumentException(sm.getString("rfc6265CookieProcessor.invalidDomain", domain)); } i++; } // domain must end with a label if (cur == '.' || cur == '-') { - throw new IllegalArgumentException(sm.getString( - "rfc6265CookieProcessor.invalidDomain", domain)); + throw new IllegalArgumentException(sm.getString("rfc6265CookieProcessor.invalidDomain", domain)); } } @@ -239,8 +230,7 @@ public class Rfc6265CookieProcessor extends CookieProcessorBase { for (char ch : chars) { if (ch < 0x20 || ch > 0x7E || ch == ';') { - throw new IllegalArgumentException(sm.getString( - "rfc6265CookieProcessor.invalidPath", path)); + throw new IllegalArgumentException(sm.getString("rfc6265CookieProcessor.invalidPath", path)); } } } diff --git a/java/org/apache/tomcat/util/http/ServerCookie.java b/java/org/apache/tomcat/util/http/ServerCookie.java index 23c088797f..6a590a4b87 100644 --- a/java/org/apache/tomcat/util/http/ServerCookie.java +++ b/java/org/apache/tomcat/util/http/ServerCookie.java @@ -22,27 +22,25 @@ 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 ). + * 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 ). * <p> - * Tomcat.core uses this recyclable object to represent cookies, - * and the facade will convert it to the external representation. + * 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(); + 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 final MessageBytes path = MessageBytes.newInstance(); + private final MessageBytes domain = MessageBytes.newInstance(); // Version 1 (RFC2109) attributes - private final MessageBytes comment=MessageBytes.newInstance(); + private final MessageBytes comment = MessageBytes.newInstance(); private int version = 0; // Note: Servlet Spec =< 3.0 only refers to Netscape and RFC2109, not RFC2965 @@ -62,7 +60,7 @@ public class ServerCookie implements Serializable { comment.recycle(); path.recycle(); domain.recycle(); - version=0; + version = 0; } public MessageBytes getComment() { @@ -98,8 +96,7 @@ public class ServerCookie implements Serializable { @Override public String toString() { - return "Cookie " + getName() + "=" + getValue() + " ; " - + getVersion() + " " + getPath() + " " + getDomain(); + return "Cookie " + getName() + "=" + getValue() + " ; " + getVersion() + " " + getPath() + " " + getDomain(); } } diff --git a/java/org/apache/tomcat/util/http/ServerCookies.java b/java/org/apache/tomcat/util/http/ServerCookies.java index 93c9e699d5..f40469f49e 100644 --- a/java/org/apache/tomcat/util/http/ServerCookies.java +++ b/java/org/apache/tomcat/util/http/ServerCookies.java @@ -37,19 +37,18 @@ public class ServerCookies { /** - * Register a new, initialized cookie. Cookies are recycled, and most of the - * time an existing ServerCookie object is returned. The caller can set the - * name/value and attributes for the cookie. + * Register a new, initialized cookie. Cookies are recycled, and most of the time an existing ServerCookie object is + * returned. The caller can set the name/value and attributes for the cookie. + * * @return the new cookie */ public ServerCookie addCookie() { if (limit > -1 && cookieCount >= limit) { - throw new IllegalArgumentException( - sm.getString("cookies.maxCountFail", Integer.valueOf(limit))); + throw new IllegalArgumentException(sm.getString("cookies.maxCountFail", Integer.valueOf(limit))); } if (cookieCount >= serverCookies.length) { - int newSize = limit > -1 ? Math.min(2*cookieCount, limit) : 2*cookieCount; + int newSize = limit > -1 ? Math.min(2 * cookieCount, limit) : 2 * cookieCount; ServerCookie scookiesTmp[] = new ServerCookie[newSize]; System.arraycopy(serverCookies, 0, scookiesTmp, 0, cookieCount); serverCookies = scookiesTmp; --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org