Merge branch 'jetty-9.4.x' of github.com:eclipse/jetty.project into jetty-9.4.x
This commit is contained in:
commit
7af2eecf6a
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue