Merge remote-tracking branch 'origin/jetty-9.4.x'

This commit is contained in:
Jan Bartel 2017-09-27 12:19:54 +10:00
commit d81b835ad0
10 changed files with 129 additions and 71 deletions

View File

@ -61,11 +61,11 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump
private long _selectorIndex;
private int _reservedThreads = -1;
public static int defaultSchedulers(Executor executor)
private static int defaultSelectors(Executor executor)
{
if (executor instanceof ThreadPool)
if (executor instanceof ThreadPool.SizedThreadPool)
{
int threads = ((ThreadPool)executor).getThreads();
int threads = ((ThreadPool.SizedThreadPool)executor).getMaxThreads();
int cpus = Runtime.getRuntime().availableProcessors();
return Math.max(1,Math.min(cpus/2,threads/16));
}
@ -87,7 +87,7 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump
protected SelectorManager(Executor executor, Scheduler scheduler, int selectors)
{
if (selectors <= 0)
selectors = defaultSchedulers(executor);
selectors = defaultSelectors(executor);
this.executor = executor;
this.scheduler = scheduler;
_selectors = new ManagedSelector[selectors];

View File

@ -357,7 +357,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
StacklessLogging stackless = new StacklessLogging(HttpConnection.class))
{
Log.getLogger(HttpConnection.class).info("expect header is too large, then ISE extra data ...");
Log.getLogger(HttpConnection.class).info("expect header is too large ...");
OutputStream os = client.getOutputStream();
byte[] buffer = new byte[64 * 1024];
@ -379,9 +379,16 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
buffer[15]='H';
buffer[16]=':';
Arrays.fill(buffer,17,buffer.length-1,(byte)'A');
os.write(buffer);
os.flush();
// write the request.
try
{
os.write(buffer);
os.flush();
}
catch(Exception e)
{
// Ignore exceptions during writing, so long as we can read response below
}
// Read the response.
try
@ -391,7 +398,8 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
}
catch(Exception e)
{
// TODO evaluate why we sometimes get an early close on this test
Log.getLogger(HttpServerTestBase.class).warn("TODO Early close???");
// TODO #1832 evaluate why we sometimes get an early close on this test
}
}
}

View File

@ -40,6 +40,7 @@ import java.util.regex.Pattern;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManagerFactory;
import javax.servlet.ServletException;
@ -118,14 +119,7 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
@Override
public void testFullHeader() throws Exception
{
try
{
super.testFullHeader();
}
catch (SocketException e)
{
Log.getLogger(SslConnection.class).warn("Close overtook 400 response");
}
super.testFullHeader();
}
@Before
@ -167,7 +161,6 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
}
catch(Exception e)
{
e.printStackTrace();
throw new RuntimeException(e);
}
}

View File

