Merge branch 'master' into bugs/469860

Conflicts:
	jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java
	jetty-start/src/test/resources/assert-home-with-http2.txt
This commit is contained in:
Joakim Erdfelt 2015-06-11 06:57:16 -07:00
commit b670b9e47d
8 changed files with 111 additions and 43 deletions

View File

@ -23,6 +23,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
/** /**
* Simple Jetty FileServer. * Simple Jetty FileServer.
@ -47,9 +48,11 @@ public class FileServer
resource_handler.setResourceBase("."); resource_handler.setResourceBase(".");
// Add the ResourceHandler to the server. // Add the ResourceHandler to the server.
GzipHandler gzip = new GzipHandler();
server.setHandler(gzip);
HandlerList handlers = new HandlerList(); HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() }); handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
server.setHandler(handlers); gzip.setHandler(handlers);
// Start things up! By using the server.join() the server thread will join with the current thread. // Start things up! By using the server.join() the server thread will join with the current thread.
// See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details. // See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details.

View File

@ -43,7 +43,7 @@ public class ManyConnectors
// to get access to a keystore that we use in many unit tests and should // to get access to a keystore that we use in many unit tests and should
// probably be a direct path to your own keystore. // probably be a direct path to your own keystore.
String jettyDistKeystore = "../../jetty-distribution/target/distribution/etc/keystore"; String jettyDistKeystore = "../../jetty-distribution/target/distribution/demo-base/etc/keystore";
String keystorePath = System.getProperty( String keystorePath = System.getProperty(
"example.keystore", jettyDistKeystore); "example.keystore", jettyDistKeystore);
File keystoreFile = new File(keystorePath); File keystoreFile = new File(keystorePath);

View File

@ -26,6 +26,7 @@ import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.Destination; import org.eclipse.jetty.client.api.Destination;
@ -36,7 +37,6 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker;
import org.eclipse.jetty.util.thread.Sweeper; import org.eclipse.jetty.util.thread.Sweeper;
public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
@ -44,7 +44,7 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
protected static final Logger LOG = Log.getLogger(ConnectionPool.class); protected static final Logger LOG = Log.getLogger(ConnectionPool.class);
private final AtomicInteger connectionCount = new AtomicInteger(); private final AtomicInteger connectionCount = new AtomicInteger();
private final Locker locker = new Locker(); private final ReentrantLock lock = new ReentrantLock();
private final Destination destination; private final Destination destination;
private final int maxConnections; private final int maxConnections;
private final Callback requester; private final Callback requester;
@ -137,11 +137,18 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
protected void idleCreated(Connection connection) protected void idleCreated(Connection connection)
{ {
boolean idle; boolean idle;
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
// Use "cold" new connections as last. // Use "cold" new connections as last.
idle = idleConnections.offerLast(connection); idle = idleConnections.offerLast(connection);
} }
finally
{
lock.unlock();
}
idle(connection, idle); idle(connection, idle);
} }
@ -149,13 +156,19 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
{ {
boolean acquired; boolean acquired;
Connection connection; Connection connection;
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
connection = idleConnections.pollFirst(); connection = idleConnections.pollFirst();
if (connection == null) if (connection == null)
return null; return null;
acquired = activeConnections.offer(connection); acquired = activeConnections.offer(connection);
} }
finally
{
lock.unlock();
}
if (acquired) if (acquired)
{ {
@ -180,13 +193,20 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
public boolean release(Connection connection) public boolean release(Connection connection)
{ {
boolean idle; boolean idle;
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
if (!activeConnections.remove(connection)) if (!activeConnections.remove(connection))
return false; return false;
// Make sure we use "hot" connections first. // Make sure we use "hot" connections first.
idle = idleConnections.offerFirst(connection); idle = idleConnections.offerFirst(connection);
} }
finally
{
lock.unlock();
}
released(connection); released(connection);
return idle(connection, idle); return idle(connection, idle);
} }
@ -216,11 +236,18 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
{ {
boolean activeRemoved; boolean activeRemoved;
boolean idleRemoved; boolean idleRemoved;
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
activeRemoved = activeConnections.remove(connection); activeRemoved = activeConnections.remove(connection);
idleRemoved = idleConnections.remove(connection); idleRemoved = idleConnections.remove(connection);
} }
finally
{
lock.unlock();
}
if (activeRemoved) if (activeRemoved)
released(connection); released(connection);
boolean removed = activeRemoved || idleRemoved; boolean removed = activeRemoved || idleRemoved;
@ -235,18 +262,30 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
public boolean isActive(Connection connection) public boolean isActive(Connection connection)
{ {
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
return activeConnections.contains(connection); return activeConnections.contains(connection);
} }
finally
{
lock.unlock();
}
} }
public boolean isIdle(Connection connection) public boolean isIdle(Connection connection)
{ {
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
return idleConnections.contains(connection); return idleConnections.contains(connection);
} }
finally
{
lock.unlock();
}
} }
public boolean isEmpty() public boolean isEmpty()
@ -258,13 +297,20 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
{ {
List<Connection> idles = new ArrayList<>(); List<Connection> idles = new ArrayList<>();
List<Connection> actives = new ArrayList<>(); List<Connection> actives = new ArrayList<>();
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
idles.addAll(idleConnections); idles.addAll(idleConnections);
idleConnections.clear(); idleConnections.clear();
actives.addAll(activeConnections); actives.addAll(activeConnections);
activeConnections.clear(); activeConnections.clear();
} }
finally
{
lock.unlock();
}
connectionCount.set(0); connectionCount.set(0);
for (Connection connection : idles) for (Connection connection : idles)
@ -286,11 +332,18 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
{ {
List<Connection> actives = new ArrayList<>(); List<Connection> actives = new ArrayList<>();
List<Connection> idles = new ArrayList<>(); List<Connection> idles = new ArrayList<>();
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
actives.addAll(activeConnections); actives.addAll(activeConnections);
idles.addAll(idleConnections); idles.addAll(idleConnections);
} }
finally
{
lock.unlock();
}
ContainerLifeCycle.dumpObject(out, this); ContainerLifeCycle.dumpObject(out, this);
ContainerLifeCycle.dump(out, indent, actives, idles); ContainerLifeCycle.dump(out, indent, actives, idles);
} }
@ -299,7 +352,9 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
public boolean sweep() public boolean sweep()
{ {
List<Sweeper.Sweepable> toSweep = new ArrayList<>(); List<Sweeper.Sweepable> toSweep = new ArrayList<>();
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
for (Connection connection : getActiveConnections()) for (Connection connection : getActiveConnections())
{ {
@ -307,6 +362,10 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
toSweep.add(((Sweeper.Sweepable)connection)); toSweep.add(((Sweeper.Sweepable)connection));
} }
} }
finally
{
lock.unlock();
}
for (Sweeper.Sweepable candidate : toSweep) for (Sweeper.Sweepable candidate : toSweep)
{ {
@ -330,11 +389,18 @@ public class ConnectionPool implements Closeable, Dumpable, Sweeper.Sweepable
{ {
int activeSize; int activeSize;
int idleSize; int idleSize;
try (Locker.Lock lock = this.locker.lock()) final ReentrantLock lock = this.lock;
lock.lock();
try
{ {
activeSize = activeConnections.size(); activeSize = activeConnections.size();
idleSize = idleConnections.size(); idleSize = idleConnections.size();
} }
finally
{
lock.unlock();
}
return String.format("%s[c=%d/%d,a=%d,i=%d]", return String.format("%s[c=%d/%d,a=%d,i=%d]",
getClass().getSimpleName(), getClass().getSimpleName(),
connectionCount.get(), connectionCount.get(),

View File

@ -21,13 +21,11 @@ package org.eclipse.jetty.client;
import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker;
public abstract class HttpChannel public abstract class HttpChannel
{ {
protected static final Logger LOG = Log.getLogger(HttpChannel.class); protected static final Logger LOG = Log.getLogger(HttpChannel.class);
private final Locker _locker = new Locker();
private final HttpDestination _destination; private final HttpDestination _destination;
private HttpExchange _exchange; private HttpExchange _exchange;
@ -53,7 +51,7 @@ public abstract class HttpChannel
{ {
boolean result = false; boolean result = false;
boolean abort = true; boolean abort = true;
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
if (_exchange == null) if (_exchange == null)
{ {
@ -76,7 +74,7 @@ public abstract class HttpChannel
public boolean disassociate(HttpExchange exchange) public boolean disassociate(HttpExchange exchange)
{ {
boolean result = false; boolean result = false;
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
HttpExchange existing = _exchange; HttpExchange existing = _exchange;
_exchange = null; _exchange = null;
@ -86,6 +84,7 @@ public abstract class HttpChannel
result = true; result = true;
} }
} }
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("{} disassociated {} from {}", exchange, result, this); LOG.debug("{} disassociated {} from {}", exchange, result, this);
return result; return result;
@ -93,7 +92,7 @@ public abstract class HttpChannel
public HttpExchange getHttpExchange() public HttpExchange getHttpExchange()
{ {
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
return _exchange; return _exchange;
} }

View File

@ -24,7 +24,6 @@ import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker;
public class HttpExchange public class HttpExchange
{ {
@ -34,7 +33,6 @@ public class HttpExchange
private final HttpRequest request; private final HttpRequest request;
private final List<Response.ResponseListener> listeners; private final List<Response.ResponseListener> listeners;
private final HttpResponse response; private final HttpResponse response;
private final Locker _locker = new Locker();
private State requestState = State.PENDING; private State requestState = State.PENDING;
private State responseState = State.PENDING; private State responseState = State.PENDING;
private HttpChannel _channel; private HttpChannel _channel;
@ -64,7 +62,7 @@ public class HttpExchange
public Throwable getRequestFailure() public Throwable getRequestFailure()
{ {
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
return requestFailure; return requestFailure;
} }
@ -82,7 +80,7 @@ public class HttpExchange
public Throwable getResponseFailure() public Throwable getResponseFailure()
{ {
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
return responseFailure; return responseFailure;
} }
@ -99,7 +97,7 @@ public class HttpExchange
{ {
boolean result = false; boolean result = false;
boolean abort = false; boolean abort = false;
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
// Only associate if the exchange state is initial, // Only associate if the exchange state is initial,
// as the exchange could be already failed. // as the exchange could be already failed.
@ -123,7 +121,7 @@ public class HttpExchange
void disassociate(HttpChannel channel) void disassociate(HttpChannel channel)
{ {
boolean abort = false; boolean abort = false;
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
if (_channel != channel || requestState != State.TERMINATED || responseState != State.TERMINATED) if (_channel != channel || requestState != State.TERMINATED || responseState != State.TERMINATED)
abort = true; abort = true;
@ -136,7 +134,7 @@ public class HttpExchange
private HttpChannel getHttpChannel() private HttpChannel getHttpChannel()
{ {
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
return _channel; return _channel;
} }
@ -144,7 +142,7 @@ public class HttpExchange
public boolean requestComplete(Throwable failure) public boolean requestComplete(Throwable failure)
{ {
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
return completeRequest(failure); return completeRequest(failure);
} }
@ -163,7 +161,7 @@ public class HttpExchange
public boolean responseComplete(Throwable failure) public boolean responseComplete(Throwable failure)
{ {
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
return completeResponse(failure); return completeResponse(failure);
} }
@ -183,7 +181,7 @@ public class HttpExchange
public Result terminateRequest() public Result terminateRequest()
{ {
Result result = null; Result result = null;
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
if (requestState == State.COMPLETED) if (requestState == State.COMPLETED)
requestState = State.TERMINATED; requestState = State.TERMINATED;
@ -200,7 +198,7 @@ public class HttpExchange
public Result terminateResponse() public Result terminateResponse()
{ {
Result result = null; Result result = null;
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
if (responseState == State.COMPLETED) if (responseState == State.COMPLETED)
responseState = State.TERMINATED; responseState = State.TERMINATED;
@ -220,7 +218,7 @@ public class HttpExchange
// This will avoid that this exchange can be associated to a channel. // This will avoid that this exchange can be associated to a channel.
boolean abortRequest; boolean abortRequest;
boolean abortResponse; boolean abortResponse;
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
abortRequest = completeRequest(failure); abortRequest = completeRequest(failure);
abortResponse = completeResponse(failure); abortResponse = completeResponse(failure);
@ -273,7 +271,7 @@ public class HttpExchange
public void resetResponse() public void resetResponse()
{ {
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
responseState = State.PENDING; responseState = State.PENDING;
responseFailure = null; responseFailure = null;
@ -290,7 +288,7 @@ public class HttpExchange
@Override @Override
public String toString() public String toString()
{ {
try (Locker.Lock lock = _locker.lock()) synchronized (this)
{ {
return String.format("%s@%x req=%s/%s@%h res=%s/%s@%h", return String.format("%s@%x req=%s/%s@%h res=%s/%s@%h",
HttpExchange.class.getSimpleName(), HttpExchange.class.getSimpleName(),

View File

@ -586,6 +586,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
public void sendContent(ByteBuffer content) throws IOException public void sendContent(ByteBuffer content) throws IOException
{ {
write(content, true); write(content, true);
closed();
} }
/** /**

View File

@ -287,6 +287,9 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
@Override @Override
protected Action process() throws Exception protected Action process() throws Exception
{ {
if (_deflater==null)
return Action.SUCCEEDED;
if (_deflater.needsInput()) if (_deflater.needsInput())
{ {
if (BufferUtil.isEmpty(_content)) if (BufferUtil.isEmpty(_content))

View File

@ -1552,7 +1552,7 @@ public class SslContextFactory extends AbstractLifeCycle
{ {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("Customize {}",sslEngine); LOG.debug("Customize {}",sslEngine);
SSLParameters sslParams = sslEngine.getSSLParameters(); SSLParameters sslParams = sslEngine.getSSLParameters();
sslParams.setEndpointIdentificationAlgorithm(_endpointIdentificationAlgorithm); sslParams.setEndpointIdentificationAlgorithm(_endpointIdentificationAlgorithm);
sslParams.setUseCipherSuitesOrder(_useCipherSuitesOrder); sslParams.setUseCipherSuitesOrder(_useCipherSuitesOrder);
@ -1562,17 +1562,15 @@ public class SslContextFactory extends AbstractLifeCycle
LOG.debug("Enable SNI matching {}",sslEngine); LOG.debug("Enable SNI matching {}",sslEngine);
sslParams.setSNIMatchers(Collections.singletonList((SNIMatcher)new AliasSNIMatcher())); sslParams.setSNIMatchers(Collections.singletonList((SNIMatcher)new AliasSNIMatcher()));
} }
if (getWantClientAuth())
sslEngine.setWantClientAuth(getWantClientAuth());
if (getNeedClientAuth())
sslEngine.setNeedClientAuth(getNeedClientAuth());
sslParams.setCipherSuites(_selectedCipherSuites); sslParams.setCipherSuites(_selectedCipherSuites);
sslEngine.setEnabledCipherSuites(_selectedCipherSuites); sslParams.setProtocols(_selectedProtocols);
sslEngine.setEnabledProtocols(_selectedProtocols);
if (getWantClientAuth())
sslParams.setWantClientAuth(true);
if (getNeedClientAuth())
sslParams.setNeedClientAuth(true);
sslEngine.setSSLParameters(sslParams); sslEngine.setSSLParameters(sslParams);
} }
public static X509Certificate[] getCertChain(SSLSession sslSession) public static X509Certificate[] getCertChain(SSLSession sslSession)