Merge `jetty-9.4.x` into `jetty-10.0.x`

Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>

# Conflicts:
#	examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java
#	jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java
#	jetty-http/src/test/java/org/eclipse/jetty/http/QuotedCSVTest.java
#	jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyWebAppContext.java
#	jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java
#	jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java
#	jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java
#	jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java
#	jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
#	jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/WSServer.java
#	jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WSServer.java
#	tests/test-integration/src/test/java/org/eclipse/jetty/test/support/XmlBasedJettyServer.java
This commit is contained in:
Joakim Erdfelt 2019-06-13 14:14:42 -05:00
commit 60d8661890
53 changed files with 817 additions and 331 deletions

View File

@ -24,7 +24,6 @@ import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Queue;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@ -67,12 +66,25 @@ public class AbstractRestServlet extends HttpServlet
_appid = servletConfig.getInitParameter(APPID_PARAM);
}
public static String sanitize(String s)
// TODO: consider using StringUtil.sanitizeFileSystemName instead of this?
// might introduce jetty-util dependency though
public static String sanitize(String str)
{
if (s==null)
if (str == null)
return null;
return s.replace("<","?").replace("&","?").replace("\n","?");
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 == '<') || (c == '&'))
{
chars[i] = '?';
}
}
return String.valueOf(chars);
}
protected String restURL(String item)

View File

@ -37,6 +37,8 @@ import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.ManifestUtils;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.MultiReleaseJarFile;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
@ -150,7 +152,7 @@ public class AnnotationParser
if (name.endsWith(".class"))
name = name.substring(0, name.length()-".class".length());
return name.replace('/', '.');
return StringUtil.replace(name,'/', '.');
}
/**
@ -582,13 +584,12 @@ public class AnnotationParser
if (className == null)
return;
String tmp = className;
className = className.replace('.', '/')+".class";
URL resource = Loader.getResource(className);
String classRef = TypeUtil.toClassReference(className);
URL resource = Loader.getResource(classRef);
if (resource!= null)
{
Resource r = Resource.newResource(resource);
addParsedClass(tmp, r);
addParsedClass(className, r);
try (InputStream is = r.getInputStream())
{
scanClass(handlers, null, is);
@ -609,7 +610,7 @@ public class AnnotationParser
Class<?> cz = clazz;
while (cz != Object.class)
{
String nameAsResource = cz.getName().replace('.', '/')+".class";
String nameAsResource = TypeUtil.toClassReference(cz);
URL resource = Loader.getResource(nameAsResource);
if (resource!= null)
{
@ -654,17 +655,16 @@ public class AnnotationParser
{
MultiException me = new MultiException();
for (String s:classNames)
for (String className : classNames)
{
try
{
String name = s;
s = s.replace('.', '/')+".class";
URL resource = Loader.getResource(s);
String classRef = TypeUtil.toClassReference(className);
URL resource = Loader.getResource(classRef);
if (resource!= null)
{
Resource r = Resource.newResource(resource);
addParsedClass(name, r);
addParsedClass(className, r);
try (InputStream is = r.getInputStream())
{
scanClass(handlers, null, is);
@ -673,7 +673,7 @@ public class AnnotationParser
}
catch (Exception e)
{
me.add(new RuntimeException("Error scanning class "+s, e));
me.add(new RuntimeException("Error scanning class "+className, e));
}
}
me.ifExceptionThrow();
@ -710,8 +710,9 @@ public class AnnotationParser
{
Path classpath = rootFile.toPath().relativize(file.toPath());
String str = classpath.toString();
str = str.substring(0, str.lastIndexOf(".class")).replace('/', '.').replace('\\', '.');
str = str.substring(0, str.lastIndexOf(".class"));
str = StringUtil.replace(str, File.separatorChar, '.');
try
{
if (LOG.isDebugEnabled())
@ -877,7 +878,7 @@ public class AnnotationParser
//check file is a valid class file name
if (isValidClassFileName(name) && isValidClassFilePath(name))
{
String shortName = name.replace('/', '.').substring(0,name.length()-6);
String shortName = StringUtil.replace(name, '/', '.').substring(0, name.length() - 6);
addParsedClass(shortName, Resource.newResource("jar:"+jar.getURI()+"!/"+entry.getNameInJar()));
if (LOG.isDebugEnabled())
LOG.debug("Scanning class from jar {}!/{}", jar, entry);

View File

@ -19,11 +19,12 @@
package org.eclipse.jetty.annotations;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
@ -42,6 +43,7 @@ import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
import org.junit.jupiter.api.Test;
@ -298,25 +300,17 @@ public class TestAnnotationParser
private void copyClass(Class<?> clazz, File basedir) throws IOException
{
String classname = clazz.getName().replace('.',File.separatorChar) + ".class";
URL url = this.getClass().getResource('/'+classname);
assertThat("URL for: " + classname,url,notNullValue());
String classRef = TypeUtil.toClassReference(clazz);
URL url = this.getClass().getResource('/' + classRef);
assertThat("URL for: " + classRef, url, notNullValue());
String classpath = classname.substring(0,classname.lastIndexOf(File.separatorChar));
FS.ensureDirExists(new File(basedir,classpath));
Path outputFile = basedir.toPath().resolve(classRef);
FS.ensureDirExists(outputFile.getParent());
InputStream in = null;
OutputStream out = null;
try
try (InputStream in = url.openStream();
OutputStream out = Files.newOutputStream(outputFile))
{
in = url.openStream();
out = new FileOutputStream(new File(basedir,classname));
IO.copy(in,out);
}
finally
{
IO.close(out);
IO.close(in);
IO.copy(in, out);
}
}
}

View File

@ -35,7 +35,7 @@ public class AntWebInfConfiguration extends WebInfConfiguration
{
return WebInfConfiguration.class;
}
/**
* Adds classpath files into web application classloader, and
* sets web.xml and base directory for the configured web application.

View File

@ -35,6 +35,7 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.StringUtil;
public class HttpSenderOverFCGI extends HttpSender
{
@ -88,7 +89,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_" + StringUtil.replace(name, '-', '_').toUpperCase(Locale.ENGLISH);
fcgiHeaders.add(fcgiName, field.getValue());
}

View File

@ -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

View File

@ -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());
}

View File

@ -20,6 +20,7 @@ package org.eclipse.jetty.http;
import java.util.Collections;
import org.eclipse.jetty.util.StringUtil;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
@ -114,13 +115,13 @@ public class QuotedCSVTest
{
if (buffer.toString().contains("DELETE"))
{
String s = buffer.toString().replace("DELETE","");
String s = StringUtil.strip(buffer.toString(), "DELETE");
buffer.setLength(0);
buffer.append(s);
}
if (buffer.toString().contains("APPEND"))
{
String s = buffer.toString().replace("APPEND","Append")+"!";
String s = StringUtil.replace(buffer.toString(), "APPEND", "Append") + "!";
buffer.setLength(0);
buffer.append(s);
}

View File

@ -48,6 +48,7 @@ import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@ -167,7 +168,7 @@ public class ProxyProtocolTest
// String is: "MAGIC VER|CMD FAM|PROT LEN SRC_ADDR DST_ADDR SRC_PORT DST_PORT PP2_TYPE_SSL LEN CLIENT VERIFY PP2_SUBTYPE_SSL_VERSION LEN 1.2"
String request1 = "0D0A0D0A000D0A515549540A 21 11 001A 0A000004 0A000005 8420 22B8 20 000B 01 00000000 21 0003 312E32";
request1 = request1.replace(" ", "");
request1 = StringUtil.strip(request1, " ");
SocketChannel channel = SocketChannel.open();
channel.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
channel.write(ByteBuffer.wrap(TypeUtil.fromHexString(request1)));

View File

@ -25,7 +25,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
@ -41,6 +40,7 @@ import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.WriteFlusher;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
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.thread.Invocable;
@ -584,7 +584,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
if (LOG.isDebugEnabled())
LOG.debug("unwrap net_filled={} {} encryptedBuffer={} unwrapBuffer={} appBuffer={}",
net_filled,
unwrapResult.toString().replace('\n', ' '),
StringUtil.replace(unwrapResult.toString(), '\n', ' '),
BufferUtil.toSummaryString(_encryptedInput),
BufferUtil.toDetailString(app_in),
BufferUtil.toDetailString(buffer));
@ -895,7 +895,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
}
if (LOG.isDebugEnabled())
LOG.debug("wrap {} {} ioDone={}/{}",
wrapResult.toString().replace('\n', ' '),
StringUtil.replace(wrapResult.toString(), '\n', ' '),
BufferUtil.toSummaryString(_encryptedOutput),
_sslEngine.isInboundDone(),
_sslEngine.isOutboundDone());

View File

@ -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();
}
}

View File

@ -30,7 +30,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
@ -39,6 +38,7 @@ import javax.management.ObjectName;
import javax.management.modelmbean.ModelMBean;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Container;
@ -394,15 +394,7 @@ public class MBeanContainer implements Container.InheritedListener, Dumpable, De
*/
public String makeName(String basis)
{
if (basis == null)
return null;
return basis
.replace(':', '_')
.replace('*', '_')
.replace('?', '_')
.replace('=', '_')
.replace(',', '_')
.replace(' ', '_');
return StringUtil.sanitizeFileSystemName(basis);
}
@Override

