Issue #3708 - use StringUtil alternatives for known slow JVM impls.
+ StringUtil.replace() + StringUtil.replaceFirst() + StringUtil.sanitizeFileSystemPath() Change existing usages of String.replace() to either use new StringUtil.replace() or other methods elsewhere that better suit that specific need. Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
da4f116c63
commit
33fe55c339
|
@ -28,6 +28,7 @@ import java.util.regex.Pattern;
|
|||
|
||||
import org.apache.tools.ant.AntClassLoader;
|
||||
import org.eclipse.jetty.util.PatternMatcher;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
@ -88,7 +89,7 @@ public class AntWebInfConfiguration extends WebInfConfiguration
|
|||
}
|
||||
catch (URISyntaxException e)
|
||||
{
|
||||
containerUris[i] = new URI(u.toString().replaceAll(" ", "%20"));
|
||||
containerUris[i] = new URI(URIUtil.encodeSpaces(u.toString()));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public class HttpSenderOverFCGI extends HttpSender
|
|||
for (HttpField field : headers)
|
||||
{
|
||||
String name = field.getName();
|
||||
String fcgiName = "HTTP_" + name.replaceAll("-", "_").toUpperCase(Locale.ENGLISH);
|
||||
String fcgiName = "HTTP_" + name.replace('-', '_').toUpperCase(Locale.ENGLISH);
|
||||
fcgiHeaders.add(fcgiName, field.getValue());
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.net.URL;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
|
@ -35,6 +34,8 @@ import javax.servlet.ServletResponse;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Inspired by nginx's try_files functionality.
|
||||
* <p>
|
||||
|
@ -132,7 +133,7 @@ public class TryFilesFilter implements Filter
|
|||
path += info;
|
||||
if (!path.startsWith("/"))
|
||||
path = "/" + path;
|
||||
return value.replaceAll("\\$path", path);
|
||||
return StringUtil.replace(value, "$path", path);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -196,7 +196,7 @@ public class MimeTypes
|
|||
int charset=type.toString().indexOf(";charset=");
|
||||
if (charset>0)
|
||||
{
|
||||
String alt=type.toString().replace(";charset=","; charset=");
|
||||
String alt = StringUtil.replace(type.toString(), ";charset=", "; charset=");
|
||||
CACHE.put(alt,type);
|
||||
TYPES.put(alt,type.asBuffer());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
import org.openjdk.jmh.runner.Runner;
|
||||
import org.openjdk.jmh.runner.RunnerException;
|
||||
import org.openjdk.jmh.runner.options.Options;
|
||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||
|
||||
@Fork(value = 3)
|
||||
@State(Scope.Benchmark)
|
||||
@Warmup(iterations = 4, time = 1, timeUnit = TimeUnit.SECONDS)
|
||||
@Measurement(iterations = 4, time = 1, timeUnit = TimeUnit.SECONDS)
|
||||
public class StringReplaceBenchmark
|
||||
{
|
||||
@Param({"3", "100", "1000"})
|
||||
int size;
|
||||
|
||||
@Param({"0", "1", "3", "50"})
|
||||
int matches;
|
||||
|
||||
String input;
|
||||
|
||||
@Setup(Level.Trial)
|
||||
public void setupTrial() throws Exception
|
||||
{
|
||||
String pattern = "abc";
|
||||
StringBuilder str = new StringBuilder();
|
||||
while (str.length() < size)
|
||||
{
|
||||
str.append(pattern);
|
||||
}
|
||||
|
||||
if (matches > 0)
|
||||
{
|
||||
int partSize = (int)((double)str.length() / (double)matches);
|
||||
for (int i = 0; i < matches; i++)
|
||||
{
|
||||
str.insert((i * partSize), "'");
|
||||
}
|
||||
}
|
||||
input = str.toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testJavaStringReplace_Growth(Blackhole blackhole)
|
||||
{
|
||||
blackhole.consume(input.replace("'", "FOOBAR"));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testJavaStringReplace_Same(Blackhole blackhole)
|
||||
{
|
||||
blackhole.consume(input.replace("'", "X"));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testJavaStringReplace_Reduce(Blackhole blackhole)
|
||||
{
|
||||
blackhole.consume(input.replace("'", ""));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testJettyStringUtilReplace_Growth(Blackhole blackhole)
|
||||
{
|
||||
blackhole.consume(StringUtil.replace(input, "'", "FOOBAR"));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testJettyStringUtilReplace_Same(Blackhole blackhole)
|
||||
{
|
||||
blackhole.consume(StringUtil.replace(input, "'", "X"));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void testJettyStringUtilReplace_Reduce(Blackhole blackhole)
|
||||
{
|
||||
blackhole.consume(StringUtil.replace(input, "'", ""));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws RunnerException
|
||||
{
|
||||
Options opt = new OptionsBuilder()
|
||||
.include(StringReplaceBenchmark.class.getSimpleName())
|
||||
// .addProfiler(GCProfiler.class)
|
||||
.forks(1)
|
||||
.build();
|
||||
|
||||
new Runner(opt).run();
|
||||
}
|
||||
}
|
|
@ -27,10 +27,10 @@ import java.util.Date;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
/**
|
||||
* MongoUtils
|
||||
|
@ -69,23 +69,23 @@ public class MongoUtils
|
|||
throw new IllegalStateException(valueToDecode.getClass().toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static String decodeName(String name)
|
||||
{
|
||||
return name.replace("%2E",".").replace("%25","%");
|
||||
String cleaned = name;
|
||||
cleaned = StringUtil.replace(cleaned, "%2E", ".");
|
||||
cleaned = StringUtil.replace(cleaned, "%25", "%");
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String encodeName(String name)
|
||||
{
|
||||
return name.replace("%","%25").replace(".","%2E");
|
||||
String cleaned = name;
|
||||
cleaned = StringUtil.replace(cleaned, "%", "%25");
|
||||
cleaned = StringUtil.replace(cleaned, ".", "%2E");
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Object encodeName(Object value) throws IOException
|
||||
{
|
||||
if (value instanceof Number || value instanceof String || value instanceof Boolean || value instanceof Date)
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.regex.Pattern;
|
|||
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
|
||||
import org.eclipse.jetty.osgi.boot.utils.Util;
|
||||
import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
|
@ -339,7 +340,7 @@ public class OSGiWebInfConfiguration extends WebInfConfiguration
|
|||
}
|
||||
catch (URISyntaxException e)
|
||||
{
|
||||
uri = new URI(url.toString().replaceAll(" ", "%20"));
|
||||
uri = new URI(URIUtil.encodeSpaces(url.toString()));
|
||||
}
|
||||
String key = resourcePath.startsWith("/") ? resourcePath.substring(1) : resourcePath;
|
||||
resourceMap.put(key + ";" + fragment.getSymbolicName(), Resource.newResource(uri));
|
||||
|
|
|
@ -43,7 +43,6 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.AsyncEvent;
|
||||
import javax.servlet.AsyncListener;
|
||||
|
@ -670,7 +669,7 @@ public class ProxyServletTest
|
|||
|
||||
// Make the request to the proxy, it should transparently forward to the server
|
||||
ContentResponse response = client.newRequest("localhost", proxyConnector.getLocalPort())
|
||||
.path((prefix + target).replaceAll("//", "/"))
|
||||
.path((prefix + target).replace("//", "/"))
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
assertEquals(200, response.getStatus());
|
||||
|
|
|
@ -37,6 +37,7 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
|
@ -454,13 +455,7 @@ public class AttributeNormalizer
|
|||
// leftover
|
||||
expanded.append(str.substring(offset));
|
||||
|
||||
// special case for "$$"
|
||||
if (expanded.indexOf("$$") >= 0)
|
||||
{
|
||||
return expanded.toString().replaceAll("\\$\\$","\\$");
|
||||
}
|
||||
|
||||
return expanded.toString();
|
||||
return StringUtil.replace(expanded.toString(), "$$", "$");
|
||||
}
|
||||
|
||||
private String getString(String property)
|
||||
|
|
|
@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
|
||||
/**
|
||||
|
@ -93,7 +94,7 @@ public class RedirectRegexRule extends RegexRule
|
|||
for (int g = 1; g <= matcher.groupCount(); g++)
|
||||
{
|
||||
String group = matcher.group(g);
|
||||
target = target.replaceAll("\\$" + g, group);
|
||||
target = StringUtil.replace(target, "$" + g, group);
|
||||
}
|
||||
|
||||
target = response.encodeRedirectURL(target);
|
||||
|
@ -110,6 +111,11 @@ public class RedirectRegexRule extends RegexRule
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s[%d>%s]", super.toString(), _statusCode, _location);
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append(super.toString());
|
||||
str.append('[').append(_statusCode);
|
||||
str.append('>').append(_location);
|
||||
str.append(']');
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,11 +20,11 @@ package org.eclipse.jetty.rewrite.handler;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
|
||||
/**
|
||||
|
@ -96,15 +96,22 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI
|
|||
group="";
|
||||
else
|
||||
group = Matcher.quoteReplacement(group);
|
||||
target=target.replaceAll("\\$"+g,group);
|
||||
if (query!=null)
|
||||
query=query.replaceAll("\\$"+g,group);
|
||||
String dollarGroup = "$" + g;
|
||||
target = StringUtil.replace(target, dollarGroup, group);
|
||||
if (query != null)
|
||||
query = StringUtil.replace(query, dollarGroup, group);
|
||||
}
|
||||
|
||||
if (query!=null)
|
||||
{
|
||||
if (_queryGroup)
|
||||
query=query.replace("$Q",request.getQueryString()==null?"":request.getQueryString());
|
||||
{
|
||||
String replacement = "";
|
||||
if (request.getQueryString() != null)
|
||||
replacement = request.getQueryString();
|
||||
|
||||
query = StringUtil.replace(query, "$Q", replacement);
|
||||
}
|
||||
request.setAttribute("org.eclipse.jetty.rewrite.handler.RewriteRegexRule.Q",query);
|
||||
}
|
||||
|
||||
|
|
|
@ -140,7 +140,8 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
|
|||
int bang_slash = uri.indexOf("!/");
|
||||
if (colon < 0 || bang_slash < 0 || colon > bang_slash)
|
||||
throw new IllegalArgumentException("Not resolved JarFile resource: " + uri);
|
||||
String entry_path = uri.substring(colon + 2).replace("!/", "__").replace('/', '_').replace('.', '_');
|
||||
|
||||
String entry_path = StringUtil.sanitizeFileSystemPath(uri.substring(colon + 2));
|
||||
|
||||
Path tmpDirectory = Files.createTempDirectory("users_store");
|
||||
tmpDirectory.toFile().deleteOnExit();
|
||||
|
|
|
@ -52,12 +52,10 @@ import org.eclipse.jetty.http.HttpVersion;
|
|||
import org.eclipse.jetty.http.MetaData;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.http.PreEncodedHttpField;
|
||||
import org.eclipse.jetty.http.Syntax;
|
||||
import org.eclipse.jetty.io.RuntimeIOException;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ErrorHandler;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -237,7 +235,7 @@ public class Response implements HttpServletResponse
|
|||
if (i >= 0)
|
||||
{
|
||||
httpOnly = true;
|
||||
comment = comment.replace(HTTP_ONLY_COMMENT, "").trim();
|
||||
comment = StringUtil.replace(comment.trim(), HTTP_ONLY_COMMENT, "");
|
||||
if (comment.length() == 0)
|
||||
comment = null;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ public class DefaultHandler extends AbstractHandler
|
|||
{
|
||||
writer.append("<a href=\"").append(href).append("\">");
|
||||
}
|
||||
writer.append(contextPath.replaceAll("%", "%"));
|
||||
writer.append(StringUtil.replace(contextPath, "%", "%"));
|
||||
if (context.isRunning())
|
||||
{
|
||||
writer.append("</a>");
|
||||
|
|
|
@ -18,13 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.servlet;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -38,6 +34,9 @@ import org.junit.jupiter.api.AfterAll;
|
|||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class ResponseHeadersTest
|
||||
{
|
||||
public static class SimulateUpgradeServlet extends HttpServlet
|
||||
|
@ -144,7 +143,7 @@ public class ResponseHeadersTest
|
|||
assertThat("Response Code",response.getStatus(),is(200));
|
||||
assertThat("Response Header Content-Type",response.get("Content-Type"),is("text/plain;charset=UTF-8"));
|
||||
|
||||
String expected = actualPathInfo.replaceAll("%0A", " "); // replace OBS fold with space
|
||||
String expected = actualPathInfo.replace("%0A", " "); // replace OBS fold with space
|
||||
expected = URLDecoder.decode(expected, "utf-8"); // decode the rest
|
||||
expected = expected.trim(); // trim whitespace at start/end
|
||||
assertThat("Response Header X-example", response.get("X-Example"), is(expected));
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.Enumeration;
|
|||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
|
@ -368,8 +367,8 @@ public class CrossOriginFilter implements Filter
|
|||
|
||||
private String parseAllowedWildcardOriginToRegex(String allowedOrigin)
|
||||
{
|
||||
String regex = allowedOrigin.replace(".", "\\.");
|
||||
return regex.replace("*", ".*"); // we want to be greedy here to match multiple subdomains, thus we use .*
|
||||
String regex = StringUtil.replace(allowedOrigin, ".", "\\.");
|
||||
return StringUtil.replace(regex, "*", ".*"); // we want to be greedy here to match multiple subdomains, thus we use .*
|
||||
}
|
||||
|
||||
private boolean isSimpleRequest(HttpServletRequest request)
|
||||
|
|
|
@ -26,14 +26,13 @@ import java.util.List;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/** Fast String Utilities.
|
||||
/**
|
||||
* Fast String Utilities.
|
||||
*
|
||||
* These string utilities provide both convenience methods and
|
||||
* performance improvements over most standard library versions. The
|
||||
* main aim of the optimizations is to avoid object creation unless
|
||||
* absolutely required.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class StringUtil
|
||||
{
|
||||
|
@ -62,8 +61,7 @@ public class StringUtil
|
|||
CHARSETS.put("iso-8859-1",__ISO_8859_1);
|
||||
CHARSETS.put("iso_8859_1",__ISO_8859_1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/** Convert alternate charset names (eg utf8) to normalized
|
||||
* name (eg UTF-8).
|
||||
* @param s the charset to normalize
|
||||
|
@ -74,8 +72,7 @@ public class StringUtil
|
|||
String n=CHARSETS.get(s);
|
||||
return (n==null)?s:n;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/** Convert alternate charset names (eg utf8) to normalized
|
||||
* name (eg UTF-8).
|
||||
* @param s the charset to normalize
|
||||
|
@ -88,9 +85,7 @@ public class StringUtil
|
|||
String n=CHARSETS.get(s,offset,length);
|
||||
return (n==null)?s.substring(offset,offset+length):n;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static final char[] lowercases = {
|
||||
'\000','\001','\002','\003','\004','\005','\006','\007',
|
||||
'\010','\011','\012','\013','\014','\015','\016','\017',
|
||||
|
@ -109,7 +104,6 @@ public class StringUtil
|
|||
'\160','\161','\162','\163','\164','\165','\166','\167',
|
||||
'\170','\171','\172','\173','\174','\175','\176','\177' };
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* fast lower case conversion. Only works on ascii (not unicode)
|
||||
* @param s the string to convert
|
||||
|
@ -122,7 +116,6 @@ public class StringUtil
|
|||
|
||||
char[] c = null;
|
||||
int i=s.length();
|
||||
|
||||
// look for first conversion
|
||||
while (i-->0)
|
||||
{
|
||||
|
@ -138,7 +131,6 @@ public class StringUtil
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (i-->0)
|
||||
{
|
||||
if(c[i]<=127)
|
||||
|
@ -148,8 +140,43 @@ public class StringUtil
|
|||
return c==null?s:new String(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all characters from input string that are known to have
|
||||
* special meaning in various filesytems.
|
||||
*
|
||||
* <p>
|
||||
* This will replace all of the following characters
|
||||
* with a "{@code _}" (underscore).
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>Control Characters</li>
|
||||
* <li>Anything not 7-bit printable ASCII</li>
|
||||
* <li>Special characters "{@code !|/.,:&><\?*"}"</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param str the raw input string
|
||||
* @return the sanitized output string.
|
||||
*/
|
||||
public static String sanitizeFileSystemPath(String str)
|
||||
{
|
||||
char[] chars = str.toCharArray();
|
||||
int len = chars.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char c = chars[i];
|
||||
if ((c <= 0x1F) || // control characters
|
||||
(c >= 0x7F) || // over 7-bit printable ASCII
|
||||
(c == '!') || (c == '|') || (c == '.') ||
|
||||
(c == ':') || (c == '>') || (c == '<') ||
|
||||
(c == '?') || (c == '/') || (c == '\\') ||
|
||||
(c == '*') || (c == '"') || (c == '&'))
|
||||
{
|
||||
chars[i] = '_';
|
||||
}
|
||||
}
|
||||
return String.valueOf(chars);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static boolean startsWithIgnoreCase(String s,String w)
|
||||
{
|
||||
if (w==null)
|
||||
|
@ -174,13 +201,11 @@ public class StringUtil
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
public static boolean endsWithIgnoreCase(String s,String w)
|
||||
{
|
||||
if (w==null)
|
||||
return true;
|
||||
|
||||
if (s==null)
|
||||
return false;
|
||||
|
||||
|
@ -206,8 +231,7 @@ public class StringUtil
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* returns the next index of a character from the chars string
|
||||
* @param s the input string to search
|
||||
|
@ -221,10 +245,13 @@ public class StringUtil
|
|||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* replace substrings within string.
|
||||
* Replace substrings within string.
|
||||
* <p>
|
||||
* Fast replacement for {@code java.lang.String#}{@link String#replace(CharSequence, CharSequence)}
|
||||
* </p>
|
||||
*
|
||||
* @param s the input string
|
||||
* @param sub the string to look for
|
||||
* @param with the string to replace with
|
||||
|
@ -232,27 +259,56 @@ public class StringUtil
|
|||
*/
|
||||
public static String replace(String s, String sub, String with)
|
||||
{
|
||||
int c=0;
|
||||
int i=s.indexOf(sub,c);
|
||||
int c = 0;
|
||||
int i = s.indexOf(sub, c);
|
||||
if (i == -1)
|
||||
{
|
||||
return s;
|
||||
|
||||
StringBuilder buf = new StringBuilder(s.length()+with.length());
|
||||
|
||||
}
|
||||
StringBuilder buf = new StringBuilder(s.length() + with.length());
|
||||
do
|
||||
{
|
||||
buf.append(s.substring(c,i));
|
||||
buf.append(s, c, i);
|
||||
buf.append(with);
|
||||
c=i+sub.length();
|
||||
} while ((i=s.indexOf(sub,c))!=-1);
|
||||
|
||||
if (c<s.length())
|
||||
buf.append(s.substring(c,s.length()));
|
||||
|
||||
c = i + sub.length();
|
||||
}
|
||||
while ((i = s.indexOf(sub, c)) != -1);
|
||||
if (c < s.length())
|
||||
{
|
||||
buf.append(s.substring(c));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Replace first substrings within string.
|
||||
* <p>
|
||||
* Fast replacement for {@code java.lang.String#}{@link String#replaceFirst(String, String)}, but without
|
||||
* Regex support.
|
||||
* </p>
|
||||
*
|
||||
* @param original the original string
|
||||
* @param target the target string to look for
|
||||
* @param replacement the replacement string to use
|
||||
* @return the replaced string
|
||||
*/
|
||||
public static String replaceFirst(String original, String target, String replacement)
|
||||
{
|
||||
int idx = original.indexOf(target);
|
||||
if (idx == -1)
|
||||
return original;
|
||||
|
||||
int offset = 0;
|
||||
int originalLen = original.length();
|
||||
StringBuilder buf = new StringBuilder(originalLen + replacement.length());
|
||||
buf.append(original, offset, idx);
|
||||
offset += idx + target.length();
|
||||
buf.append(replacement);
|
||||
buf.append(original, offset, originalLen);
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** Remove single or double quotes.
|
||||
* @param s the input string
|
||||
* @return the string with quotes removed
|
||||
|
@ -263,8 +319,6 @@ public class StringUtil
|
|||
return QuotedStringTokenizer.unquote(s);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Append substring to StringBuilder
|
||||
* @param buf StringBuilder to append to
|
||||
* @param s String to append from
|
||||
|
@ -288,8 +342,6 @@ public class StringUtil
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* append hex digit
|
||||
* @param buf the buffer to append to
|
||||
|
@ -310,7 +362,6 @@ public class StringUtil
|
|||
buf.append((char)c);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Append 2 digits (zero padded) to the StringBuffer
|
||||
*
|
||||
|
@ -325,8 +376,7 @@ public class StringUtil
|
|||
buf.append((char)(i%10+'0'));
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* Append 2 digits (zero padded) to the StringBuilder
|
||||
*
|
||||
|
@ -341,8 +391,7 @@ public class StringUtil
|
|||
buf.append((char)(i%10+'0'));
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/** Return a non null string.
|
||||
* @param s String
|
||||
* @return The string passed in or empty string if it is null.
|
||||
|
@ -353,8 +402,7 @@ public class StringUtil
|
|||
return "";
|
||||
return s;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
public static boolean equals(String s,char[] buf, int offset, int length)
|
||||
{
|
||||
if (s.length()!=length)
|
||||
|
@ -365,13 +413,11 @@ public class StringUtil
|
|||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static String toUTF8String(byte[] b,int offset,int length)
|
||||
{
|
||||
return new String(b,offset,length,StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static String toString(byte[] b,int offset,int length,String charset)
|
||||
{
|
||||
try
|
||||
|
@ -380,6 +426,7 @@ public class StringUtil
|
|||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
@ -431,7 +478,6 @@ public class StringUtil
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Test if a string is null or only has whitespace characters in it.
|
||||
* <p>
|
||||
|
@ -494,7 +540,6 @@ public class StringUtil
|
|||
return str == null || str.isEmpty();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Test if a string is not null and contains at least 1 non-whitespace characters in it.
|
||||
* <p>
|
||||
|
@ -534,14 +579,11 @@ public class StringUtil
|
|||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static boolean isUTF8(String charset)
|
||||
{
|
||||
return __UTF8.equalsIgnoreCase(charset)||__UTF8.equalsIgnoreCase(normalizeCharset(charset));
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static String printable(String name)
|
||||
{
|
||||
if (name==null)
|
||||
|
@ -556,7 +598,7 @@ public class StringUtil
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
public static String printable(byte[] b)
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
@ -592,13 +634,10 @@ public class StringUtil
|
|||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
return s.getBytes();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Converts a binary SID to a string SID
|
||||
*
|
||||
|
@ -631,7 +670,6 @@ public class StringUtil
|
|||
|
||||
// the number of subAuthorities we need to attach
|
||||
int subAuthorityCount = sidBytes[1];
|
||||
|
||||
// attach each of the subAuthorities
|
||||
for (int i = 0; i < subAuthorityCount; ++i)
|
||||
{
|
||||
|
@ -670,10 +708,8 @@ public class StringUtil
|
|||
|
||||
// the revision byte
|
||||
sidBytes[byteCount++] = (byte)Integer.parseInt(sidTokens[1]);
|
||||
|
||||
// the # of sub authorities byte
|
||||
sidBytes[byteCount++] = (byte)subAuthorityCount;
|
||||
|
||||
// the certAuthority
|
||||
String hexStr = Long.toHexString(Long.parseLong(sidTokens[2]));
|
||||
|
||||
|
@ -681,7 +717,6 @@ public class StringUtil
|
|||
{
|
||||
hexStr = "0" + hexStr;
|
||||
}
|
||||
|
||||
// place the certAuthority 6 bytes
|
||||
for ( int i = 0 ; i < hexStr.length(); i = i + 2)
|
||||
{
|
||||
|
@ -720,7 +755,6 @@ public class StringUtil
|
|||
int val = 0;
|
||||
boolean started = false;
|
||||
boolean minus = false;
|
||||
|
||||
for (int i = from; i < string.length(); i++)
|
||||
{
|
||||
char b = string.charAt(i);
|
||||
|
@ -741,7 +775,6 @@ public class StringUtil
|
|||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (started)
|
||||
return minus?(-val):val;
|
||||
throw new NumberFormatException(string);
|
||||
|
@ -759,7 +792,6 @@ public class StringUtil
|
|||
long val = 0;
|
||||
boolean started = false;
|
||||
boolean minus = false;
|
||||
|
||||
for (int i = 0; i < string.length(); i++)
|
||||
{
|
||||
char b = string.charAt(i);
|
||||
|
@ -780,7 +812,6 @@ public class StringUtil
|
|||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (started)
|
||||
return minus?(-val):val;
|
||||
throw new NumberFormatException(string);
|
||||
|
@ -799,12 +830,10 @@ public class StringUtil
|
|||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (str.length() <= maxSize)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
return str.substring(0,maxSize);
|
||||
}
|
||||
|
||||
|
@ -817,20 +846,18 @@ public class StringUtil
|
|||
{
|
||||
if (s==null)
|
||||
return new String[]{};
|
||||
|
||||
if (!s.startsWith("[") || !s.endsWith("]"))
|
||||
throw new IllegalArgumentException();
|
||||
if (s.length()==2)
|
||||
return new String[]{};
|
||||
|
||||
return csvSplit(s,1,s.length()-2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a CSV string using {@link #csvSplit(List,String, int, int)}
|
||||
* @param s The string to parse
|
||||
* @return An array of parsed values.
|
||||
*/
|
||||
* Parse a CSV string using {@link #csvSplit(List,String, int, int)}
|
||||
* @param s The string to parse
|
||||
* @return An array of parsed values.
|
||||
*/
|
||||
public static String[] csvSplit(String s)
|
||||
{
|
||||
if (s==null)
|
||||
|
@ -851,13 +878,12 @@ public class StringUtil
|
|||
return null;
|
||||
if (off<0 || len<0 || off>s.length())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
csvSplit(list,s,off,len);
|
||||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
enum CsvSplitState { PRE_DATA, QUOTE, SLOSH, DATA, WHITE, POST_DATA };
|
||||
enum CsvSplitState { PRE_DATA, QUOTE, SLOSH, DATA, WHITE, POST_DATA }
|
||||
|
||||
/** Split a quoted comma separated string to a list
|
||||
* <p>Handle <a href="https://www.ietf.org/rfc/rfc4180.txt">rfc4180</a>-like
|
||||
|
@ -890,7 +916,6 @@ public class StringUtil
|
|||
case PRE_DATA:
|
||||
if (Character.isWhitespace(ch))
|
||||
continue;
|
||||
|
||||
if ('"'==ch)
|
||||
{
|
||||
state=CsvSplitState.QUOTE;
|
||||
|
@ -902,11 +927,9 @@ public class StringUtil
|
|||
list.add("");
|
||||
continue;
|
||||
}
|
||||
|
||||
state=CsvSplitState.DATA;
|
||||
out.append(ch);
|
||||
continue;
|
||||
|
||||
case DATA:
|
||||
if (Character.isWhitespace(ch))
|
||||
{
|
||||
|
@ -923,7 +946,6 @@ public class StringUtil
|
|||
state=CsvSplitState.PRE_DATA;
|
||||
continue;
|
||||
}
|
||||
|
||||
out.append(ch);
|
||||
continue;
|
||||
|
||||
|
@ -947,7 +969,6 @@ public class StringUtil
|
|||
out.append(ch);
|
||||
last=-1;
|
||||
continue;
|
||||
|
||||
case QUOTE:
|
||||
if ('\\'==ch)
|
||||
{
|
||||
|
@ -978,13 +999,11 @@ public class StringUtil
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case PRE_DATA:
|
||||
case POST_DATA:
|
||||
break;
|
||||
|
||||
case DATA:
|
||||
case QUOTE:
|
||||
case SLOSH:
|
||||
|
@ -1011,7 +1030,6 @@ public class StringUtil
|
|||
loop: for (;i<html.length();i++)
|
||||
{
|
||||
char c=html.charAt(i);
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case '&' :
|
||||
|
@ -1020,13 +1038,11 @@ public class StringUtil
|
|||
case '\'':
|
||||
case '"':
|
||||
break loop;
|
||||
|
||||
default:
|
||||
if (Character.isISOControl(c) && !Character.isWhitespace(c))
|
||||
break loop;
|
||||
}
|
||||
}
|
||||
|
||||
// No characters need sanitizing, so return original string
|
||||
if (i==html.length())
|
||||
return html;
|
||||
|
@ -1039,7 +1055,6 @@ public class StringUtil
|
|||
for (;i<html.length();i++)
|
||||
{
|
||||
char c=html.charAt(i);
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case '&' :
|
||||
|
@ -1057,7 +1072,6 @@ public class StringUtil
|
|||
case '"':
|
||||
out.append(""");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Character.isISOControl(c) && !Character.isWhitespace(c))
|
||||
out.append('?');
|
||||
|
@ -1067,8 +1081,7 @@ public class StringUtil
|
|||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/** The String value of an Object
|
||||
* <p>This method calls {@link String#valueOf(Object)} unless the object is null,
|
||||
* in which case null is returned</p>
|
||||
|
|
|
@ -268,7 +268,19 @@ public class URIUtil
|
|||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode a raw URI String and convert any raw spaces to
|
||||
* their "%20" equivalent.
|
||||
*
|
||||
* @param str input raw string
|
||||
* @return output with spaces converted to "%20"
|
||||
*/
|
||||
public static String encodeSpaces(String str)
|
||||
{
|
||||
return StringUtil.replace(str, " ", "%20");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Encode a URI path.
|
||||
* @param path The path the encode
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Iterator;
|
|||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||
|
||||
|
@ -99,9 +100,15 @@ public interface Dumpable
|
|||
else if (o instanceof Map)
|
||||
s = String.format("%s@%x{size=%d}",o.getClass().getName(),o.hashCode(),((Map<?,?>)o).size());
|
||||
else if (o instanceof Dumpable)
|
||||
s = ((Dumpable)o).dumpSelf().replace("\r\n","|").replace("\n","|");
|
||||
{
|
||||
s = StringUtil.replace(((Dumpable)o).dumpSelf(), "\r\n", "|")
|
||||
.replace('\n', '|');
|
||||
}
|
||||
else
|
||||
s = String.valueOf(o).replace("\r\n","|").replace("\n","|");
|
||||
{
|
||||
s = StringUtil.replace(String.valueOf(o), "\r\n", "|")
|
||||
.replace('\n', '|');
|
||||
}
|
||||
|
||||
if (o instanceof LifeCycle)
|
||||
out.append(s).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n");
|
||||
|
|
|
@ -18,19 +18,21 @@
|
|||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.arrayContaining;
|
||||
import static org.hamcrest.Matchers.emptyArray;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class StringUtilTest
|
||||
|
@ -98,7 +100,36 @@ public class StringUtilTest
|
|||
|
||||
s=" \u0690bc ";
|
||||
assertEquals(StringUtil.replace(s, "\u0690bc", "xyz")," xyz ");
|
||||
}
|
||||
|
||||
public static Stream<String[]> replaceFirstArgs() {
|
||||
List<String[]> data = new ArrayList<>();
|
||||
|
||||
// [original, target, replacement, expected]
|
||||
|
||||
// no match
|
||||
data.add(new String[]{ "abc", "z", "foo", "abc" });
|
||||
|
||||
// matches at start of string
|
||||
data.add(new String[]{ "abc", "a", "foo", "foobc" });
|
||||
data.add(new String[]{ "abcabcabc", "a", "foo", "foobcabcabc" });
|
||||
|
||||
// matches in middle of string
|
||||
data.add(new String[]{ "abc", "b", "foo", "afooc" });
|
||||
data.add(new String[]{ "abcabcabc", "b", "foo", "afoocabcabc" });
|
||||
data.add(new String[]{ "abcabcabc", "cab", "X", "abXcabc" });
|
||||
|
||||
// matches at end of string
|
||||
data.add(new String[]{ "abc", "c", "foo", "abfoo" });
|
||||
|
||||
return data.stream();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource(value = "replaceFirstArgs")
|
||||
public void testReplaceFirst(String original, String target, String replacement, String expected)
|
||||
{
|
||||
assertThat(StringUtil.replaceFirst(original, target, replacement), is(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -165,50 +196,6 @@ public class StringUtilTest
|
|||
assertEquals(sid5, StringUtil.sidBytesToString(sid5Bytes));
|
||||
assertEquals(sid6, StringUtil.sidBytesToString(sid6Bytes));
|
||||
assertEquals(sid12, StringUtil.sidBytesToString(sid12Bytes));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] arg) throws Exception
|
||||
{
|
||||
String string = "Now \u0690xxxxxxxx";
|
||||
System.err.println(string);
|
||||
byte[] bytes=string.getBytes(StandardCharsets.UTF_8);
|
||||
System.err.println(new String(bytes));
|
||||
System.err.println(bytes.length);
|
||||
long calc=0;
|
||||
Utf8StringBuffer strbuf = new Utf8StringBuffer(bytes.length);
|
||||
for (int i=0;i<10;i++)
|
||||
{
|
||||
long s1=TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
|
||||
for (int j=1000000; j-->0;)
|
||||
{
|
||||
calc+=new String(bytes,0,bytes.length,StandardCharsets.UTF_8).hashCode();
|
||||
}
|
||||
long s2=TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
|
||||
for (int j=1000000; j-->0;)
|
||||
{
|
||||
calc+=StringUtil.toUTF8String(bytes,0,bytes.length).hashCode();
|
||||
}
|
||||
long s3=TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
|
||||
for (int j=1000000; j-->0;)
|
||||
{
|
||||
Utf8StringBuffer buffer = new Utf8StringBuffer(bytes.length);
|
||||
buffer.append(bytes,0,bytes.length);
|
||||
calc+=buffer.toString().hashCode();
|
||||
}
|
||||
long s4=TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
|
||||
for (int j=1000000; j-->0;)
|
||||
{
|
||||
strbuf.reset();
|
||||
strbuf.append(bytes,0,bytes.length);
|
||||
calc+=strbuf.toString().hashCode();
|
||||
}
|
||||
long s5=TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
|
||||
|
||||
System.err.println((s2-s1)+", "+(s3-s2)+", "+(s4-s3)+", "+(s5-s4));
|
||||
}
|
||||
System.err.println(calc);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -703,7 +703,7 @@ public class ClasspathPattern extends AbstractSet<String>
|
|||
name=name.substring(0,name.length()-6);
|
||||
|
||||
// Treat path elements as packages for name matching
|
||||
name=name.replace("/",".");
|
||||
name = name.replace('/', '.');
|
||||
|
||||
return combine(_packageOrNamePatterns, name, _locations, ()->
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.eclipse.jetty.server.Server;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.JavaVersion;
|
||||
import org.eclipse.jetty.util.PatternMatcher;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -210,7 +211,8 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
}
|
||||
catch (URISyntaxException e)
|
||||
{
|
||||
containerUris.add(new URI(u.toString().replaceAll(" ", "%20")));
|
||||
String fixedUriStr = StringUtil.replace(u.toString(), " ", "%20");
|
||||
containerUris.add(new URI(fixedUriStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ package com.acme;
|
|||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.Cookie;
|
||||
|
@ -29,7 +28,6 @@ import javax.servlet.http.HttpServlet;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Test Servlet Cookies.
|
||||
*/
|
||||
|
@ -117,9 +115,9 @@ public class CookieDump extends HttpServlet
|
|||
{
|
||||
if (string==null)
|
||||
return null;
|
||||
string=string.replace("&", "&");
|
||||
string=string.replace( "<", "<");
|
||||
string=string.replace( ">", ">");
|
||||
string = string.replace("&", "&");
|
||||
string = string.replace( "<", "<");
|
||||
string = string.replace( ">", ">");
|
||||
return string;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ import java.util.Enumeration;
|
|||
import java.util.Locale;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.AsyncEvent;
|
||||
import javax.servlet.AsyncListener;
|
||||
|
@ -57,13 +56,14 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import javax.servlet.http.HttpServletResponseWrapper;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Dump Servlet Request.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class Dump extends HttpServlet
|
||||
{
|
||||
/** Zero Width Space, to allow text to be wrapped at designated spots */
|
||||
private static final String ZWSP = "​";
|
||||
boolean fixed;
|
||||
Timer _timer;
|
||||
|
||||
|
@ -647,7 +647,7 @@ public class Dump extends HttpServlet
|
|||
{
|
||||
name= (String)a.nextElement();
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+": </th>");
|
||||
pout.write("<th align=\"right\" valign=\"top\">" + name.replace(".", ZWSP + ".") + ": </th>");
|
||||
Object value=request.getAttribute(name);
|
||||
if (value instanceof File)
|
||||
{
|
||||
|
@ -678,7 +678,7 @@ public class Dump extends HttpServlet
|
|||
{
|
||||
name= (String)a.nextElement();
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+": </th>");
|
||||
pout.write("<th align=\"right\" valign=\"top\">" + name.replace(".", ZWSP + ".") + ": </th>");
|
||||
pout.write("<td>"+ toString(getServletContext().getInitParameter(name)) + "</td>");
|
||||
}
|
||||
|
||||
|
@ -689,7 +689,7 @@ public class Dump extends HttpServlet
|
|||
{
|
||||
name= (String)a.nextElement();
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+": </th>");
|
||||
pout.write("<th align=\"right\" valign=\"top\">" + name.replace(".", ZWSP + ".") + ": </th>");
|
||||
pout.write("<td>"+"<pre>" + toString(getServletContext().getAttribute(name)) + "</pre>"+"</td>");
|
||||
}
|
||||
|
||||
|
@ -1055,9 +1055,9 @@ public class Dump extends HttpServlet
|
|||
{
|
||||
if (s==null)
|
||||
return "null";
|
||||
s=s.replaceAll("&","&");
|
||||
s=s.replaceAll("<","<");
|
||||
s=s.replaceAll(">",">");
|
||||
s = s.replace("&","&");
|
||||
s = s.replace("<","<");
|
||||
s = s.replace(">",">");
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue