Merge branch 'jetty-9.4.x' of github.com:eclipse/jetty.project into jetty-9.4.x

This commit is contained in:
Joakim Erdfelt 2018-06-01 13:32:24 -05:00
commit 7af2eecf6a
6 changed files with 96 additions and 207 deletions

View File

@ -274,7 +274,7 @@ public abstract class HttpDestination extends ContainerLifeCycle implements Dest
{
if (LOG.isDebugEnabled())
LOG.debug("Max queue size {} exceeded by {} for {}", client.getMaxRequestsQueuedPerDestination(), request, this);
request.abort(new RejectedExecutionException("Max requests per destination " + client.getMaxRequestsQueuedPerDestination() + " exceeded for " + this));
request.abort(new RejectedExecutionException("Max requests queued per destination " + client.getMaxRequestsQueuedPerDestination() + " exceeded for " + this));
}
}
else

View File

@ -24,8 +24,8 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.Channel;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.concurrent.Exchanger;
@ -189,114 +189,24 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
// Get the server side endpoint
EndPoint endPoint = exchanger.exchange(null,10,TimeUnit.SECONDS);
if (endPoint instanceof SslConnection.DecryptedEndPoint)
endPoint=endPoint.getConnection().getEndPoint();
endPoint = ((SslConnection.DecryptedEndPoint)endPoint).getSslConnection().getEndPoint();
// read the response
String result=IO.toString(is);
Assert.assertThat("OK",result, Matchers.containsString("200 OK"));
// check client reads EOF
Assert.assertEquals(-1, is.read());
// wait for idle timeout
TimeUnit.MILLISECONDS.sleep(3 * MAX_IDLE_TIME);
// further writes will get broken pipe or similar
try
{
for (int i=0;i<1000;i++)
{
os.write((
"GET / HTTP/1.0\r\n"+
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
"connection: keep-alive\r\n"+
"\r\n").getBytes("utf-8"));
os.flush();
}
Assert.fail("half close should have timed out");
}
catch(SocketException e)
{
// expected
}
// check the server side is closed
Assert.assertFalse(endPoint.isOpen());
}
@Test(timeout=60000)
public void testMaxIdleWithRequest10ClientIgnoresClose() throws Exception
{
final Exchanger<EndPoint> exchanger = new Exchanger<>();
configureServer(new HelloWorldHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException
{
try
{
exchanger.exchange(baseRequest.getHttpChannel().getEndPoint());
}
catch (Exception e)
{
e.printStackTrace();
}
super.handle(target, baseRequest, request, response);
}
});
Socket client=newSocket(_serverURI.getHost(),_serverURI.getPort());
client.setSoTimeout(10000);
Assert.assertFalse(client.isClosed());
OutputStream os=client.getOutputStream();
InputStream is=client.getInputStream();
os.write((
"GET / HTTP/1.0\r\n"+
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
"connection: close\r\n"+
"\r\n").getBytes("utf-8"));
os.flush();
// Get the server side endpoint
EndPoint endPoint = exchanger.exchange(null,10,TimeUnit.SECONDS);
if (endPoint instanceof SslConnection.DecryptedEndPoint)
endPoint=endPoint.getConnection().getEndPoint();
// read the response
String result=IO.toString(is);
Assert.assertThat("OK",result, Matchers.containsString("200 OK"));
Assert.assertThat(result, Matchers.containsString("200 OK"));
// check client reads EOF
Assert.assertEquals(-1, is.read());
Assert.assertTrue(endPoint.isOutputShutdown());
Thread.sleep(2 * MAX_IDLE_TIME);
// further writes will get broken pipe or similar
try
{
long end=TimeUnit.NANOSECONDS.toMillis(System.nanoTime())+MAX_IDLE_TIME+3000;
while (TimeUnit.NANOSECONDS.toMillis(System.nanoTime())<end)
{
os.write("THIS DATA SHOULD NOT BE PARSED!\n\n".getBytes("utf-8"));
os.flush();
Thread.sleep(100);
}
Assert.fail("half close should have timed out");
}
catch(SocketException e)
{
// expected
// Give the SSL onClose time to act
Thread.sleep(100);
}
// wait for idle timeout
TimeUnit.MILLISECONDS.sleep(2 * MAX_IDLE_TIME);
// check the server side is closed
Assert.assertFalse(endPoint.isOpen());
Object transport = endPoint.getTransport();
if (transport instanceof Channel)
Assert.assertFalse(((Channel)transport).isOpen());
}
@Test(timeout=60000)
@ -343,37 +253,24 @@ public abstract class ConnectorTimeoutTest extends HttpServerTestFixture
// Get the server side endpoint
EndPoint endPoint = exchanger.exchange(null,10,TimeUnit.SECONDS);
if (endPoint instanceof SslConnection.DecryptedEndPoint)
endPoint = ((SslConnection.DecryptedEndPoint)endPoint).getSslConnection().getEndPoint();
// read the response
IO.toString(is);
// check client reads EOF
Assert.assertEquals(-1, is.read());
Assert.assertTrue(endPoint.isOutputShutdown());
TimeUnit.MILLISECONDS.sleep(3*MAX_IDLE_TIME);
// The server has shutdown the output, the client does not close,
// the server should idle timeout and close the connection.
TimeUnit.MILLISECONDS.sleep(2 * MAX_IDLE_TIME);
// further writes will get broken pipe or similar
try
{
for (int i=0;i<1000;i++)
{
os.write((
"GET / HTTP/1.0\r\n"+
"host: "+_serverURI.getHost()+":"+_serverURI.getPort()+"\r\n"+
"connection: keep-alive\r\n"+
"\r\n").getBytes("utf-8"));
os.flush();
}
Assert.fail("half close should have timed out");
}
catch(SocketException e)
{
// expected
}
// check the server side is closed
Assert.assertFalse(endPoint.isOpen());
Object transport = endPoint.getTransport();
if (transport instanceof Channel)
Assert.assertFalse(((Channel)transport).isOpen());
}
@Test(timeout=60000)

View File

@ -18,16 +18,6 @@
package org.eclipse.jetty.server;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
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 java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
@ -64,9 +54,16 @@ import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
*
*/
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
@RunWith(AdvancedRunner.class)
public abstract class HttpServerTestBase extends HttpServerTestFixture
{
@ -214,19 +211,23 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
{
configureServer(new HelloWorldHandler());
int maxHeaderSize = 1000;
_httpConfiguration.setRequestHeaderSize(maxHeaderSize);
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
StacklessLogging stackless = new StacklessLogging(HttpConnection.class))
{
((AbstractLogger)Log.getLogger(HttpConnection.class)).info("expect URI is too large, then ISE extra data ...");
Log.getLogger(HttpConnection.class).info("expect URI is too large");
OutputStream os = client.getOutputStream();
byte[] buffer = new byte[64 * 1024];
// Take into account the initial bytes for the HTTP method.
byte[] buffer = new byte[5 + maxHeaderSize];
buffer[0]='G';
buffer[1]='E';
buffer[2]='T';
buffer[3]=' ';
buffer[4]='/';
Arrays.fill(buffer, 5,buffer.length-1,(byte)'A');
Arrays.fill(buffer, 5, buffer.length, (byte)'A');
os.write(buffer);
os.flush();

View File

@ -27,14 +27,11 @@ import java.net.Socket;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.handler.HotSwapHandler;
import org.eclipse.jetty.toolchain.test.PropertyFlag;
import org.eclipse.jetty.util.IO;
@ -269,12 +266,4 @@ public class HttpServerTestFixture
}
public final static HostnameVerifier __hostnameverifier = new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
};
}

View File