View File

@ -43,6 +43,7 @@ import org.apache.maven.project.MavenProject;
import org.eclipse.jetty.maven.plugin.utils.MavenProjectHelper;
import org.eclipse.jetty.util.PathWatcher;
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceCollection;
import org.eclipse.jetty.webapp.WebAppContext;
@ -661,7 +662,7 @@ public class JettyRunMojo extends AbstractJettyMojo
int i = name.lastIndexOf('/');
if (i>0)
name = name.substring(i+1,name.length());
name = name.replace('.', '_');
name = StringUtil.replace(name, '.', '_');
//name = name+(++COUNTER); //add some digits to ensure uniqueness
File overlaysDir = new File (project.getBuild().getDirectory(), "jetty_overlays");
File dir = new File(overlaysDir, name);

View File

@ -183,7 +183,7 @@ public class JettyWebAppContext extends WebAppContext
/**
* Ordered list of wars to overlay on top of the current project. The list
* may contain an overlay that represents the current project.
*
*
* @param overlays the list of overlays
*/
public void setOverlays(List<Overlay> overlays)
@ -194,7 +194,7 @@ public class JettyWebAppContext extends WebAppContext
/**
* Set the name of the attribute that is used in each generated xml element
* to indicate the source of the xml element (eg annotation, web.xml etc).
*
*
* @param name the name of the attribute to use.
*/
public void setOriginAttribute(String name)
@ -214,7 +214,7 @@ public class JettyWebAppContext extends WebAppContext
/**
* Toggle whether or not the origin attribute will be generated into the
* xml.
*
*
* @param generateOrigin if true then the origin of each xml element is
* added, otherwise it is omitted.
*/
@ -249,7 +249,7 @@ public class JettyWebAppContext extends WebAppContext
/**
* Set the file to use into which to generate the quickstart output.
*
*
* @param quickStartWebXml the full path to the file to use
* @throws Exception
*/
@ -260,7 +260,7 @@ public class JettyWebAppContext extends WebAppContext
/**
* Set the Resource to use into which to generate the quickstart output.
*
*
* @param quickStartWebXml
*/
protected void setQuickStartWebDescriptor(Resource quickStartWebXml)
@ -282,7 +282,7 @@ public class JettyWebAppContext extends WebAppContext
/**
* This method is provided as a convenience for jetty maven plugin
* configuration
*
*
* @param resourceBases Array of resources strings to set as a
* {@link ResourceCollection}. Each resource string may be a
* comma separated list of resources
@ -311,7 +311,7 @@ public class JettyWebAppContext extends WebAppContext
/**
* If true, a quickstart for the webapp is generated.
*
*
* @param quickStart if true the quickstart is generated, false otherwise
*/
public void setGenerateQuickStart(boolean quickStart)
@ -475,7 +475,7 @@ public class JettyWebAppContext extends WebAppContext
int i = 0;
while (res == null && (i < _webInfClasses.size()))
{
String newPath = uri.replace(WEB_INF_CLASSES_PREFIX, _webInfClasses.get(i).getPath());
String newPath = StringUtil.replace(uri, WEB_INF_CLASSES_PREFIX, _webInfClasses.get(i).getPath());
res = Resource.newResource(newPath);
if (!res.exists())
{
@ -490,9 +490,11 @@ public class JettyWebAppContext extends WebAppContext
{
// Return the real jar file for all accesses to
// /WEB-INF/lib/*.jar
String jarName = uri.replace(WEB_INF_LIB_PREFIX, "");
if (jarName.startsWith("/") || jarName.startsWith("\\")) jarName = jarName.substring(1);
if (jarName.length() == 0) return null;
String jarName = StringUtil.strip(uri, WEB_INF_LIB_PREFIX);
if (jarName.startsWith("/") || jarName.startsWith("\\"))
jarName = jarName.substring(1);
if (jarName.length()==0)
return null;
File jarFile = _webInfJarMap.get(jarName);
if (jarFile != null) return Resource.newResource(jarFile.getPath());
@ -538,7 +540,7 @@ public class JettyWebAppContext extends WebAppContext
while (i < _webInfClasses.size())
{
String newPath = path.replace(WEB_INF_CLASSES_PREFIX, _webInfClasses.get(i).getPath());
String newPath = StringUtil.replace(path, WEB_INF_CLASSES_PREFIX, _webInfClasses.get(i).getPath());
allPaths.addAll(super.getResourcePaths(newPath));
i++;
}

View File

@ -33,6 +33,7 @@ import java.util.jar.Manifest;
import org.codehaus.plexus.util.SelectorUtils;
import org.eclipse.jetty.util.IO;
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;
@ -146,7 +147,7 @@ public class SelectiveJarResource extends JarResource
String entryName = entry.getName();
LOG.debug("Looking at "+entryName);
String dotCheck = entryName.replace('\\', '/');
String dotCheck = StringUtil.replace(entryName, '\\', '/');
dotCheck = URIUtil.canonicalPath(dotCheck);
if (dotCheck == null)
{

View File

@ -41,6 +41,7 @@ import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.UnreadableSessionDataException;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.log.Log;
@ -573,8 +574,8 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
{
if (vhost == null)
return "";
return vhost.replace('.', '_');
return StringUtil.replace(vhost, '.', '_');
}

View File

@ -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.URIUtil;
/**
* MongoUtils
@ -69,23 +69,17 @@ public class MongoUtils
throw new IllegalStateException(valueToDecode.getClass().toString());
}
}
public static String decodeName(String name)
{
return name.replace("%2E",".").replace("%25","%");
return URIUtil.decodeSpecific(name, ".%");
}
public static String encodeName(String name)
{
return name.replace("%","%25").replace(".","%2E");
return URIUtil.encodeSpecific(name, ".%");
}
public static Object encodeName(Object value) throws IOException
{
if (value instanceof Number || value instanceof String || value instanceof Boolean || value instanceof Date)

View File

@ -30,6 +30,7 @@ import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.resource.Resource;
import org.objectweb.asm.Opcodes;
import org.osgi.framework.Bundle;
@ -209,7 +210,7 @@ public class AnnotationParser extends org.eclipse.jetty.annotations.AnnotationPa
continue;
}
//transform into a classname to pass to the resolver
String shortName = name.replace('/', '.').substring(0,name.length()-6);
String shortName = StringUtil.replace(name, '/', '.').substring(0, name.length() - 6);
addParsedClass(shortName, getResource(bundle));
try (InputStream classInputStream = classUrl.openStream())

View File

@ -280,7 +280,7 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund
// the location will often reflect the version.
// maybe this is relevant when the file is a war)
String location = bundle.getLocation();
String toks[] = location.replace('\\', '/').split("/");
String toks[] = StringUtil.replace(location, '\\', '/').split("/");
contextPath = toks[toks.length - 1];
// remove .jar, .war etc:
int lastDot = contextPath.lastIndexOf('.');

View File

@ -30,10 +30,10 @@ import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.JarFile;
import javax.servlet.http.HttpServlet;
import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelperFactory;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
@ -61,12 +61,12 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
public static void addClassThatIdentifiesAJarThatMustBeRejected(Class<?> zclass)
{
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclass.getName().replace('.', '/') + ".class");
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(TypeUtil.toClassReference(zclass.getName()));
}
public static void addClassThatIdentifiesAJarThatMustBeRejected(String zclassName)
{
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(zclassName.replace('.', '/') + ".class");
JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(TypeUtil.toClassReference(zclassName));
}
static

View File

@ -30,6 +30,7 @@ import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -238,8 +239,9 @@ public class NamingEntryUtil
if (scope==null)
return "";
String str = scope.getClass().getName()+"@"+Long.toHexString(scope.hashCode());
str=str.replace('/', '_').replace(' ', '_');
String str = scope.getClass().getName() + "@" + Long.toHexString(scope.hashCode());
str = StringUtil.replace(str, '/', '_');
str = StringUtil.replace(str, ' ', '_');
return str;
}
}

View File

@ -49,6 +49,7 @@ import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.util.HttpCookieStore;
import org.eclipse.jetty.util.ProcessorUtils;
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.thread.QueuedThreadPool;
@ -201,7 +202,7 @@ public abstract class AbstractProxyServlet extends HttpServlet
protected Logger createLogger()
{
String servletName = getServletConfig().getServletName();
servletName = servletName.replace('-', '.');
servletName = StringUtil.replace(servletName, '-', '.');
if ((getClass().getPackage() != null) && !servletName.startsWith(getClass().getPackage().getName()))
{
servletName = getClass().getName() + "." + servletName;

View File

@ -44,7 +44,6 @@ import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.zip.GZIPOutputStream;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
@ -87,6 +86,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
@ -678,7 +678,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(StringUtil.replace((prefix + target), "//", "/"))
.timeout(5, TimeUnit.SECONDS)
.send();
assertEquals(200, response.getStatus());

View File

@ -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)

View File

@ -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;
/**
@ -83,7 +84,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);
@ -100,7 +101,12 @@ 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();
}
}

View File

@ -20,7 +20,6 @@ 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;

View File

@ -129,7 +129,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.sanitizeFileSystemName(uri.substring(colon + 2));
Path tmpDirectory = Files.createTempDirectory("users_store");
tmpDirectory.toFile().deleteOnExit();

View File

@ -53,12 +53,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;
@ -238,7 +236,7 @@ public class Response implements HttpServletResponse
if (i >= 0)
{
httpOnly = true;
comment = comment.replace(HTTP_ONLY_COMMENT, "").trim();
comment = StringUtil.strip(comment.trim(), HTTP_ONLY_COMMENT);
if (comment.length() == 0)
comment = null;
}
@ -1153,7 +1151,7 @@ public class Response implements HttpServletResponse
return;
_locale = locale;
_fields.put(HttpHeader.CONTENT_LANGUAGE, locale.toString().replace('_', '-'));
_fields.put(HttpHeader.CONTENT_LANGUAGE, StringUtil.replace(locale.toString(), '_', '-'));
if (_outputType != OutputType.NONE)
return;

View File

@ -164,7 +164,7 @@ public class DefaultHandler extends AbstractHandler
{
writer.append("<a href=\"").append(href).append("\">");
}
writer.append(contextPath.replaceAll("%", "&#37;"));
writer.append(StringUtil.replace(contextPath, "%", "&#37;"));
if (context.isRunning())
{
writer.append("</a>");

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.server.session;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.util.StringUtil;
/**
* SessionContext
@ -138,7 +139,6 @@ public class SessionContext
if (path==null)
return "";
return path.replace('/', '_').replace('.','_').replace('\\','_');
return StringUtil.sanitizeFileSystemName(path);
}
}

View File

@ -18,8 +18,6 @@
package org.eclipse.jetty.server;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
@ -29,7 +27,6 @@ import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
@ -40,6 +37,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.IO;
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.thread.QueuedThreadPool;
@ -49,6 +47,8 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@Disabled
@Tag("stress")
public class AsyncStressTest
@ -123,7 +123,7 @@ public class AsyncStressTest
int p=path[i][l]=_random.nextInt(__paths.length);
int period = _random.nextInt(290)+10;
String uri=__paths[p][0].replace("<PERIOD>",Integer.toString(period));
String uri = StringUtil.replace(__paths[p][0], "<PERIOD>", Integer.toString(period));
long start=TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
String request =

View File

@ -957,7 +957,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
}
catch (Exception e)
{
String tmp = jsp.replace('.','_');
String tmp = StringUtil.replace(jsp, '.', '_');
if (LOG.isDebugEnabled())
{
LOG.warn("JspUtil.makeJavaIdentifier failed for jsp "+jsp +" using "+tmp+" instead");
@ -994,9 +994,9 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
s = 1;
//remove the element after last slash, which should be name of jsp
tmp = tmp.substring(s,i);
tmp = tmp.substring(s,i).trim();
tmp = tmp.replace('/','.').trim();
tmp = StringUtil.replace(tmp, '/', '.');
tmp = (".".equals(tmp)? "": tmp);
if (LOG.isDebugEnabled())
{

View File

@ -21,7 +21,6 @@ package org.eclipse.jetty.servlet;
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;
@ -31,6 +30,7 @@ import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.tools.HttpTester;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.StringUtil;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@ -144,7 +144,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 = StringUtil.replace(actualPathInfo, "%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));

View File

@ -29,7 +29,6 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@ -324,7 +323,7 @@ public class CGI extends HttpServlet
if (name.equalsIgnoreCase("Proxy"))
continue;
String value = req.getHeader(name);
env.set("HTTP_" + name.toUpperCase(Locale.ENGLISH).replace('-', '_'), value);
env.set("HTTP_" + StringUtil.replace(name.toUpperCase(Locale.ENGLISH), '-', '_'), value);
}
// these extra ones were from printenv on www.dev.nomura.co.uk

View File

@ -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)

View File

@ -34,6 +34,7 @@ import org.eclipse.jetty.http.tools.HttpTester;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlet.ServletTester;
import org.eclipse.jetty.util.StringUtil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -94,7 +95,7 @@ public class CrossOriginFilterTest
CountDownLatch latch = new CountDownLatch(1);
tester.getContext().addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
String otherOrigin = origin.replace("localhost", "127.0.0.1");
String otherOrigin = StringUtil.replace(origin, "localhost", "127.0.0.1");
String request = "" +
"GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" +
@ -284,7 +285,7 @@ public class CrossOriginFilterTest
{
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
String origin = "http://localhost";
String otherOrigin = origin.replace("localhost", "127.0.0.1");
String otherOrigin = StringUtil.replace(origin, "localhost", "127.0.0.1");
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, origin + "," + otherOrigin);
tester.getContext().addFilter(filterHolder, "/*", EnumSet.of(DispatcherType.REQUEST));

View File

@ -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
{
@ -44,7 +43,7 @@ public class StringUtil
public static final String ALL_INTERFACES="0.0.0.0";
public static final String CRLF="\015\012";
public static final String __ISO_8859_1="iso-8859-1";
public final static String __UTF8="utf-8";
public final static String __UTF16="utf-16";
@ -58,8 +57,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
@ -70,8 +68,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
@ -84,9 +81,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',
@ -105,7 +100,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
@ -118,7 +112,6 @@ public class StringUtil
char[] c = null;
int i=s.length();
// look for first conversion
while (i-->0)
{
@ -134,7 +127,6 @@ public class StringUtil
}
}
}
while (i-->0)
{
if(c[i]<=127)
@ -144,8 +136,55 @@ 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 filesystems.
*
* <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: pipe, redirect, combine, slash, equivalence, bang, glob, selection, etc...</li>
* <li>Space</li>
* </ul>
*
* @param str the raw input string
* @return the sanitized output string. or null if {@code str} is null.
*/
public static String sanitizeFileSystemName(String str)
{
if (str == null)
return null;
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
// piping : special meaning on unix / osx / windows
(c == '|') || (c == '>') || (c == '<') || (c == '/') || (c == '&') ||
// special characters on windows
(c == '\\') || (c == '.') || (c == ':') ||
// special characters on osx
(c == '=') || (c == '"') || (c == ',') ||
// glob / selection characters on most OS's
(c == '*') || (c == '?') ||
// bang execution on unix / osx
(c == '!') ||
// spaces are just generally difficult to work with
(c == ' '))
{
chars[i] = '_';
}
}
return String.valueOf(chars);
}
/* ------------------------------------------------------------ */
public static boolean startsWithIgnoreCase(String s,String w)
{
if (w==null)
@ -170,13 +209,11 @@ public class StringUtil
}
return true;
}
/* ------------------------------------------------------------ */
public static boolean endsWithIgnoreCase(String s,String w)
{
if (w==null)
return true;
if (s==null)
return false;
@ -202,8 +239,7 @@ public class StringUtil
}
return true;
}
/* ------------------------------------------------------------ */
/**
* returns the next index of a character from the chars string
* @param s the input string to search
@ -217,10 +253,48 @@ public class StringUtil
return i;
return -1;
}
/* ------------------------------------------------------------ */
/**
* replace substrings within string.
* Replace chars within string.
* <p>
* Fast replacement for {@code java.lang.String#}{@link String#replace(char, char)}
* </p>
*
* @param str the input string
* @param find the char to look for
* @param with the char to replace with
* @return the now replaced string
*/
public static String replace(String str, char find, char with)
{
if (str == null)
return null;
if (find == with)
return str;
int c = 0;
int idx = str.indexOf(find, c);
if (idx == -1)
{
return str;
}
char[] chars = str.toCharArray();
int len = chars.length;
for (int i = idx; i < len; i++)
{
if (chars[i] == find)
chars[i] = with;
}
return String.valueOf(chars);
}
/**
* 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
@ -228,28 +302,70 @@ public class StringUtil
*/
public static String replace(String s, String sub, String with)
{
int c=0;
int i=s.indexOf(sub,c);
if (i == -1)
return s;
StringBuilder buf = new StringBuilder(s.length()+with.length());
if (s == null)
return null;
int c = 0;
int i = s.indexOf(sub, c);
if (i == -1)
{
return s;
}
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()));
return buf.toString();
c = i + sub.length();
}
while ((i = s.indexOf(sub, c)) != -1);
if (c < s.length())
{
buf.append(s.substring(c));
}
return buf.toString();
}
/* ------------------------------------------------------------ */
/** Append substring to StringBuilder
/**
* 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
*/
@Deprecated
public static String unquote(String s)
{
return QuotedStringTokenizer.unquote(s);
}
/** Append substring to StringBuilder
* @param buf StringBuilder to append to
* @param s String to append from
* @param offset The offset of the substring
@ -272,8 +388,6 @@ public class StringUtil
}
}
/* ------------------------------------------------------------ */
/**
* append hex digit
* @param buf the buffer to append to
@ -294,7 +408,6 @@ public class StringUtil
buf.append((char)c);
}
/* ------------------------------------------------------------ */
/**
* Append 2 digits (zero padded) to the StringBuffer
*
@ -309,8 +422,7 @@ public class StringUtil
buf.append((char)(i%10+'0'));
}
}
/* ------------------------------------------------------------ */
/**
* Append 2 digits (zero padded) to the StringBuilder
*
@ -325,8 +437,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.
@ -337,8 +448,7 @@ public class StringUtil
return "";
return s;
}
/* ------------------------------------------------------------ */
public static boolean equals(String s,char[] buf, int offset, int length)
{
if (s.length()!=length)
@ -349,13 +459,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
@ -364,6 +472,7 @@ public class StringUtil
}
catch (UnsupportedEncodingException e)
{
LOG.warn(e);
throw new IllegalArgumentException(e);
}
}
@ -415,7 +524,6 @@ public class StringUtil
return -1;
}
/* ------------------------------------------------------------ */
/**
* Test if a string is null or only has whitespace characters in it.
* <p>
@ -478,7 +586,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>
@ -518,14 +625,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)
@ -540,7 +644,7 @@ public class StringUtil
return buf.toString();
}
/* ------------------------------------------------------------ */
public static String printable(byte[] b)
{
StringBuilder buf = new StringBuilder();
@ -580,7 +684,7 @@ public class StringUtil
return s.getBytes();
}
}
/**
* Convert String to an integer. Parses up to the first non-numeric character. If no number is found an IllegalArgumentException is thrown
*
@ -593,7 +697,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);
@ -614,7 +717,6 @@ public class StringUtil
else
break;
}
if (started)
return minus?(-val):val;
throw new NumberFormatException(string);
@ -632,7 +734,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);
@ -653,7 +754,6 @@ public class StringUtil
else
break;
}
if (started)
return minus?(-val):val;
throw new NumberFormatException(string);
@ -672,12 +772,10 @@ public class StringUtil
{
return null;
}
if (str.length() <= maxSize)
{
return str;
}
return str.substring(0,maxSize);
}
@ -690,20 +788,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)
@ -724,13 +820,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
@ -763,7 +858,6 @@ public class StringUtil
case PRE_DATA:
if (Character.isWhitespace(ch))
continue;
if ('"'==ch)
{
state=CsvSplitState.QUOTE;
@ -775,11 +869,9 @@ public class StringUtil
list.add("");
continue;
}
state=CsvSplitState.DATA;
out.append(ch);
continue;
case DATA:
if (Character.isWhitespace(ch))
{
@ -796,7 +888,6 @@ public class StringUtil
state=CsvSplitState.PRE_DATA;
continue;
}
out.append(ch);
continue;
@ -820,7 +911,6 @@ public class StringUtil
out.append(ch);
last=-1;
continue;
case QUOTE:
if ('\\'==ch)
{
@ -851,13 +941,11 @@ public class StringUtil
continue;
}
}
switch(state)
{
case PRE_DATA:
case POST_DATA:
break;
case DATA:
case QUOTE:
case SLOSH:
@ -884,7 +972,6 @@ public class StringUtil
loop: for (;i<html.length();i++)
{
char c=html.charAt(i);
switch(c)
{
case '&' :
@ -893,13 +980,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;
@ -912,7 +997,6 @@ public class StringUtil
for (;i<html.length();i++)
{
char c=html.charAt(i);
switch(c)
{
case '&' :
@ -930,7 +1014,6 @@ public class StringUtil
case '"':
out.append("&quot;");
break;
default:
if (Character.isISOControl(c) && !Character.isWhitespace(c))
out.append('?');
@ -940,8 +1023,12 @@ public class StringUtil
}
return out.toString();
}
/* ------------------------------------------------------------ */
public static String strip(String str, String find)
{
return StringUtil.replace(str, find, "");
}
/** 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>

View File

@ -207,6 +207,46 @@ public class TypeUtil
return class2Name.get(type);
}
/**
* Return the Classpath / Classloader reference for the
* provided class file.
*
* <p>
* Convenience method for the code
* </p>
*
* <pre>
* String ref = myObject.getClass().getName().replace('.','/') + ".class";
* </pre>
*
* @param clazz the class to reference
* @return the classpath reference syntax for the class file
*/
public static String toClassReference(Class<?> clazz)
{
return TypeUtil.toClassReference(clazz.getName());
}
/**
* Return the Classpath / Classloader reference for the
* provided class file.
*
* <p>
* Convenience method for the code
* </p>
*
* <pre>
* String ref = myClassName.replace('.','/') + ".class";
* </pre>
*
* @param className the class to reference
* @return the classpath reference syntax for the class file
*/
public static String toClassReference(String className)
{
return StringUtil.replace(className, '.', '/').concat(".class");
}
/* ------------------------------------------------------------ */
/** Convert String value to instance.
* @param type The class of the instance, which may be a primitive TYPE field.
@ -561,7 +601,7 @@ public class TypeUtil
}
}
String resourceName = clazz.getName().replace('.', '/') + ".class";
String resourceName = TypeUtil.toClassReference(clazz);
ClassLoader loader = clazz.getClassLoader();
URL url = (loader == null ? ClassLoader.getSystemClassLoader() : loader).getResource(resourceName);
if (url != null)

View File

@ -268,7 +268,134 @@ 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 raw String and convert any specific characters to their URI encoded equivalent.
*
* @param str input raw string
* @param charsToEncode the list of raw characters that need to be encoded (if encountered)
* @return output with specified characters encoded.
*/
@SuppressWarnings("Duplicates")
public static String encodeSpecific(String str, String charsToEncode)
{
if ((str == null) || (str.length() == 0))
return null;
if ((charsToEncode == null) || (charsToEncode.length() == 0))
return str;
char[] find = charsToEncode.toCharArray();
int len = str.length();
StringBuilder ret = new StringBuilder((int)(len * 0.20d));
for (int i = 0; i < len; i++)
{
char c = str.charAt(i);
boolean escaped = false;
for (char f : find)
{
if (c == f)
{
escaped = true;
ret.append('%');
int d = 0xf & ((0xF0 & c) >> 4);
ret.append((char)((d > 9 ? ('A' - 10) : '0') + d));
d = 0xf & c;
ret.append((char)((d > 9 ? ('A' - 10) : '0') + d));
break;
}
}
if (!escaped)
{
ret.append(c);
}
}
return ret.toString();
}
/**
* Decode a raw String and convert any specific URI encoded sequences into characters.
*
* @param str input raw string
* @param charsToDecode the list of raw characters that need to be decoded (if encountered), leaving all other encoded sequences alone.
* @return output with specified characters decoded.
*/
@SuppressWarnings("Duplicates")
public static String decodeSpecific(String str, String charsToDecode)
{
if ((str == null) || (str.length() == 0))
return null;
if ((charsToDecode == null) || (charsToDecode.length() == 0))
return str;
int idx = str.indexOf('%');
if (idx == -1)
{
// no hits
return str;
}
char[] find = charsToDecode.toCharArray();
int len = str.length();
Utf8StringBuilder ret = new Utf8StringBuilder(len);
ret.append(str, 0, idx);
for (int i = idx; i < len; i++)
{
char c = str.charAt(i);
switch (c)
{
case '%':
if ((i + 2) < len)
{
char u = str.charAt(i + 1);
char l = str.charAt(i + 2);
char result = (char)(0xff & (TypeUtil.convertHexDigit(u) * 16 + TypeUtil.convertHexDigit(l)));
boolean decoded = false;
for (char f : find)
{
if (f == result)
{
ret.append(result);
decoded = true;
break;
}
}
if (decoded)
{
i += 2;
}
else
{
ret.append(c);
}
}
else
{
throw new IllegalArgumentException("Bad URI % encoding");
}
break;
default:
ret.append(c);
break;
}
}
return ret.toString();
}
/* ------------------------------------------------------------ */
/** Encode a URI path.
* @param path The path the encode

View File

@ -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,17 @@ 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 = ((Dumpable)o).dumpSelf();
s = StringUtil.replace(s, "\r\n", "|");
s = StringUtil.replace(s, '\n', '|');
}
else
s = String.valueOf(o).replace("\r\n","|").replace("\n","|");
{
s = String.valueOf(o);
s = StringUtil.replace(s, "\r\n", "|");
s = StringUtil.replace(s, '\n', '|');
}
if (o instanceof LifeCycle)
out.append(s).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n");

View File

@ -33,6 +33,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.Uptime;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
@ -102,7 +103,7 @@ public class Log
// NOTE: cannot use jetty-util's StringUtil as that initializes logging itself.
if (osName != null && osName.length() > 0)
{
osName = osName.toLowerCase(Locale.ENGLISH).replace(' ','-');
osName = StringUtil.replace(osName.toLowerCase(Locale.ENGLISH), ' ', '-');
loadProperties("jetty-logging-" + osName + ".properties",__props);
}

View File

@ -29,6 +29,7 @@ import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
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;
@ -320,8 +321,8 @@ public class JarFileResource extends JarResource
String dir=_urlString.substring(_urlString.lastIndexOf("!/")+2);
while(e.hasMoreElements())
{
JarEntry entry = e.nextElement();
String name=entry.getName().replace('\\','/');
JarEntry entry = e.nextElement();
String name = StringUtil.replace(entry.getName(), '\\', '/');
if(!name.startsWith(dir) || name.length()==dir.length())
{
continue;

View File

@ -32,6 +32,7 @@ import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import org.eclipse.jetty.util.IO;
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;
@ -212,7 +213,7 @@ public class JarResource extends URLResource
continue;
}
String dotCheck = entryName.replace('\\', '/');
String dotCheck = StringUtil.replace(entryName, '\\', '/');
dotCheck = URIUtil.canonicalPath(dotCheck);
if (dotCheck == null)
{

View File

@ -18,15 +18,6 @@
package org.eclipse.jetty.util;
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.ADDED;
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.DELETED;
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.MODIFIED;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@ -52,6 +43,15 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.ADDED;
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.DELETED;
import static org.eclipse.jetty.util.PathWatcher.PathWatchEventType.MODIFIED;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Disabled
@ExtendWith(WorkDirExtension.class)
public class PathWatcherTest
@ -111,7 +111,7 @@ public class PathWatcherTest
synchronized (events)
{
Path relativePath = this.baseDir.relativize(event.getPath());
String key = relativePath.toString().replace(File.separatorChar,'/');
String key = StringUtil.replace(relativePath.toString(), File.separatorChar, '/');
List<PathWatchEventType> types = this.events.get(key);
if (types == null)

View File

@ -18,10 +18,13 @@
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;
@ -97,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
@ -133,48 +165,6 @@ public class StringUtilTest
}
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
public void testHasControlCharacter()
{

View File

@ -18,18 +18,22 @@
package org.eclipse.jetty.util;
import java.net.URI;
import java.nio.charset.StandardCharsets;
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.is;
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;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.Test;
/**
* URIUtil Tests.
*/
@ -314,4 +318,109 @@ public class URIUtilTest
assertThat(URIUtil.getJarSource(new URI("jar:file:///tmp/foo.jar")),is(new URI("file:///tmp/foo.jar")));
assertThat(URIUtil.getJarSource(new URI("jar:file:///tmp/foo.jar!/some/path")),is(new URI("file:///tmp/foo.jar")));
}
public static Stream<String[]> encodeSpaces()
{
List<String[]> data = new ArrayList<>();
// [raw, expected]
// null
data.add(new String[]{null, null});
// no spaces
data.add(new String[]{"abc", "abc"});
// match
data.add(new String[]{"a c", "a%20c"});
data.add(new String[]{" ", "%20%20%20"});
data.add(new String[]{"a%20space", "a%20space"});
return data.stream();
}
@ParameterizedTest
@MethodSource(value = "encodeSpaces")
public void testEncodeSpaces(String raw, String expected)
{
assertThat(URIUtil.encodeSpaces(raw), is(expected));
}
public static Stream<String[]> encodeSpecific()
{
List<String[]> data = new ArrayList<>();
// [raw, chars, expected]
// null input
data.add(new String[]{null, null, null});
// null chars
data.add(new String[]{"abc", null, "abc"});
// empty chars
data.add(new String[]{"abc", "", "abc"});
// no matches
data.add(new String[]{"abc", ".;", "abc"});
data.add(new String[]{"xyz", ".;", "xyz"});
data.add(new String[]{":::", ".;", ":::"});
// matches
data.add(new String[]{"a c", " ", "a%20c"});
data.add(new String[]{"name=value", "=", "name%3Dvalue"});
data.add(new String[]{"This has fewer then 10% hits.", ".%", "This has fewer then 10%25 hits%2E"});
// partially encoded already
data.add(new String[]{"a%20name=value%20pair", "=", "a%20name%3Dvalue%20pair"});
data.add(new String[]{"a%20name=value%20pair", "=%", "a%2520name%3Dvalue%2520pair"});
return data.stream();
}
@ParameterizedTest
@MethodSource(value = "encodeSpecific")
public void testEncodeSpecific(String raw, String chars, String expected)
{
assertThat(URIUtil.encodeSpecific(raw, chars), is(expected));
}
public static Stream<String[]> decodeSpecific()
{
List<String[]> data = new ArrayList<>();
// [raw, chars, expected]
// null input
data.add(new String[]{null, null, null});
// null chars
data.add(new String[]{"abc", null, "abc"});
// empty chars
data.add(new String[]{"abc", "", "abc"});
// no matches
data.add(new String[]{"abc", ".;", "abc"});
data.add(new String[]{"xyz", ".;", "xyz"});
data.add(new String[]{":::", ".;", ":::"});
// matches
data.add(new String[]{"a%20c", " ", "a c"});
data.add(new String[]{"name%3Dvalue", "=", "name=value"});
data.add(new String[]{"This has fewer then 10%25 hits%2E", ".%", "This has fewer then 10% hits."});
// partially decode
data.add(new String[]{"a%20name%3Dvalue%20pair", "=", "a%20name=value%20pair"});
data.add(new String[]{"a%2520name%3Dvalue%2520pair", "=%", "a%20name=value%20pair"});
return data.stream();
}
@ParameterizedTest
@MethodSource(value = "decodeSpecific")
public void testDecodeSpecific(String raw, String chars, String expected)
{
assertThat(URIUtil.decodeSpecific(raw, chars), is(expected));
}
}