@ -400,9 +400,11 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
_config=new Config();
if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
_servlet = new SingleThreadedWrapper();
synchronized (this)
{
if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
_servlet = new SingleThreadedWrapper();
}
}
@ -485,18 +487,38 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
public synchronized Servlet getServlet()
throws ServletException
{
// Handle previous unavailability
if (_unavailable!=0)
{
if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
throw _unavailableEx;
_unavailable=0;
_unavailableEx=null;
}
Servlet servlet=_servlet;
if (servlet!=null && _unavailable==0)
return servlet;
if (_servlet==null)
initServlet();
return _servlet;
synchronized(this)
{
// Handle previous unavailability
if (_unavailable!=0)
{
if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
throw _unavailableEx;
_unavailable=0;
_unavailableEx=null;
}
servlet=_servlet;
if (servlet!=null)
return servlet;
if (isRunning())
{
if (_class == null)
throw new UnavailableException("Servlet Not Initialized");
if (_unavailable != 0 || !_initOnStartup)
initServlet();
servlet=_servlet;
if (servlet == null)
throw new UnavailableException("Could not instantiate " + _class);
}
return servlet;
}
}
/* ------------------------------------------------------------ */
@ -505,7 +527,13 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
*/
public Servlet getServletInstance()
{
return _servlet;
Servlet servlet=_servlet;
if (servlet!=null)
return servlet;
synchronized(this)
{
return _servlet;
}
}
/* ------------------------------------------------------------ */
@ -604,7 +632,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
}
/* ------------------------------------------------------------ */
private void initServlet()
private synchronized void initServlet()
throws ServletException
{
Object old_run_as = null;
@ -767,36 +795,17 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
protected void prepare (Request baseRequest, ServletRequest request, ServletResponse response)
throws ServletException, UnavailableException
{
ensureInstance();
getServlet();
MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
if (mpce != null)
baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
}
@Deprecated
public Servlet ensureInstance()
throws ServletException, UnavailableException
throws ServletException, UnavailableException
{
if (!isStarted())
throw new UnavailableException("Servlet not initialized", -1);
Servlet servlet=_servlet;
if (servlet!=null && _unavailable==0)
return servlet;
synchronized(this)
{
servlet=_servlet;
if (servlet!=null)
return servlet;
if (_class == null)
throw new UnavailableException("Servlet Not Initialized");
if (_unavailable != 0 || (!_initOnStartup && servlet == null))
servlet = getServlet();
if (servlet == null)
throw new UnavailableException("Could not instantiate " + _class);
return servlet;
}
return getServlet();
}
/* ------------------------------------------------------------ */
@ -820,7 +829,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
if (_class==null)
throw new UnavailableException("Servlet Not Initialized");
Servlet servlet = ensureInstance();
Servlet servlet = getServlet();
// Service the request
Object old_run_as = null;
@ -865,26 +874,23 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
/* ------------------------------------------------------------ */
private boolean isJspServlet ()
protected boolean isJspServlet ()
{
if (_servlet == null)
return false;
Servlet servlet = getServletInstance();
Class<?> c = servlet==null?_class:servlet.getClass();
Class<?> c = _servlet.getClass();
boolean result = false;
while (c != null && !result)
while (c != null)
{
result = isJspServlet(c.getName());
if (isJspServlet(c.getName()))
return true;
c = c.getSuperclass();
}
return result;
return false;
}
/* ------------------------------------------------------------ */
private boolean isJspServlet (String classname)
protected boolean isJspServlet (String classname)
{
if (classname == null)
return false;

View File

@ -447,8 +447,8 @@ public abstract class Resource implements ResourceFactory, Closeable
/* ------------------------------------------------------------ */
/**
* list of resource names contained in the given resource.
*
* @return a list of resource names contained in the given resource.
* Ordering is unspecified, so callers may wish to sort the return value to ensure deterministic behavior.
* @return a list of resource names contained in the given resource, or null.
* Note: The resource names are not URL encoded.
*/
public abstract String[] list();

View File

@ -29,6 +29,7 @@ import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
@ -328,6 +329,10 @@ public class WebAppClassLoader extends URLClassLoader
if (lib.exists() && lib.isDirectory())
{
String[] files=lib.list();
if (files != null)
{
Arrays.sort(files);
}
for (int f=0;files!=null && f<files.length;f++)
{
try

View File

@ -22,10 +22,13 @@ import static org.eclipse.jetty.toolchain.test.ExtraMatchers.ordered;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeThat;
import java.io.InputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.net.URI;
@ -34,10 +37,12 @@ import java.nio.file.Path;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
import org.junit.Before;
@ -358,4 +363,26 @@ public class WebAppClassLoaderTest
}
@Test
public void ordering() throws Exception
{
// The existence of a URLStreamHandler changes the behavior
assumeThat("URLStreamHandler changes behavior, skip test", URLStreamHandlerUtil.getFactory(), nullValue());
Enumeration<URL> resources = _loader.getResources("org/acme/clashing.txt");
assertTrue(resources.hasMoreElements());
URL resource = resources.nextElement();
try (InputStream data = resource.openStream())
{
assertEquals("correct contents of " + resource, "alpha", IO.toString(data));
}
assertTrue(resources.hasMoreElements());
resource = resources.nextElement();
try (InputStream data = resource.openStream())
{
assertEquals("correct contents of " + resource, "omega", IO.toString(data));
}
assertFalse(resources.hasMoreElements());
}
}

View File

@ -23,9 +23,11 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -46,6 +48,8 @@ import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.HotSwapHandler;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceCollection;
import org.hamcrest.Matchers;
@ -369,4 +373,19 @@ public class WebAppContextTest
server.stop();
}
@Test
public void ordering() throws Exception
{
Path testWebappDir = MavenTestingUtils.getProjectDirPath("src/test/webapp");
Resource webapp = new PathResource(testWebappDir);
WebAppContext context = new WebAppContext();
context.setBaseResource(webapp);
context.setContextPath("/test");
context.setServer(new Server());
new MetaInfConfiguration().preConfigure(context);
assertEquals(Arrays.asList("acme.jar", "alpha.jar", "omega.jar"),
context.getMetaData().getWebInfJars().stream().map(r -> r.getURI().toString().replaceFirst(".+/", "")).collect(Collectors.toList()));
}
}

Binary file not shown.

Binary file not shown.