Skip to content

Commit

Permalink
More work towards using Charset rather than String internally to redu…
Browse files Browse the repository at this point in the history
…ce the number of calls required to B2CConverter.getCharset() or equivalent during a request.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1793798 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
markt-asf committed May 4, 2017
1 parent 43bf93f commit 1fbe4cb
Show file tree
Hide file tree
Showing 14 changed files with 79 additions and 29 deletions.
4 changes: 3 additions & 1 deletion java/org/apache/catalina/connector/CoyoteAdapter.java
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.EnumSet;
import java.util.concurrent.atomic.AtomicBoolean;

Expand Down Expand Up @@ -771,7 +772,8 @@ protected boolean postParseRequest(org.apache.coyote.Request req, Request reques
// Possible redirect
MessageBytes redirectPathMB = request.getMappingData().redirectPath;
if (!redirectPathMB.isNull()) {
String redirectPath = URLEncoder.DEFAULT.encode(redirectPathMB.toString(), "UTF-8");
String redirectPath = URLEncoder.DEFAULT.encode(
redirectPathMB.toString(), StandardCharsets.UTF_8);
String query = request.getQueryString();
if (request.isRequestedSessionIdFromURL()) {
// This is not optimal, but as this is not very common, it
Expand Down
5 changes: 3 additions & 2 deletions java/org/apache/catalina/connector/Request.java
Expand Up @@ -24,6 +24,7 @@
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
Expand Down Expand Up @@ -1359,9 +1360,9 @@ public RequestDispatcher getRequestDispatcher(String path) {
if (context.getDispatchersUseEncodedPaths()) {
if (pos >= 0) {
relative = URLEncoder.DEFAULT.encode(
requestPath.substring(0, pos + 1), "UTF-8") + path;
requestPath.substring(0, pos + 1), StandardCharsets.UTF_8) + path;
} else {
relative = URLEncoder.DEFAULT.encode(requestPath, "UTF-8") + path;
relative = URLEncoder.DEFAULT.encode(requestPath, StandardCharsets.UTF_8) + path;
}
} else {
if (pos >= 0) {
Expand Down
3 changes: 2 additions & 1 deletion java/org/apache/catalina/core/ApplicationContext.java
Expand Up @@ -22,6 +22,7 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
Expand Down Expand Up @@ -486,7 +487,7 @@ public RequestDispatcher getRequestDispatcher(String path) {

mappingData.recycle();

String encodedUri = URLEncoder.DEFAULT.encode(uriCC.toString(), "UTF-8");
String encodedUri = URLEncoder.DEFAULT.encode(uriCC.toString(), StandardCharsets.UTF_8);

// Construct a RequestDispatcher to process this request
return new ApplicationDispatcher(wrapper, encodedUri, wrapperPath, pathInfo,
Expand Down
3 changes: 2 additions & 1 deletion java/org/apache/catalina/core/AsyncContextImpl.java
Expand Up @@ -17,6 +17,7 @@
package org.apache.catalina.core;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -164,7 +165,7 @@ public void dispatch() {
path += pathInfo;
}
if (this.context.getDispatchersUseEncodedPaths()) {
path = URLEncoder.DEFAULT.encode(path, "UTF-8");
path = URLEncoder.DEFAULT.encode(path, StandardCharsets.UTF_8);
}
dispatch(path);
}
Expand Down
3 changes: 2 additions & 1 deletion java/org/apache/catalina/core/StandardContext.java
Expand Up @@ -21,6 +21,7 @@
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
Expand Down Expand Up @@ -2066,7 +2067,7 @@ public void setPath(String path) {
log.warn(sm.getString(
"standardContext.pathInvalid", path, this.path));
}
encodedPath = URLEncoder.DEFAULT.encode(this.path, "UTF-8");
encodedPath = URLEncoder.DEFAULT.encode(this.path, StandardCharsets.UTF_8);
if (getName() == null) {
setName(this.path);
}
Expand Down
9 changes: 6 additions & 3 deletions java/org/apache/catalina/manager/HTMLManagerServlet.java
Expand Up @@ -24,6 +24,7 @@
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -423,10 +424,11 @@ protected void list(HttpServletRequest request,

StringBuilder tmp = new StringBuilder();
tmp.append("path=");
tmp.append(URLEncoder.DEFAULT.encode(displayPath, "UTF-8"));
tmp.append(URLEncoder.DEFAULT.encode(displayPath, StandardCharsets.UTF_8));
if (ctxt.getWebappVersion().length() > 0) {
tmp.append("&version=");
tmp.append(URLEncoder.DEFAULT.encode(ctxt.getWebappVersion(), "UTF-8"));
tmp.append(URLEncoder.DEFAULT.encode(
ctxt.getWebappVersion(), StandardCharsets.UTF_8));
}
String pathVersion = tmp.toString();

Expand All @@ -438,7 +440,8 @@ protected void list(HttpServletRequest request,
}

args = new Object[7];
args[0] = "<a href=\"" + URLEncoder.DEFAULT.encode(contextPath + "/", "UTF-8") +
args[0] = "<a href=\"" +
URLEncoder.DEFAULT.encode(contextPath + "/", StandardCharsets.UTF_8) +
"\">" + RequestUtil.filter(displayPath) + "</a>";
if ("".equals(ctxt.getWebappVersion())) {
args[1] = noVersion;
Expand Down
3 changes: 2 additions & 1 deletion java/org/apache/catalina/servlets/DefaultServlet.java
Expand Up @@ -32,6 +32,7 @@
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -704,7 +705,7 @@ && checkIfNoneMatch(request, response, resource)
* @return the rewritten path
*/
protected String rewriteUrl(String path) {
return URLEncoder.DEFAULT.encode(path, "UTF-8");
return URLEncoder.DEFAULT.encode(path, StandardCharsets.UTF_8);
}


Expand Down
3 changes: 2 additions & 1 deletion java/org/apache/catalina/ssi/SSIMediator.java
Expand Up @@ -17,6 +17,7 @@
package org.apache.catalina.ssi;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
Expand Down Expand Up @@ -279,7 +280,7 @@ protected String formatDate(Date date, TimeZone timeZone) {
protected String encode(String value, String encoding) {
String retVal = null;
if (encoding.equalsIgnoreCase("url")) {
retVal = URLEncoder.DEFAULT.encode(value, "UTF-8");
retVal = URLEncoder.DEFAULT.encode(value, StandardCharsets.UTF_8);
} else if (encoding.equalsIgnoreCase("none")) {
retVal = value;
} else if (encoding.equalsIgnoreCase("entity")) {
Expand Down
35 changes: 28 additions & 7 deletions java/org/apache/catalina/util/URLEncoder.java
Expand Up @@ -19,8 +19,12 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.BitSet;

import org.apache.tomcat.util.buf.B2CConverter;

/**
*
* This class is very similar to the java.net.URLEncoder class.
Expand Down Expand Up @@ -133,18 +137,35 @@ public void setEncodeSpaceAsPlus(boolean encodeSpaceAsPlus) {
* @param encoding The encoding to use to convert the path to bytes
*
* @return The encoded path
*
* @deprecated This will be removed in Tomcat 9.0.x
*/
@Deprecated
public String encode(String path, String encoding) {
Charset charset;
try {
charset = B2CConverter.getCharset(encoding);
} catch (UnsupportedEncodingException e) {
charset = Charset.defaultCharset();
}
return encode(path, charset);
}


/**
* URL encodes the provided path using the given character set.
*
* @param path The path to encode
* @param charset The character set to use to convert the path to bytes
*
* @return The encoded path
*/
public String encode(String path, Charset charset) {

int maxBytesPerChar = 10;
StringBuilder rewrittenPath = new StringBuilder(path.length());
ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
OutputStreamWriter writer = null;
try {
writer = new OutputStreamWriter(buf, encoding);
} catch (Exception e) {
e.printStackTrace();
writer = new OutputStreamWriter(buf);
}
OutputStreamWriter writer = new OutputStreamWriter(buf, charset);

for (int i = 0; i < path.length(); i++) {
int c = path.charAt(i);
Expand Down
10 changes: 10 additions & 0 deletions java/org/apache/catalina/valves/rewrite/Resolver.java
Expand Up @@ -17,6 +17,8 @@

package org.apache.catalina.valves.rewrite;

import java.nio.charset.Charset;

/**
* Resolver abstract class.
*/
Expand All @@ -34,5 +36,13 @@ public String resolveEnv(String key) {

public abstract boolean resolveResource(int type, String name);

/**
* @return The name of the encoding to use to %nn encode URIs
*
* @deprecated This will be removed in Tomcat 9.0.x
*/
@Deprecated
public abstract String getUriEncoding();

public abstract Charset getUriCharset();
}
7 changes: 7 additions & 0 deletions java/org/apache/catalina/valves/rewrite/ResolverImpl.java
Expand Up @@ -16,6 +16,7 @@
*/
package org.apache.catalina.valves.rewrite;

import java.nio.charset.Charset;
import java.util.Calendar;

import org.apache.catalina.WebResource;
Expand Down Expand Up @@ -178,7 +179,13 @@ private static final String emptyStringIfNull(String value) {
}

@Override
@Deprecated
public String getUriEncoding() {
return request.getConnector().getURIEncoding();
}

@Override
public Charset getUriCharset() {
return request.getConnector().getURICharset();
}
}
19 changes: 10 additions & 9 deletions java/org/apache/catalina/valves/rewrite/RewriteValve.java
Expand Up @@ -23,7 +23,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Hashtable;
Expand All @@ -50,6 +50,7 @@
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.buf.UDecoder;
import org.apache.tomcat.util.buf.UriUtil;
import org.apache.tomcat.util.http.RequestUtil;

Expand Down Expand Up @@ -296,7 +297,7 @@ public void invoke(Request request, Response response)

// As long as MB isn't a char sequence or affiliated, this has to be
// converted to a string
String uriEncoding = request.getConnector().getURIEncoding();
Charset uriCharset = request.getConnector().getURICharset();
String originalQueryStringEncoded = request.getQueryString();
MessageBytes urlMB =
context ? request.getRequestPathMB() : request.getDecodedRequestURIMB();
Expand Down Expand Up @@ -360,7 +361,7 @@ public void invoke(Request request, Response response)
}

StringBuffer urlStringEncoded =
new StringBuffer(URLEncoder.DEFAULT.encode(urlStringDecoded, uriEncoding));
new StringBuffer(URLEncoder.DEFAULT.encode(urlStringDecoded, uriCharset));
if (originalQueryStringEncoded != null &&
originalQueryStringEncoded.length() > 0) {
if (rewrittenQueryStringDecoded == null) {
Expand All @@ -371,7 +372,7 @@ public void invoke(Request request, Response response)
// if qsa is specified append the query
urlStringEncoded.append('?');
urlStringEncoded.append(URLEncoder.QUERY.encode(
rewrittenQueryStringDecoded, uriEncoding));
rewrittenQueryStringDecoded, uriCharset));
urlStringEncoded.append('&');
urlStringEncoded.append(originalQueryStringEncoded);
} else if (index == urlStringEncoded.length() - 1) {
Expand All @@ -381,13 +382,13 @@ public void invoke(Request request, Response response)
} else {
urlStringEncoded.append('?');
urlStringEncoded.append(URLEncoder.QUERY.encode(
rewrittenQueryStringDecoded, uriEncoding));
rewrittenQueryStringDecoded, uriCharset));
}
}
} else if (rewrittenQueryStringDecoded != null) {
urlStringEncoded.append('?');
urlStringEncoded.append(
URLEncoder.QUERY.encode(rewrittenQueryStringDecoded, uriEncoding));
URLEncoder.QUERY.encode(rewrittenQueryStringDecoded, uriCharset));
}

// Insert the context if
Expand All @@ -400,7 +401,7 @@ public void invoke(Request request, Response response)
}
if (rule.isNoescape()) {
response.sendRedirect(
URLDecoder.decode(urlStringEncoded.toString(), uriEncoding));
UDecoder.URLDecode(urlStringEncoded.toString(), uriCharset));
} else {
response.sendRedirect(urlStringEncoded.toString());
}
Expand Down Expand Up @@ -485,7 +486,7 @@ public void invoke(Request request, Response response)
// This is neither decoded nor normalized
chunk.append(contextPath);
}
chunk.append(URLEncoder.DEFAULT.encode(urlStringDecoded, uriEncoding));
chunk.append(URLEncoder.DEFAULT.encode(urlStringDecoded, uriCharset));
request.getCoyoteRequest().requestURI().toChars();
// Decoded and normalized URI
// Rewriting may have denormalized the URL
Expand All @@ -504,7 +505,7 @@ public void invoke(Request request, Response response)
request.getCoyoteRequest().queryString().setString(null);
chunk = request.getCoyoteRequest().queryString().getCharChunk();
chunk.recycle();
chunk.append(URLEncoder.QUERY.encode(queryStringDecoded, uriEncoding));
chunk.append(URLEncoder.QUERY.encode(queryStringDecoded, uriCharset));
if (qsa && originalQueryStringEncoded != null &&
originalQueryStringEncoded.length() > 0) {
chunk.append('&');
Expand Down
2 changes: 1 addition & 1 deletion java/org/apache/catalina/valves/rewrite/Substitution.java
Expand Up @@ -51,7 +51,7 @@ public String evaluate(Matcher rule, Matcher cond, Resolver resolver) {
// We might want to consider providing a dedicated decoder
// with an option to add additional safe characters to
// provide users with more flexibility
return URLEncoder.DEFAULT.encode(result, resolver.getUriEncoding());
return URLEncoder.DEFAULT.encode(result, resolver.getUriCharset());
} else {
return result;
}
Expand Down
Expand Up @@ -488,7 +488,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
int lastSlash = target.lastIndexOf('/');
target = target.substring(0, lastSlash + 1);
if (encodePath) {
target = URLEncoder.DEFAULT.encode(target, "UTF-8");
target = URLEncoder.DEFAULT.encode(target, StandardCharsets.UTF_8);
}
target += dispatchPath;
}
Expand Down

0 comments on commit 1fbe4cb

Please sign in to comment.