View File

@ -41,6 +41,7 @@ import java.util.function.Supplier;
import org.eclipse.jetty.util.ArrayTernaryTrie;
import org.eclipse.jetty.util.IncludeExcludeSet;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
@ -726,7 +727,7 @@ public class ClassMatcher extends AbstractSet<String>
name=name.substring(0,name.length()-6);
// Treat path elements as packages for name matching
name=name.replace("/",".");
name = StringUtil.replace(name, '/', '.');
return combine(_patterns, name, _locations, ()->
{

View File

@ -41,7 +41,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jetty.util.ClassVisibilityChecker;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
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,12 +340,10 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
if(LOG.isDebugEnabled())
LOG.debug("addJar - {}", fn);
String fnlc=fn.getName().toLowerCase(Locale.ENGLISH);
// don't check if this is a directory, see Bug 353165
// don't check if this is a directory (prevents use of symlinks), see Bug 353165
if (isFileSupported(fnlc))
{
String jar=fn.toString();
jar=StringUtil.replace(jar, ",", "%2C");
jar=StringUtil.replace(jar, ";", "%3B");
String jar = URIUtil.encodeSpecific(fn.toString(), ",;");
addClassPath(jar);
}
}
@ -610,7 +609,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
// Look in the webapp classloader as a resource, to avoid
// loading a system class.
Class<?> webapp_class = null;
String path = name.replace('.', '/').concat(".class");
String path = TypeUtil.toClassReference(name);
URL webapp_url = findResource(path);
if (webapp_url!=null && (!checkSystemResource || !_context.isSystemResource(name,webapp_url)))
@ -636,7 +635,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
return super.findClass(name);
}
String path = name.replace('.', '/').concat(".class");
String path = TypeUtil.toClassReference(name);
URL url = findResource(path);
if (url==null)
throw new ClassNotFoundException(name);

View File

@ -34,6 +34,7 @@ import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.JAR;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.PathResource;
@ -44,6 +45,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
/**
* Utility to build out exploded directory WebApps, in the /target/tests/ directory, for testing out servers that use javax.websocket endpoints.
* <p>
@ -73,7 +75,7 @@ public class WSServer extends LocalServer implements LocalFuzzer.Provider
public void copyClass(Class<?> clazz) throws Exception
{
ClassLoader cl = Thread.currentThread().getContextClassLoader();
String endpointPath = clazz.getName().replace('.', '/') + ".class";
String endpointPath = TypeUtil.toClassReference(clazz);
URL classUrl = cl.getResource(endpointPath);
assertThat("Class URL for: " + clazz, classUrl, notNullValue());
Path destFile = classesDir.resolve(endpointPath);

View File

@ -19,12 +19,13 @@
package org.eclipse.jetty.test.support;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -34,6 +35,7 @@ import java.util.Properties;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.PathResource;
@ -57,8 +59,8 @@ public class XmlBasedJettyServer
private String _scheme = HttpScheme.HTTP.asString();
/* Popular Directories */
private File baseDir;
private File testResourcesDir;
private Path baseDir;
private Path testResourcesDir;
public XmlBasedJettyServer() throws IOException
{
@ -66,31 +68,28 @@ public class XmlBasedJettyServer
Properties properties = new Properties();
/* Establish Popular Directories */
String baseDirPath = System.getProperty("basedir");
if (baseDirPath == null)
{
baseDirPath = System.getProperty("user.dir",".");
}
baseDir = new File(baseDirPath);
properties.setProperty("test.basedir",baseDir.getAbsolutePath());
baseDir = MavenTestingUtils.getBasePath();
properties.setProperty("test.basedir",baseDir.toString());
testResourcesDir = new File(baseDirPath,"src/test/resources".replace('/',File.separatorChar));
properties.setProperty("test.resourcesdir",testResourcesDir.getAbsolutePath());
testResourcesDir = MavenTestingUtils.getTestResourcesPath();
properties.setProperty("test.resourcesdir",testResourcesDir.toString());
File testDocRoot = new File(testResourcesDir,"docroots");
properties.setProperty("test.docroot.base",testDocRoot.getAbsolutePath());
Path testDocRoot = MavenTestingUtils.getTestResourcePathDir("docroots");
properties.setProperty("test.docroot.base",testDocRoot.toString());
File targetDir = new File(baseDir,"target");
properties.setProperty("test.targetdir",targetDir.getAbsolutePath());
Path targetDir = MavenTestingUtils.getTargetPath();
properties.setProperty("test.targetdir",targetDir.toString());
File webappsDir = new File(targetDir,"webapps");
properties.setProperty("test.webapps",webappsDir.getAbsolutePath());
Path webappsDir = MavenTestingUtils.getTargetPath("webapps");
properties.setProperty("test.webapps",webappsDir.toString());
// Write out configuration for use by ConfigurationManager.
File testConfig = new File(targetDir,"testable-jetty-server-config.properties");
FileOutputStream out = new FileOutputStream(testConfig);
properties.store(out,"Generated by " + XmlBasedJettyServer.class.getName());
Path testConfig = targetDir.resolve("testable-jetty-server-config.properties");
try(OutputStream out = Files.newOutputStream(testConfig))
{
properties.store(out,"Generated by " + XmlBasedJettyServer.class.getName());
}
for (Object key:properties.keySet())
_properties.put(String.valueOf(key),String.valueOf(properties.get(key)));
}
@ -105,9 +104,9 @@ public class XmlBasedJettyServer
_xmlConfigurations.add(new PathResource(xmlConfigFile));
}
public void addXmlConfiguration(String testConfigName) throws MalformedURLException
public void addXmlConfiguration(String testConfigName)
{
addXmlConfiguration(new File(testResourcesDir,testConfigName));
addXmlConfiguration(MavenTestingUtils.getTestResourceFile(testConfigName));
}
public void setProperty(String key, String value)

View File

@ -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("&", "&amp;");
string=string.replace( "<", "&lt;");
string=string.replace( ">", "&gt;");
string = string.replace("&", "&amp;");
string = string.replace( "<", "&lt;");
string = string.replace( ">", "&gt;");
return string;
}

View File

@ -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 = "&#8203;";
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("."," .")+":&nbsp;</th>");
pout.write("<th align=\"right\" valign=\"top\">" + name.replace(".", ZWSP + ".") + ":&nbsp;</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("."," .")+":&nbsp;</th>");
pout.write("<th align=\"right\" valign=\"top\">" + name.replace(".", ZWSP + ".") + ":&nbsp;</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("."," .")+":&nbsp;</th>");
pout.write("<th align=\"right\" valign=\"top\">" + name.replace(".", ZWSP + ".") + ":&nbsp;</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("&","&amp;");
s=s.replaceAll("<","&lt;");
s=s.replaceAll(">","&gt;");
s = s.replace("&","&amp;");
s = s.replace("<","&lt;");
s = s.replace(">","&gt;");
return s;
}
}

View File

@ -24,7 +24,6 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;