@ -18,13 +18,6 @@
package org.eclipse.jetty.server.ssl;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -34,7 +27,6 @@ import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -58,31 +50,83 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.OS;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.Scheduler;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
/**
* HttpServer Tester.
*/
public class SelectChannelServerSslTest extends HttpServerTestBase
{
static SSLContext __sslContext;
private SSLContext _sslContext;
public SelectChannelServerSslTest()
{
_scheme="https";
}
@Before
public void init() throws Exception
{
String keystorePath = MavenTestingUtils.getTestResourcePath("keystore").toString();
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(keystorePath);
sslContextFactory.setKeyStorePassword("storepwd");
sslContextFactory.setKeyManagerPassword("keypwd");
sslContextFactory.setTrustStorePath(keystorePath);
sslContextFactory.setTrustStorePassword("storepwd");
ByteBufferPool pool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
HttpConnectionFactory httpConnectionFactory = new HttpConnectionFactory();
ServerConnector connector = new ServerConnector(_server, null, null, pool, 1, 1, AbstractConnectionFactory.getFactories(sslContextFactory, httpConnectionFactory));
SecureRequestCustomizer secureRequestCustomer = new SecureRequestCustomizer();
secureRequestCustomer.setSslSessionAttribute("SSL_SESSION");
httpConnectionFactory.getHttpConfiguration().addCustomizer(secureRequestCustomer);
startServer(connector);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
try (InputStream stream = sslContextFactory.getKeyStoreResource().getInputStream())
{
keystore.load(stream, "storepwd".toCharArray());
}
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keystore);
_sslContext = SSLContext.getInstance("TLS");
_sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
try
{
// Client configuration in case we use HttpsURLConnection.
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, SslContextFactory.TRUST_ALL_CERTS, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
@Override
protected Socket newSocket(String host, int port) throws Exception
{
Socket socket = __sslContext.getSocketFactory().createSocket(host,port);
Socket socket = _sslContext.getSocketFactory().createSocket(host,port);
socket.setSoTimeout(10000);
socket.setTcpNoDelay(true);
socket.setSoLinger(false,0);
@ -94,19 +138,19 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
{
// Don't run on Windows (buggy JVM)
Assume.assumeTrue(!OS.IS_WINDOWS);
try
{
super.testFullMethod();
}
catch (SocketException e)
{
// TODO This needs to be investigated #2244
// TODO This needs to be investigated #2244
Log.getLogger(SslConnection.class).warn("Close overtook 400 response");
}
catch (SSLException e)
{
// TODO This needs to be investigated #2244
// TODO This needs to be investigated #2244
if (e.getCause() instanceof SocketException)
Log.getLogger(SslConnection.class).warn("Close overtook 400 response");
else
@ -135,49 +179,6 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
super.testFullHeader();
}
@Before
public void init() throws Exception
{
String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(keystorePath);
sslContextFactory.setKeyStorePassword("storepwd");
sslContextFactory.setKeyManagerPassword("keypwd");
sslContextFactory.setTrustStorePath(keystorePath);
sslContextFactory.setTrustStorePassword("storepwd");
ByteBufferPool pool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
HttpConnectionFactory httpConnectionFactory = new HttpConnectionFactory();
ServerConnector connector = new ServerConnector(_server,(Executor)null,(Scheduler)null,pool, 1, 1, AbstractConnectionFactory.getFactories(sslContextFactory,httpConnectionFactory));
SecureRequestCustomizer secureRequestCustomer = new SecureRequestCustomizer();
secureRequestCustomer.setSslSessionAttribute("SSL_SESSION");
httpConnectionFactory.getHttpConfiguration().addCustomizer(secureRequestCustomer);
startServer(connector);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
try (InputStream stream = sslContextFactory.getKeyStoreResource().getInputStream())
{
keystore.load(stream, "storepwd".toCharArray());
}
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keystore);
__sslContext = SSLContext.getInstance("TLS");
__sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
try
{
HttpsURLConnection.setDefaultHostnameVerifier(__hostnameverifier);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, SslContextFactory.TRUST_ALL_CERTS, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
@Override
public void testBlockingWhileReadingRequestContent() throws Exception
{

View File

@ -496,7 +496,8 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP
@ManagedAttribute("number of busy threads in the pool")
public int getBusyThreads()
{
return getThreads() - getIdleThreads();
int reserved = _tryExecutor instanceof ReservedThreadExecutor ? ((ReservedThreadExecutor)_tryExecutor).getAvailable() : 0;
return getThreads() - getIdleThreads() - reserved;
}
/**