Author: markt Date: Tue Jun 21 14:29:49 2011 New Revision: 1138019 URL: http://svn.apache.org/viewvc?rev=1138019&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=51400 Avoid known bottleneck in JVM when converting between Strings and bytes by always providing a Charset rather than an encoding name. Based on a patch by Dave Engberg.
Note: There are some Charsets that the JVM must support and in those cases Charset.forName(String) should not throw an exception. Modified: tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java tomcat/trunk/java/org/apache/catalina/ha/backend/MultiCastSender.java tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java tomcat/trunk/java/org/apache/catalina/realm/JNDIRealm.java tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java tomcat/trunk/java/org/apache/catalina/tribes/membership/Constants.java tomcat/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java tomcat/trunk/java/org/apache/catalina/tribes/util/Arrays.java tomcat/trunk/java/org/apache/catalina/util/RequestUtil.java tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java tomcat/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java tomcat/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java tomcat/trunk/java/org/apache/jasper/compiler/PageDataImpl.java tomcat/trunk/java/org/apache/jasper/compiler/SmapUtil.java tomcat/trunk/java/org/apache/naming/resources/ProxyDirContext.java tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java tomcat/trunk/java/org/apache/tomcat/util/buf/ByteChunk.java tomcat/trunk/java/org/apache/tomcat/util/buf/MessageBytes.java tomcat/trunk/java/org/apache/tomcat/util/http/Parameters.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java (original) +++ tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java Tue Jun 21 14:29:49 2011 @@ -26,6 +26,7 @@ import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; +import java.nio.charset.Charset; import org.apache.catalina.util.Base64; import org.apache.tools.ant.BuildException; @@ -200,7 +201,8 @@ public abstract class AbstractCatalinaTa // Set up an authorization header with our credentials String input = username + ":" + password; - String output = Base64.encode(input.getBytes()); + String output = + Base64.encode(input.getBytes(Charset.defaultCharset())); hconn.setRequestProperty("Authorization", "Basic " + output); Modified: tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java Tue Jun 21 14:29:49 2011 @@ -20,6 +20,7 @@ package org.apache.catalina.authenticato import java.io.IOException; +import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Principal; @@ -378,7 +379,8 @@ public class DigestAuthenticator extends byte[] buffer; synchronized (md5Helper) { - buffer = md5Helper.digest(ipTimeKey.getBytes()); + buffer = md5Helper.digest( + ipTimeKey.getBytes(Charset.defaultCharset())); } return currentTime + ":" + md5Encoder.encode(buffer); @@ -617,7 +619,8 @@ public class DigestAuthenticator extends request.getRemoteAddr() + ":" + nOnceTime + ":" + key; byte[] buffer = null; synchronized (md5Helper) { - buffer = md5Helper.digest(serverIpTimeKey.getBytes()); + buffer = md5Helper.digest( + serverIpTimeKey.getBytes(Charset.defaultCharset())); } String md5ServerIpTimeKey = md5Encoder.encode(buffer); if (!md5ServerIpTimeKey.equals(md5clientIpTimeKey)) { @@ -679,7 +682,7 @@ public class DigestAuthenticator extends byte[] buffer; synchronized (md5Helper) { - buffer = md5Helper.digest(a2.getBytes()); + buffer = md5Helper.digest(a2.getBytes(Charset.defaultCharset())); } String md5a2 = md5Encoder.encode(buffer); Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Tue Jun 21 14:29:49 2011 @@ -20,6 +20,7 @@ package org.apache.catalina.connector; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.EnumSet; import javax.servlet.RequestDispatcher; @@ -784,6 +785,13 @@ public class CoyoteAdapter implements Ad if (enc == null) { enc = "ISO-8859-1"; } + Charset charset = null; + try { + charset = B2CConverter.getCharset(enc); + } catch (UnsupportedEncodingException e1) { + log.warn(sm.getString("coyoteAdapter.parsePathParam", + enc)); + } if (log.isDebugEnabled()) { log.debug(sm.getString("coyoteAdapter.debug", "uriBC", @@ -808,15 +816,9 @@ public class CoyoteAdapter implements Ad String pv = null; if (pathParamEnd >= 0) { - try { - pv = (new String(uriBC.getBuffer(), start + pathParamStart, - pathParamEnd - pathParamStart, enc)); - } catch (UnsupportedEncodingException e) { - if (!warnedEncoding) { - log.warn(sm.getString("coyoteAdapter.parsePathParam", - enc)); - warnedEncoding = true; - } + if (charset != null) { + pv = new String(uriBC.getBuffer(), start + pathParamStart, + pathParamEnd - pathParamStart, charset); } // Extract path param from decoded request URI byte[] buf = uriBC.getBuffer(); @@ -827,15 +829,9 @@ public class CoyoteAdapter implements Ad uriBC.setBytes(buf, start, end - start - pathParamEnd + semicolon); } else { - try { - pv = (new String(uriBC.getBuffer(), start + pathParamStart, - (end - start) - pathParamStart, enc)); - } catch (UnsupportedEncodingException e) { - if (!warnedEncoding) { - log.warn(sm.getString("coyoteAdapter.parsePathParam", - enc)); - warnedEncoding = true; - } + if (charset != null) { + pv = new String(uriBC.getBuffer(), start + pathParamStart, + (end - start) - pathParamStart, charset); } uriBC.setEnd(start + semicolon); } Modified: tomcat/trunk/java/org/apache/catalina/ha/backend/MultiCastSender.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/backend/MultiCastSender.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/ha/backend/MultiCastSender.java (original) +++ tomcat/trunk/java/org/apache/catalina/ha/backend/MultiCastSender.java Tue Jun 21 14:29:49 2011 @@ -18,11 +18,11 @@ package org.apache.catalina.ha.backend; -import java.io.UnsupportedEncodingException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.MulticastSocket; +import java.nio.charset.Charset; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; @@ -34,6 +34,7 @@ public class MultiCastSender implements Sender { private static final Log log = LogFactory.getLog(HeartbeatListener.class); + private static final Charset US_ASCII = Charset.forName("US-ASCII"); HeartbeatListener config = null; @@ -68,11 +69,7 @@ public class MultiCastSender } byte[] buf; - try { - buf = mess.getBytes("US-ASCII"); - } catch (UnsupportedEncodingException ex) { - buf = mess.getBytes(); - } + buf = mess.getBytes(US_ASCII); DatagramPacket data = new DatagramPacket(buf, buf.length, group, config.getMultiport()); try { s.send(data); Modified: tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java (original) +++ tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Tue Jun 21 14:29:49 2011 @@ -33,6 +33,7 @@ import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.charset.Charset; import java.security.AccessControlException; import java.security.AccessController; import java.security.CodeSource; @@ -125,6 +126,7 @@ public class WebappClassLoader private static final org.apache.juli.logging.Log log= org.apache.juli.logging.LogFactory.getLog( WebappClassLoader.class ); + private static final Charset CHARSET_UTF8 = Charset.forName("UTF-8"); /** * List of ThreadGroup names to ignore when scanning for web application * started threads that need to be shut down. @@ -3086,7 +3088,7 @@ public class WebappClassLoader // http://svn.apache.org/viewvc?view=revision&revision=303915 String str = new String(binaryContent,0,pos); try { - binaryContent = str.getBytes("UTF-8"); + binaryContent = str.getBytes(CHARSET_UTF8); } catch (Exception e) { return null; } Modified: tomcat/trunk/java/org/apache/catalina/realm/JNDIRealm.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/JNDIRealm.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/realm/JNDIRealm.java (original) +++ tomcat/trunk/java/org/apache/catalina/realm/JNDIRealm.java Tue Jun 21 14:29:49 2011 @@ -20,6 +20,7 @@ package org.apache.catalina.realm; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.nio.charset.Charset; import java.security.Principal; import java.text.MessageFormat; import java.util.ArrayList; @@ -1531,7 +1532,7 @@ public class JNDIRealm extends RealmBase synchronized (this) { password = password.substring(5); md.reset(); - md.update(credentials.getBytes()); + md.update(credentials.getBytes(Charset.defaultCharset())); String digestedPassword = Base64.encode(md.digest()); validated = password.equals(digestedPassword); } @@ -1542,12 +1543,13 @@ public class JNDIRealm extends RealmBase password = password.substring(6); md.reset(); - md.update(credentials.getBytes()); + md.update(credentials.getBytes(Charset.defaultCharset())); // Decode stored password. ByteChunk pwbc = new ByteChunk(password.length()); try { - pwbc.append(password.getBytes(), 0, password.length()); + pwbc.append(password.getBytes(Charset.defaultCharset()), + 0, password.length()); } catch (IOException e) { // Should never happen containerLog.error("Could not append password bytes to chunk: ", e); Modified: tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java Tue Jun 21 14:29:49 2011 @@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener import java.beans.PropertyChangeSupport; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Principal; @@ -52,6 +53,7 @@ import org.apache.catalina.util.Lifecycl import org.apache.catalina.util.MD5Encoder; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.util.buf.B2CConverter; import org.apache.tomcat.util.buf.HexUtils; import org.apache.tomcat.util.res.StringManager; import org.ietf.jgss.GSSContext; @@ -244,6 +246,14 @@ public abstract class RealmBase extends digestEncoding = charset; } + protected Charset getDigestCharset() throws UnsupportedEncodingException { + if (digestEncoding == null) { + return Charset.defaultCharset(); + } else { + return B2CConverter.getCharset(getDigestEncoding()); + } + } + /** * Return descriptive information about this Realm implementation and * the corresponding version number, in the format @@ -373,15 +383,11 @@ public abstract class RealmBase extends } byte[] valueBytes = null; - if(getDigestEncoding() == null) { - valueBytes = serverDigestValue.getBytes(); - } else { - try { - valueBytes = serverDigestValue.getBytes(getDigestEncoding()); - } catch (UnsupportedEncodingException uee) { - log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); - throw new IllegalArgumentException(uee.getMessage()); - } + try { + valueBytes = serverDigestValue.getBytes(getDigestCharset()); + } catch (UnsupportedEncodingException uee) { + log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); + throw new IllegalArgumentException(uee.getMessage()); } String serverDigest = null; @@ -1130,15 +1136,11 @@ public abstract class RealmBase extends md.reset(); byte[] bytes = null; - if(getDigestEncoding() == null) { - bytes = credentials.getBytes(); - } else { - try { - bytes = credentials.getBytes(getDigestEncoding()); - } catch (UnsupportedEncodingException uee) { - log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); - throw new IllegalArgumentException(uee.getMessage()); - } + try { + bytes = credentials.getBytes(getDigestCharset()); + } catch (UnsupportedEncodingException uee) { + log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); + throw new IllegalArgumentException(uee.getMessage()); } md.update(bytes); @@ -1177,15 +1179,11 @@ public abstract class RealmBase extends + getPassword(username); byte[] valueBytes = null; - if(getDigestEncoding() == null) { - valueBytes = digestValue.getBytes(); - } else { - try { - valueBytes = digestValue.getBytes(getDigestEncoding()); - } catch (UnsupportedEncodingException uee) { - log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); - throw new IllegalArgumentException(uee.getMessage()); - } + try { + valueBytes = digestValue.getBytes(getDigestCharset()); + } catch (UnsupportedEncodingException uee) { + log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); + throw new IllegalArgumentException(uee.getMessage()); } byte[] digest = null; Modified: tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java (original) +++ tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java Tue Jun 21 14:29:49 2011 @@ -24,6 +24,7 @@ import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; +import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; @@ -1151,8 +1152,8 @@ public class WebdavServlet + lock.depth + "-" + lock.owner + "-" + lock.tokens + "-" + lock.expiresAt + "-" + System.currentTimeMillis() + "-" + secret; - String lockToken = - md5Encoder.encode(md5Helper.digest(lockTokenStr.getBytes())); + String lockToken = md5Encoder.encode(md5Helper.digest( + lockTokenStr.getBytes(Charset.defaultCharset()))); if ( (exists) && (object instanceof DirContext) && (lock.depth == maxDepth) ) { Modified: tomcat/trunk/java/org/apache/catalina/tribes/membership/Constants.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/tribes/membership/Constants.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/tribes/membership/Constants.java (original) +++ tomcat/trunk/java/org/apache/catalina/tribes/membership/Constants.java Tue Jun 21 14:29:49 2011 @@ -18,6 +18,8 @@ package org.apache.catalina.tribes.membership; +import java.nio.charset.Charset; + import org.apache.catalina.tribes.util.Arrays; @@ -34,7 +36,9 @@ public class Constants { public static final String Package = "org.apache.catalina.tribes.membership"; public static void main(String[] args) throws Exception { - System.out.println(Arrays.toString("TRIBES-B".getBytes())); - System.out.println(Arrays.toString("TRIBES-E".getBytes())); + System.out.println(Arrays.toString( + "TRIBES-B".getBytes(Charset.defaultCharset()))); + System.out.println(Arrays.toString( + "TRIBES-E".getBytes(Charset.defaultCharset()))); } } Modified: tomcat/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java (original) +++ tomcat/trunk/java/org/apache/catalina/tribes/tipis/AbstractReplicatedMap.java Tue Jun 21 14:29:49 2011 @@ -21,7 +21,7 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.Serializable; -import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -71,7 +71,8 @@ public abstract class AbstractReplicated /** * Used to identify the map */ - final String chset = "ISO-8859-1"; + private static final Charset CHARSET_ISO_8859_1 = + Charset.forName("ISO-8859-1"); //------------------------------------------------------------------------------ // INSTANCE VARIABLES @@ -204,14 +205,9 @@ public abstract class AbstractReplicated this.channel = channel; this.rpcTimeout = timeout; - try { - this.mapname = mapContextName; - //unique context is more efficient if it is stored as bytes - this.mapContextName = mapContextName.getBytes(chset); - } catch (UnsupportedEncodingException x) { - log.warn("Unable to encode mapContextName[" + mapContextName + "] using getBytes(" + chset +") using default getBytes()", x); - this.mapContextName = mapContextName.getBytes(); - } + this.mapname = mapContextName; + //unique context is more efficient if it is stored as bytes + this.mapContextName = mapContextName.getBytes(CHARSET_ISO_8859_1); if ( log.isTraceEnabled() ) log.trace("Created Lazy Map with name:"+mapContextName+", bytes:"+Arrays.toString(this.mapContextName)); //create an rpc channel and add the map as a listener @@ -918,7 +914,9 @@ public abstract class AbstractReplicated protected void printMap(String header) { try { System.out.println("\nDEBUG MAP:"+header); - System.out.println("Map["+ new String(mapContextName, chset) + ", Map Size:" + super.size()); + System.out.println("Map[" + + new String(mapContextName, CHARSET_ISO_8859_1) + + ", Map Size:" + super.size()); Member[] mbrs = getMapMembers(); for ( int i=0; i<mbrs.length;i++ ) { System.out.println("Mbr["+(i+1)+"="+mbrs[i].getName()); Modified: tomcat/trunk/java/org/apache/catalina/tribes/util/Arrays.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/tribes/util/Arrays.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/tribes/util/Arrays.java (original) +++ tomcat/trunk/java/org/apache/catalina/tribes/util/Arrays.java Tue Jun 21 14:29:49 2011 @@ -16,7 +16,7 @@ */ package org.apache.catalina.tribes.util; -import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; @@ -27,15 +27,14 @@ import org.apache.catalina.tribes.Unique import org.apache.catalina.tribes.group.AbsoluteOrder; import org.apache.catalina.tribes.membership.MemberImpl; import org.apache.catalina.tribes.membership.Membership; -import org.apache.juli.logging.Log; -import org.apache.juli.logging.LogFactory; /** * @author Filip Hanik * @version 1.0 */ public class Arrays { - private static final Log log = LogFactory.getLog(Arrays.class); + private static final Charset CHARSET_ISO_8859_1 = + Charset.forName("ISO-8859-1"); public static boolean contains(byte[] source, int srcoffset, byte[] key, int keyoffset, int length) { if ( srcoffset < 0 || srcoffset >= source.length) throw new ArrayIndexOutOfBoundsException("srcoffset is out of bounds."); @@ -218,13 +217,6 @@ public class Arrays { public static byte[] convert(String s) { - try { - return s.getBytes("ISO-8859-1"); - }catch (UnsupportedEncodingException ux ) { - log.error("Unable to convert ["+s+"] into a byte[] using ISO-8859-1 encoding, falling back to default encoding."); - return s.getBytes(); - } + return s.getBytes(CHARSET_ISO_8859_1); } - - } \ No newline at end of file Modified: tomcat/trunk/java/org/apache/catalina/util/RequestUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/util/RequestUtil.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/util/RequestUtil.java (original) +++ tomcat/trunk/java/org/apache/catalina/util/RequestUtil.java Tue Jun 21 14:29:49 2011 @@ -19,12 +19,14 @@ package org.apache.catalina.util; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.Map; import java.util.TimeZone; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.util.buf.B2CConverter; import org.apache.tomcat.util.res.StringManager; @@ -199,9 +201,9 @@ public final class RequestUtil { byte[] bytes = null; try { if (encoding == null) { - bytes = data.getBytes(); + bytes = data.getBytes(Charset.defaultCharset()); } else { - bytes = data.getBytes(encoding); + bytes = data.getBytes(B2CConverter.getCharset(encoding)); } parseParameters(map, bytes, encoding); } catch (UnsupportedEncodingException uee) { @@ -264,9 +266,9 @@ public final class RequestUtil { byte[] bytes = null; try { if (enc == null) { - bytes = str.getBytes(); + bytes = str.getBytes(Charset.defaultCharset()); } else { - bytes = str.getBytes(enc); + bytes = str.getBytes(B2CConverter.getCharset(enc)); } } catch (UnsupportedEncodingException uee) { log.debug(sm.getString("requestUtil.urlDecode.uee", enc), uee); @@ -337,7 +339,7 @@ public final class RequestUtil { } if (enc != null) { try { - return new String(bytes, 0, ox, enc); + return new String(bytes, 0, ox, B2CConverter.getCharset(enc)); } catch (UnsupportedEncodingException uee) { log.debug(sm.getString("requestUtil.urlDecode.uee", enc), uee); return null; @@ -411,6 +413,8 @@ public final class RequestUtil { public static void parseParameters(Map<String,String[]> map, byte[] data, String encoding) throws UnsupportedEncodingException { + Charset charset = B2CConverter.getCharset(encoding); + if (data != null && data.length > 0) { int ix = 0; int ox = 0; @@ -420,7 +424,7 @@ public final class RequestUtil { byte c = data[ix++]; switch ((char) c) { case '&': - value = new String(data, 0, ox, encoding); + value = new String(data, 0, ox, charset); if (key != null) { putMapEntry(map, key, value); key = null; @@ -429,7 +433,7 @@ public final class RequestUtil { break; case '=': if (key == null) { - key = new String(data, 0, ox, encoding); + key = new String(data, 0, ox, charset); ox = 0; } else { data[ox++] = c; @@ -448,7 +452,7 @@ public final class RequestUtil { } //The last value does not end in '&'. So save it now. if (key != null) { - value = new String(data, 0, ox, encoding); + value = new String(data, 0, ox, charset); putMapEntry(map, key, value); } } Modified: tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java (original) +++ tomcat/trunk/java/org/apache/catalina/valves/SSLValve.java Tue Jun 21 14:29:49 2011 @@ -19,6 +19,7 @@ package org.apache.catalina.valves; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.nio.charset.Charset; import java.security.NoSuchProviderException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; @@ -94,7 +95,8 @@ public class SSLValve extends ValveBase String strcert4 = strcert3.concat(strcert2); String strcerts = strcert4.concat("\n-----END CERTIFICATE-----\n"); // ByteArrayInputStream bais = new ByteArrayInputStream(strcerts.getBytes("UTF-8")); - ByteArrayInputStream bais = new ByteArrayInputStream(strcerts.getBytes()); + ByteArrayInputStream bais = new ByteArrayInputStream( + strcerts.getBytes(Charset.defaultCharset())); X509Certificate jsseCerts[] = null; String providerName = (String) request.getConnector().getProperty( "clientCertProvider"); Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java Tue Jun 21 14:29:49 2011 @@ -21,6 +21,7 @@ package org.apache.coyote.http11; import java.io.EOFException; import java.io.IOException; import java.nio.channels.Selector; +import java.nio.charset.Charset; import org.apache.coyote.InputBuffer; import org.apache.coyote.Request; @@ -45,6 +46,9 @@ public class InternalNioInputBuffer exte private static final org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory.getLog(InternalNioInputBuffer.class); + private static final Charset DEFAULT_CHARSET = + Charset.forName("ISO-8859-1"); + // -------------------------------------------------------------- Constants enum HeaderParseStatus {DONE, HAVE_MORE_HEADERS, NEED_MORE_DATA} @@ -256,7 +260,7 @@ public class InternalNioInputBuffer exte parsingRequestLinePhase = 2; if (log.isDebugEnabled()) { log.debug("Received [" - + new String(buf, pos, lastValid - pos, "ISO-8859-1") + + new String(buf, pos, lastValid - pos, DEFAULT_CHARSET) + "]"); } } Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java Tue Jun 21 14:29:49 2011 @@ -18,6 +18,7 @@ package org.apache.coyote.http11.filters; import java.io.IOException; +import java.nio.charset.Charset; import org.apache.coyote.InputBuffer; import org.apache.coyote.Request; @@ -47,7 +48,8 @@ public class BufferedInputFilter impleme // ----------------------------------------------------- Static Initializer static { - ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length()); + ENCODING.setBytes(ENCODING_NAME.getBytes(Charset.defaultCharset()), 0, + ENCODING_NAME.length()); } Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java Tue Jun 21 14:29:49 2011 @@ -19,6 +19,7 @@ package org.apache.coyote.http11.filters import java.io.EOFException; import java.io.IOException; +import java.nio.charset.Charset; import org.apache.coyote.InputBuffer; import org.apache.coyote.Request; @@ -50,7 +51,8 @@ public class ChunkedInputFilter implemen static { - ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length()); + ENCODING.setBytes(ENCODING_NAME.getBytes(Charset.defaultCharset()), 0, + ENCODING_NAME.length()); } Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java Tue Jun 21 14:29:49 2011 @@ -18,6 +18,7 @@ package org.apache.coyote.http11.filters; import java.io.IOException; +import java.nio.charset.Charset; import org.apache.coyote.InputBuffer; import org.apache.coyote.Request; @@ -43,7 +44,8 @@ public class IdentityInputFilter impleme static { - ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length()); + ENCODING.setBytes(ENCODING_NAME.getBytes(Charset.defaultCharset()), 0, + ENCODING_NAME.length()); } Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java Tue Jun 21 14:29:49 2011 @@ -18,6 +18,7 @@ package org.apache.coyote.http11.filters; import java.io.IOException; +import java.nio.charset.Charset; import org.apache.coyote.InputBuffer; import org.apache.coyote.Request; @@ -44,7 +45,8 @@ public class VoidInputFilter implements static { - ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length()); + ENCODING.setBytes(ENCODING_NAME.getBytes(Charset.defaultCharset()), 0, + ENCODING_NAME.length()); } Modified: tomcat/trunk/java/org/apache/jasper/compiler/PageDataImpl.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/PageDataImpl.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/jasper/compiler/PageDataImpl.java (original) +++ tomcat/trunk/java/org/apache/jasper/compiler/PageDataImpl.java Tue Jun 21 14:29:49 2011 @@ -19,7 +19,7 @@ package org.apache.jasper.compiler; import java.io.ByteArrayInputStream; import java.io.CharArrayWriter; import java.io.InputStream; -import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.ListIterator; import javax.servlet.jsp.tagext.PageData; @@ -53,6 +53,7 @@ class PageDataImpl extends PageData impl private static final String JSP_VERSION = "2.0"; private static final String CDATA_START_SECTION = "<![CDATA[\n"; private static final String CDATA_END_SECTION = "]]>\n"; + private static final Charset CHARSET_UTF8 = Charset.forName("UTF-8"); // string buffer used to build XML view private StringBuilder buf; @@ -85,13 +86,7 @@ class PageDataImpl extends PageData impl */ @Override public InputStream getInputStream() { - // Turn StringBuilder into InputStream - try { - return new ByteArrayInputStream(buf.toString().getBytes("UTF-8")); - } catch (UnsupportedEncodingException uee) { - // should never happen - throw new RuntimeException(uee.toString()); - } + return new ByteArrayInputStream(buf.toString().getBytes(CHARSET_UTF8)); } /* Modified: tomcat/trunk/java/org/apache/jasper/compiler/SmapUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/SmapUtil.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/jasper/compiler/SmapUtil.java (original) +++ tomcat/trunk/java/org/apache/jasper/compiler/SmapUtil.java Tue Jun 21 14:29:49 2011 @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -159,7 +160,8 @@ public class SmapUtil { for (int i = 0; i < smap.length; i += 2) { File outServlet = new File(smap[i]); - SDEInstaller.install(outServlet, smap[i+1].getBytes()); + SDEInstaller.install(outServlet, + smap[i+1].getBytes(Charset.defaultCharset())); } } Modified: tomcat/trunk/java/org/apache/naming/resources/ProxyDirContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/resources/ProxyDirContext.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/naming/resources/ProxyDirContext.java (original) +++ tomcat/trunk/java/org/apache/naming/resources/ProxyDirContext.java Tue Jun 21 14:29:49 2011 @@ -21,6 +21,7 @@ package org.apache.naming.resources; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.Charset; import java.util.Hashtable; import javax.naming.Binding; @@ -309,7 +310,7 @@ public class ProxyDirContext implements return object; } else { return new Resource(new ByteArrayInputStream - (object.toString().getBytes())); + (object.toString().getBytes(Charset.defaultCharset()))); } } @@ -1466,7 +1467,7 @@ public class ProxyDirContext implements entry.resource = (Resource) object; } else { entry.resource = new Resource(new ByteArrayInputStream - (object.toString().getBytes())); + (object.toString().getBytes(Charset.defaultCharset()))); } Attributes attributes = dirContext.getAttributes(parseName(name)); if (!(attributes instanceof ResourceAttributes)) { @@ -1629,7 +1630,7 @@ public class ProxyDirContext implements entry.resource = (Resource) object; } else { entry.resource = new Resource(new ByteArrayInputStream - (object.toString().getBytes())); + (object.toString().getBytes(Charset.defaultCharset()))); } } catch (NamingException e) { exists = false; Modified: tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java Tue Jun 21 14:29:49 2011 @@ -22,6 +22,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.util.concurrent.ConcurrentHashMap; /** Efficient conversion of bytes to character . * @@ -40,6 +44,32 @@ public class B2CConverter { private static final org.apache.juli.logging.Log log= org.apache.juli.logging.LogFactory.getLog( B2CConverter.class ); + private static final ConcurrentHashMap<String, Charset> encodingToCharsetCache = + new ConcurrentHashMap<String, Charset>(); + + public static Charset getCharset(String enc) + throws UnsupportedEncodingException{ + + Charset charset = encodingToCharsetCache.get(enc); + if (charset == null) { + try { + charset = Charset.forName(enc); + } catch (IllegalCharsetNameException icne) { + UnsupportedEncodingException uee = + new UnsupportedEncodingException(); + uee.initCause(icne); + throw uee; + } catch (UnsupportedCharsetException uce) { + UnsupportedEncodingException uee = + new UnsupportedEncodingException(); + uee.initCause(uce); + throw uee; + } + encodingToCharsetCache.put(enc, charset); + } + return charset; + } + private IntermediateInputStream iis; private ReadConvertor conv; private String encoding; @@ -104,7 +134,7 @@ public class B2CConverter { { // destroy the reader/iis iis=new IntermediateInputStream(); - conv=new ReadConvertor( iis, encoding ); + conv = new ReadConvertor(iis, getCharset(encoding)); } } @@ -120,10 +150,8 @@ final class ReadConvertor extends Input /** Create a converter. */ - public ReadConvertor( IntermediateInputStream in, String enc ) - throws UnsupportedEncodingException - { - super( in, enc ); + public ReadConvertor(IntermediateInputStream in, Charset charset) { + super(in, charset); } /** Overridden - will do nothing but reset internal state. Modified: tomcat/trunk/java/org/apache/tomcat/util/buf/ByteChunk.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/buf/ByteChunk.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/buf/ByteChunk.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/buf/ByteChunk.java Tue Jun 21 14:29:49 2011 @@ -499,8 +499,11 @@ public final class ByteChunk implements public String toStringInternal() { String strValue=null; try { - if( enc==null ) enc=DEFAULT_CHARACTER_ENCODING; - strValue = new String( buff, start, end-start, enc ); + if (enc == null) { + enc = DEFAULT_CHARACTER_ENCODING; + } + strValue = new String(buff, start, end-start, + B2CConverter.getCharset(enc)); /* Does not improve the speed too much on most systems, it's safer to use the "classical" new String(). Modified: tomcat/trunk/java/org/apache/tomcat/util/buf/MessageBytes.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/buf/MessageBytes.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/buf/MessageBytes.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/buf/MessageBytes.java Tue Jun 21 14:29:49 2011 @@ -19,6 +19,7 @@ package org.apache.tomcat.util.buf; import java.io.IOException; import java.io.Serializable; +import java.nio.charset.Charset; import java.util.Locale; /** @@ -233,7 +234,7 @@ public final class MessageBytes implemen } toString(); type=T_BYTES; - byte bb[] = strValue.getBytes(); + byte bb[] = strValue.getBytes(Charset.defaultCharset()); byteC.setBytes(bb, 0, bb.length); } Modified: tomcat/trunk/java/org/apache/tomcat/util/http/Parameters.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/Parameters.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/Parameters.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/Parameters.java Tue Jun 21 14:29:49 2011 @@ -18,7 +18,7 @@ package org.apache.tomcat.util.http; import java.io.IOException; -import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.Enumeration; import java.util.Hashtable; @@ -191,6 +191,9 @@ public final class Parameters { private ByteChunk origValue=new ByteChunk(); CharChunk tmpNameC=new CharChunk(1024); public static final String DEFAULT_ENCODING = "ISO-8859-1"; + public static final Charset DEFAULT_CHARSET = + Charset.forName(DEFAULT_ENCODING); + public void processParameters( byte bytes[], int start, int len ) { processParameters(bytes, start, len, encoding); @@ -202,13 +205,8 @@ public final class Parameters { int pos=start; if(log.isDebugEnabled()) { - try { - log.debug("Bytes: " + - new String(bytes, start, len, DEFAULT_ENCODING)); - } catch (UnsupportedEncodingException e) { - // Should never happen... - log.error("Unable to convert bytes", e); - } + log.debug("Bytes: " + + new String(bytes, start, len, DEFAULT_CHARSET)); } do { @@ -227,14 +225,9 @@ public final class Parameters { valStart=nameEnd; valEnd=nameEnd; if(log.isDebugEnabled()) { - try { - log.debug("no equal " + nameStart + " " + nameEnd + " " + - new String(bytes, nameStart, nameEnd-nameStart, - DEFAULT_ENCODING) ); - } catch (UnsupportedEncodingException e) { - // Should never happen... - log.error("Unable to convert bytes", e); - } + log.debug("no equal " + nameStart + " " + nameEnd + " " + + new String(bytes, nameStart, nameEnd-nameStart, + DEFAULT_CHARSET)); } } if( nameEnd== -1 ) @@ -254,13 +247,8 @@ public final class Parameters { // No name eg ...&=xx&... will trigger this if (valEnd >= nameStart) { msg.append('\''); - try { - msg.append(new String(bytes, nameStart, - valEnd - nameStart, DEFAULT_ENCODING)); - } catch (UnsupportedEncodingException e) { - // Should never happen... - log.error("Unable to convert bytes", e); - } + msg.append(new String(bytes, nameStart, + valEnd - nameStart, DEFAULT_CHARSET)); msg.append("' "); } msg.append("ignored."); Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java Tue Jun 21 14:29:49 2011 @@ -18,7 +18,7 @@ package org.apache.tomcat.util.http.file import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -60,6 +60,8 @@ public abstract class FileUploadBase { // ---------------------------------------------------------- Class methods + private static final Charset CHARSET_ISO_8859_1 = + Charset.forName("ISO-8859-1"); /** * <p>Utility method that determines whether the request contains multipart @@ -372,11 +374,7 @@ public abstract class FileUploadBase { return null; } byte[] boundary; - try { - boundary = boundaryStr.getBytes("ISO-8859-1"); - } catch (UnsupportedEncodingException e) { - boundary = boundaryStr.getBytes(); - } + boundary = boundaryStr.getBytes(CHARSET_ISO_8859_1); return boundary; } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1138019&r1=1138018&r2=1138019&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Tue Jun 21 14:29:49 2011 @@ -107,6 +107,11 @@ JSP servlet has been configured via code when embedding Tomcat. (markt) </fix> <fix> + <bug>51400</bug>: Avoid known bottleneck in JVM when converting between + Strings and bytes by always providing a Charset rather than an encoding + name. Based on a patch by Dave Engberg. (markt) + </fix> + <fix> <bug>51401</bug>: Correctly initialise shared WebRuleSet instance used by the digesters that parse web.xml and prevent incorrect warnings about multiple occurrences of elements that are only allowed to appear once in --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org