Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java11
-rw-r--r--examples/pom.xml1
-rw-r--r--jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn.mod6
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java7
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java99
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java91
-rw-r--r--jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java5
-rw-r--r--jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java7
-rw-r--r--jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java1
-rw-r--r--jetty-server/src/main/config/etc/jetty-http.xml4
-rw-r--r--jetty-server/src/main/config/etc/jetty-https.xml44
-rw-r--r--jetty-server/src/main/config/modules/http.mod17
-rw-r--r--jetty-server/src/main/config/modules/ssl.mod21
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java41
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java20
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java20
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java43
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java24
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java2
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java6
-rw-r--r--jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod6
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java6
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/Main.java54
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java19
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java71
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java3
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java108
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java8
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java88
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java11
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java2
-rw-r--r--jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java2
-rw-r--r--jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java10
-rw-r--r--jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/BlockingWriteCallback.java40
-rw-r--r--tests/pom.xml1
-rw-r--r--tests/test-quickstart/pom.xml (renamed from examples/quickstart/pom.xml)23
-rw-r--r--tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java (renamed from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java)0
-rw-r--r--tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java (renamed from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java)0
-rw-r--r--tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java (renamed from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java)0
-rw-r--r--tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java (renamed from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java)0
-rw-r--r--tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java (renamed from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java)0
-rw-r--r--tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java (renamed from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java)0
-rw-r--r--tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java (renamed from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java)0
-rw-r--r--tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java (renamed from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java)0
-rw-r--r--tests/test-quickstart/src/test/resources/realm.properties (renamed from examples/quickstart/src/test/resources/realm.properties)0
-rw-r--r--tests/test-quickstart/src/test/resources/test-jndi.xml (renamed from examples/quickstart/src/test/resources/test-jndi.xml)0
-rw-r--r--tests/test-quickstart/src/test/resources/test-spec.xml (renamed from examples/quickstart/src/test/resources/test-spec.xml)0
-rw-r--r--tests/test-quickstart/src/test/resources/test.xml (renamed from examples/quickstart/src/test/resources/test.xml)2
-rw-r--r--tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini6
50 files changed, 689 insertions, 243 deletions
diff --git a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java
index 4cd7993211..9c66c8d699 100644
--- a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java
+++ b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java
@@ -23,14 +23,14 @@ import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Set;
import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
import org.apache.jasper.servlet.JasperInitializer;
import org.apache.jasper.servlet.TldPreScanned;
import org.apache.jasper.servlet.TldScanner;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
import org.xml.sax.SAXException;
/**
@@ -39,6 +39,7 @@ import org.xml.sax.SAXException;
*/
public class JettyJasperInitializer extends JasperInitializer
{
+ private static final Logger LOG = Log.getLogger(JettyJasperInitializer.class);
/**
* NullTldScanner
@@ -99,14 +100,18 @@ public class JettyJasperInitializer extends JasperInitializer
String tmp = context.getInitParameter("org.eclipse.jetty.jsp.precompiled");
if (tmp!=null && !tmp.equals("") && Boolean.valueOf(tmp))
{
+ if (LOG.isDebugEnabled()) LOG.debug("Jsp precompilation detected");
return new NullTldScanner(context, namespaceAware, validate, blockExternal);
}
Collection<URL> tldUrls = (Collection<URL>)context.getAttribute("org.eclipse.jetty.tlds");
- if (tldUrls != null && !tldUrls.isEmpty())
+ if (tldUrls != null)
{
+ if (LOG.isDebugEnabled()) LOG.debug("Tld pre-scan detected");
return new TldPreScanned(context,namespaceAware,validate,blockExternal,tldUrls);
}
+
+ if (LOG.isDebugEnabled()) LOG.debug("Defaulting to jasper tld scanning");
return super.newTldScanner(context, namespaceAware, validate, blockExternal);
}
diff --git a/examples/pom.xml b/examples/pom.xml
index f0add209d8..b803d82f21 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -47,6 +47,5 @@
-->
<module>async-rest</module>
<module>embedded</module>
- <module>quickstart</module>
</modules>
</project>
diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn.mod
index 0e399f05cb..9c6af517d1 100644
--- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn.mod
+++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn.mod
@@ -34,3 +34,9 @@ etc/protonego-alpn.xml
lib/
lib/alpn/
+[license]
+ALPN is a hosted at github under the GPL v2 with ClassPath Exception.
+ALPM replaces/modified OpenJDK classes in the java.sun.security.ssl package.
+http://github.com/jetty-project/jetty-alpn
+http://openjdk.java.net/legal/gplv2+ce.html
+
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java
index af9d0d2508..ee698bb159 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java
@@ -88,11 +88,14 @@ public abstract class AbstractHttpClientTransport extends ContainerLifeCycle imp
channel.bind(bindAddress);
configure(client, channel);
channel.configureBlocking(false);
- channel.connect(address);
context.put(SslClientConnectionFactory.SSL_PEER_HOST_CONTEXT_KEY, destination.getHost());
context.put(SslClientConnectionFactory.SSL_PEER_PORT_CONTEXT_KEY, destination.getPort());
- selectorManager.connect(channel, context);
+
+ if (channel.connect(address))
+ selectorManager.accept(channel, context);
+ else
+ selectorManager.connect(channel, context);
}
// Must catch all exceptions, since some like
// UnresolvedAddressException are not IOExceptions.
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
index f54d02b973..f1932eb972 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
@@ -18,6 +18,11 @@
package org.eclipse.jetty.http;
+import static org.eclipse.jetty.http.HttpTokens.CARRIAGE_RETURN;
+import static org.eclipse.jetty.http.HttpTokens.LINE_FEED;
+import static org.eclipse.jetty.http.HttpTokens.SPACE;
+import static org.eclipse.jetty.http.HttpTokens.TAB;
+
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -365,22 +370,22 @@ public class HttpParser
if (_cr)
{
- if (ch!=HttpTokens.LINE_FEED)
+ if (ch!=LINE_FEED)
throw new BadMessage("Bad EOL");
_cr=false;
return ch;
}
- if (ch>=0 && ch<HttpTokens.SPACE)
+ if (ch>=0 && ch<SPACE)
{
- if (ch==HttpTokens.CARRIAGE_RETURN)
+ if (ch==CARRIAGE_RETURN)
{
if (buffer.hasRemaining())
{
if(_maxHeaderBytes>0 && _state.ordinal()<State.END.ordinal())
_headerBytes++;
ch=buffer.get();
- if (ch!=HttpTokens.LINE_FEED)
+ if (ch!=LINE_FEED)
throw new BadMessage("Bad EOL");
}
else
@@ -392,8 +397,8 @@ public class HttpParser
}
}
// Only LF or TAB acceptable special characters
- else if (!(ch==HttpTokens.LINE_FEED || ch==HttpTokens.TAB))
- throw new BadMessage("Illegal character");
+ else if (!(ch==LINE_FEED || ch==TAB))
+ throw new IllegalCharacter(ch,buffer);
}
return ch;
@@ -433,7 +438,7 @@ public class HttpParser
{
int ch=next(buffer);
- if (ch > HttpTokens.SPACE)
+ if (ch > SPACE)
{
_string.setLength(0);
_string.append((char)ch);
@@ -508,7 +513,7 @@ public class HttpParser
switch (_state)
{
case METHOD:
- if (ch == HttpTokens.SPACE)
+ if (ch == SPACE)
{
_length=_string.length();
_methodString=takeString();
@@ -517,8 +522,13 @@ public class HttpParser
_methodString=method.asString();
setState(State.SPACE1);
}
- else if (ch < HttpTokens.SPACE)
- throw new BadMessage(ch<0?"Illegal character":"No URI");
+ else if (ch < SPACE)
+ {
+ if (ch==LINE_FEED)
+ throw new BadMessage("No URI");
+ else
+ throw new IllegalCharacter(ch,buffer);
+ }
else
_string.append((char)ch);
break;
@@ -534,7 +544,7 @@ public class HttpParser
setState(State.SPACE1);
}
else if (ch < HttpTokens.SPACE)
- throw new BadMessage(ch<0?"Illegal character":"No Status");
+ throw new IllegalCharacter(ch,buffer);
else
_string.append((char)ch);
break;
@@ -1147,8 +1157,8 @@ public class HttpParser
_length=_string.length();
break;
}
-
- throw new BadMessage("Illegal character");
+
+ throw new IllegalCharacter(ch,buffer);
case HEADER_VALUE:
if (ch>HttpTokens.SPACE || ch<0)
@@ -1172,8 +1182,8 @@ public class HttpParser
setState(State.HEADER);
break;
}
-
- throw new BadMessage("Illegal character");
+
+ throw new IllegalCharacter(ch,buffer);
case HEADER_IN_VALUE:
if (ch>=HttpTokens.SPACE || ch<0 || ch==HttpTokens.TAB)
@@ -1201,7 +1211,8 @@ public class HttpParser
setState(State.HEADER);
break;
}
- throw new BadMessage("Illegal character");
+
+ throw new IllegalCharacter(ch,buffer);
default:
throw new IllegalStateException(_state.toString());
@@ -1578,6 +1589,29 @@ public class HttpParser
}
/* ------------------------------------------------------------------------------- */
+ public Trie<HttpField> getFieldCache()
+ {
+ return _connectionFields;
+ }
+
+ /* ------------------------------------------------------------------------------- */
+ private String getProxyField(ByteBuffer buffer)
+ {
+ _string.setLength(0);
+ _length=0;
+
+ while (buffer.hasRemaining())
+ {
+ // process each character
+ byte ch=next(buffer);
+ if (ch<=' ')
+ return _string.toString();
+ _string.append((char)ch);
+ }
+ throw new BadMessage();
+ }
+
+ /* ------------------------------------------------------------------------------- */
@Override
public String toString()
{
@@ -1632,11 +1666,17 @@ public class HttpParser
public int getHeaderCacheSize();
}
+ /* ------------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------------- */
public interface ProxyHandler
{
void proxied(String protocol, String sAddr, String dAddr, int sPort, int dPort);
}
-
+
+ /* ------------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------------- */
public interface RequestHandler<T> extends HttpHandler<T>
{
/**
@@ -1657,6 +1697,9 @@ public class HttpParser
public abstract boolean parsedHostHeader(String host,int port);
}
+ /* ------------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------------- */
public interface ResponseHandler<T> extends HttpHandler<T>
{
/**
@@ -1665,24 +1708,14 @@ public class HttpParser
public abstract boolean startResponse(HttpVersion version, int status, String reason);
}
- public Trie<HttpField> getFieldCache()
- {
- return _connectionFields;
- }
-
- private String getProxyField(ByteBuffer buffer)
+ /* ------------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------------- */
+ private class IllegalCharacter extends BadMessage
{
- _string.setLength(0);
- _length=0;
-
- while (buffer.hasRemaining())
+ IllegalCharacter(byte ch,ByteBuffer buffer)
{
- // process each character
- byte ch=next(buffer);
- if (ch<=' ')
- return _string.toString();
- _string.append((char)ch);
+ super(String.format("Illegal character 0x%x in state=%s in '%s'",ch,_state,BufferUtil.toDebugString(buffer)));
}
- throw new BadMessage();
}
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java
index 0e6fd889da..83b4dcecb1 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java
@@ -21,6 +21,8 @@ package org.eclipse.jetty.io;
import java.io.Closeable;
import java.io.IOException;
import java.net.ConnectException;
+import java.net.Socket;
+import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.SelectionKey;
@@ -39,6 +41,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.util.ConcurrentArrayQueue;
import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
@@ -65,6 +68,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
private final ManagedSelector[] _selectors;
private long _connectTimeout = DEFAULT_CONNECT_TIMEOUT;
private long _selectorIndex;
+ private int _priorityDelta;
protected SelectorManager(Executor executor, Scheduler scheduler)
{
@@ -110,6 +114,42 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
_connectTimeout = milliseconds;
}
+
+ @ManagedAttribute("The priority delta to apply to selector threads")
+ public int getSelectorPriorityDelta()
+ {
+ return _priorityDelta;
+ }
+
+ /**
+ * Sets the selector thread priority delta to the given amount.
+ * <p>This allows the selector threads to run at a different priority.
+ * Typically this would be used to lower the priority to give preference
+ * to handling previously accepted connections rather than accepting
+ * new connections.</p>
+ *
+ * @param selectorPriorityDelta the amount to change the thread priority
+ * delta to (may be negative)
+ * @see Thread#getPriority()
+ */
+ public void setSelectorPriorityDelta(int selectorPriorityDelta)
+ {
+ int oldDelta = _priorityDelta;
+ _priorityDelta = selectorPriorityDelta;
+ if (oldDelta != selectorPriorityDelta && isStarted())
+ {
+ for (ManagedSelector selector : _selectors)
+ {
+ Thread thread = selector._thread;
+ if (thread != null)
+ {
+ int deltaDiff = selectorPriorityDelta - oldDelta;
+ thread.setPriority(Math.max(Thread.MIN_PRIORITY, Math.min(Thread.MAX_PRIORITY, thread.getPriority() - deltaDiff)));
+ }
+ }
+ }
+ }
+
/**
* Executes the given task in a different thread.
*
@@ -140,11 +180,13 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
/**
* <p>Registers a channel to perform a non-blocking connect.</p>
- * <p>The channel must be set in non-blocking mode, and {@link SocketChannel#connect(SocketAddress)}
- * must be called prior to calling this method.</p>
+ * <p>The channel must be set in non-blocking mode, {@link SocketChannel#connect(SocketAddress)}
+ * must be called prior to calling this method, and the connect operation must not be completed
+ * (the return value of {@link SocketChannel#connect(SocketAddress)} must be false).</p>
*
* @param channel the channel to register
* @param attachment the attachment object
+ * @see #accept(SocketChannel, Object)
*/
public void connect(SocketChannel channel, Object attachment)
{
@@ -153,16 +195,27 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
}
/**
+ * @see #accept(SocketChannel, Object)
+ */
+ public void accept(SocketChannel channel)
+ {
+ accept(channel, null);
+ }
+
+ /**
* <p>Registers a channel to perform non-blocking read/write operations.</p>
* <p>This method is called just after a channel has been accepted by {@link ServerSocketChannel#accept()},
- * or just after having performed a blocking connect via {@link Socket#connect(SocketAddress, int)}.</p>
+ * or just after having performed a blocking connect via {@link Socket#connect(SocketAddress, int)}, or
+ * just after a non-blocking connect via {@link SocketChannel#connect(SocketAddress)} that completed
+ * successfully.</p>
*
* @param channel the channel to register
+ * @param attachment the attachment object
*/
- public void accept(final SocketChannel channel)
+ public void accept(SocketChannel channel, Object attachment)
{
final ManagedSelector selector = chooseSelector();
- selector.submit(selector.new Accept(channel));
+ selector.submit(selector.new Accept(channel, attachment));
}
/**
@@ -173,7 +226,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
*
* @param server the server channel to register
*/
- public void acceptor(final ServerSocketChannel server)
+ public void acceptor(ServerSocketChannel server)
{
final ManagedSelector selector = chooseSelector();
selector.submit(selector.new Acceptor(server));
@@ -479,9 +532,13 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
_thread = Thread.currentThread();
String name = _thread.getName();
+ int priority = _thread.getPriority();
try
{
- _thread.setName(name + "-selector-" + SelectorManager.this.getClass().getSimpleName()+"@"+Integer.toHexString(SelectorManager.this.hashCode())+"/"+_id);
+ if (_priorityDelta != 0)
+ _thread.setPriority(Math.max(Thread.MIN_PRIORITY, Math.min(Thread.MAX_PRIORITY, priority + _priorityDelta)));
+
+ _thread.setName(String.format("%s-selector-%s@%h/%d", name, SelectorManager.this.getClass().getSimpleName(), SelectorManager.this.hashCode(), _id));
if (LOG.isDebugEnabled())
LOG.debug("Starting {} on {}", _thread, this);
while (isRunning())
@@ -494,6 +551,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
if (LOG.isDebugEnabled())
LOG.debug("Stopped {} on {}", _thread, this);
_thread.setName(name);
+ if (_priorityDelta != 0)
+ _thread.setPriority(priority);
}
}
@@ -812,11 +871,13 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
private class Accept implements Runnable
{
- private final SocketChannel _channel;
+ private final SocketChannel channel;
+ private final Object attachment;
- public Accept(SocketChannel channel)
+ private Accept(SocketChannel channel, Object attachment)
{
- this._channel = channel;
+ this.channel = channel;
+ this.attachment = attachment;
}
@Override
@@ -824,13 +885,13 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
try
{
- SelectionKey key = _channel.register(_selector, 0, null);
- EndPoint endpoint = createEndPoint(_channel, key);
+ SelectionKey key = channel.register(_selector, 0, attachment);
+ EndPoint endpoint = createEndPoint(channel, key);
key.attach(endpoint);
}
catch (Throwable x)
{
- closeNoExceptions(_channel);
+ closeNoExceptions(channel);
LOG.debug(x);
}
}
@@ -843,7 +904,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
private final Object attachment;
private final Scheduler.Task timeout;
- public Connect(SocketChannel channel, Object attachment)
+ private Connect(SocketChannel channel, Object attachment)
{
this.channel = channel;
this.attachment = attachment;
@@ -863,7 +924,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
}
}
- protected void failed(Throwable failure)
+ private void failed(Throwable failure)
{
if (failed.compareAndSet(false, true))
{
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
index e599b27149..18d44061c3 100644
--- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
+++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
@@ -416,7 +416,10 @@ public class MongoSessionIdManager extends AbstractSessionIdManager
_scheduler = new ScheduledExecutorScheduler();
_ownScheduler = true;
_scheduler.start();
- }
+ }
+ else if (!_scheduler.isStarted())
+ throw new IllegalStateException("Shared scheduler not started");
+
//setup the scavenger thread
if (_scavengePeriod > 0)
diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
index b43ce7338c..0fe85f9b28 100644
--- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
+++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
@@ -250,15 +250,18 @@ public class ConnectHandler extends HandlerWrapper
channel.socket().setTcpNoDelay(true);
channel.configureBlocking(false);
InetSocketAddress address = new InetSocketAddress(host, port);
- channel.connect(address);
AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(0);
if (LOG.isDebugEnabled())
LOG.debug("Connecting to {}", address);
+
ConnectContext connectContext = new ConnectContext(request, response, asyncContext, HttpConnection.getCurrentConnection());
- selector.connect(channel, connectContext);
+ if (channel.connect(address))
+ selector.accept(channel, connectContext);
+ else
+ selector.connect(channel, connectContext);
}
catch (Exception x)
{
diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java
index 40d99b06e6..bcbc106651 100644
--- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java
+++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java
@@ -222,6 +222,7 @@ public class ProxyServletTest
.timeout(5, TimeUnit.SECONDS)
.send();
+ Assert.assertEquals("OK", response.getReason());
Assert.assertEquals(200, response.getStatus());
Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));
}
diff --git a/jetty-server/src/main/config/etc/jetty-http.xml b/jetty-server/src/main/config/etc/jetty-http.xml
index c3f74f3e66..75012f36af 100644
--- a/jetty-server/src/main/config/etc/jetty-http.xml
+++ b/jetty-server/src/main/config/etc/jetty-http.xml
@@ -22,6 +22,8 @@
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server" /></Arg>
+ <Arg name="acceptors" type="int"><Property name="http.acceptors" default="-1"/></Arg>
+ <Arg name="selectors" type="int"><Property name="http.selectors" default="-1"/></Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
@@ -35,6 +37,8 @@
<Set name="port"><Property name="jetty.port" default="80" /></Set>
<Set name="idleTimeout"><Property name="http.timeout" default="30000"/></Set>
<Set name="soLingerTime"><Property name="http.soLingerTime" default="-1"/></Set>
+ <Set name="acceptorPriorityDelta"><Property name="http.acceptorPriorityDelta" default="0"/></Set>
+ <Set name="selectorPriorityDelta"><Property name="http.selectorPriorityDelta" default="0"/></Set>
</New>
</Arg>
</Call>
diff --git a/jetty-server/src/main/config/etc/jetty-https.xml b/jetty-server/src/main/config/etc/jetty-https.xml
index 419f8d19ee..a019cb90e7 100644
--- a/jetty-server/src/main/config/etc/jetty-https.xml
+++ b/jetty-server/src/main/config/etc/jetty-https.xml
@@ -23,26 +23,30 @@
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server" /></Arg>
- <Arg name="factories">
- <Array type="org.eclipse.jetty.server.ConnectionFactory">
- <Item>
- <New class="org.eclipse.jetty.server.SslConnectionFactory">
- <Arg name="next">http/1.1</Arg>
- <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
- </New>
- </Item>
- <Item>
- <New class="org.eclipse.jetty.server.HttpConnectionFactory">
- <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
- </New>
- </Item>
- </Array>
- </Arg>
- <Set name="host"><Property name="jetty.host" /></Set>
- <Set name="port"><Property name="https.port" default="443" /></Set>
- <Set name="idleTimeout"><Property name="https.timeout" default="30000"/></Set>
- <Set name="soLingerTime"><Property name="https.soLingerTime" default="-1"/></Set>
- </New>
+ <Arg name="acceptors" type="int"><Property name="ssl.acceptors" default="-1"/></Arg>
+ <Arg name="selectors" type="int"><Property name="ssl.selectors" default="-1"/></Arg>
+ <Arg name="factories">
+ <Array type="org.eclipse.jetty.server.ConnectionFactory">
+ <Item>
+ <New class="org.eclipse.jetty.server.SslConnectionFactory">
+ <Arg name="next">http/1.1</Arg>
+ <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
+ </New>
+ </Item>
+ <Item>
+ <New class="org.eclipse.jetty.server.HttpConnectionFactory">
+ <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
+ </New>
+ </Item>
+ </Array>
+ </Arg>
+ <Set name="host"><Property name="jetty.host" /></Set>
+ <Set name="port"><Property name="https.port" default="443" /></Set>
+ <Set name="idleTimeout"><Property name="https.timeout" default="30000"/></Set>
+ <Set name="soLingerTime"><Property name="https.soLingerTime" default="-1"/></Set>
+ <Set name="acceptorPriorityDelta"><Property name="ssl.acceptorPriorityDelta" default="0"/></Set>
+ <Set name="selectorPriorityDelta"><Property name="ssl.selectorPriorityDelta" default="0"/></Set>
+ </New>
</Arg>
</Call>
</Configure>
diff --git a/jetty-server/src/main/config/modules/http.mod b/jetty-server/src/main/config/modules/http.mod
index 8740af3c7b..dc34bc3cb9 100644
--- a/jetty-server/src/main/config/modules/http.mod
+++ b/jetty-server/src/main/config/modules/http.mod
@@ -9,10 +9,19 @@ server
etc/jetty-http.xml
[ini-template]
-## HTTP Connector Configuration
-# HTTP port to listen on
+### HTTP Connector Configuration
+
+## HTTP port to listen on
jetty.port=8080
-# HTTP idle timeout in milliseconds
+
+## HTTP idle timeout in milliseconds
http.timeout=30000
-# HTTP Socket.soLingerTime in seconds. (-1 to disable)
+
+## HTTP Socket.soLingerTime in seconds. (-1 to disable)
# http.soLingerTime=-1
+
+## Parameters to control the number and priority of acceptors and selectors
+# http.selectors=1
+# http.acceptors=1
+# http.selectorPriorityDelta=0
+# http.acceptorPriorityDelta=0
diff --git a/jetty-server/src/main/config/modules/ssl.mod b/jetty-server/src/main/config/modules/ssl.mod
index 449f58104f..ef471929f3 100644
--- a/jetty-server/src/main/config/modules/ssl.mod
+++ b/jetty-server/src/main/config/modules/ssl.mod
@@ -12,24 +12,29 @@ etc/jetty-ssl.xml
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/plain/jetty-server/src/main/config/etc/keystore|etc/keystore
[ini-template]
-## SSL Keystore Configuration
+### SSL Keystore Configuration
# define the port to use for secure redirection
jetty.secure.port=8443
-# Setup a demonstration keystore and truststore
+## Setup a demonstration keystore and truststore
jetty.keystore=etc/keystore
jetty.truststore=etc/keystore
-# Set the demonstration passwords.
-# Note that OBF passwords are not secure, just protected from casual observation
-# See http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html
+## Set the demonstration passwords.
+## Note that OBF passwords are not secure, just protected from casual observation
+## See http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html
jetty.keystore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
jetty.keymanager.password=OBF:1u2u1wml1z7s1z7a1wnl1u2g
jetty.truststore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
-# Set the client auth behavior
-# Set to true if client certificate authentication is required
+### Set the client auth behavior
+## Set to true if client certificate authentication is required
# jetty.ssl.needClientAuth=true
-# Set to true if client certificate authentication is desired
+## Set to true if client certificate authentication is desired
# jetty.ssl.wantClientAuth=true
+## Parameters to control the number and priority of acceptors and selectors
+# ssl.selectors=1
+# ssl.acceptors=1
+# ssl.selectorPriorityDelta=0
+# ssl.acceptorPriorityDelta=0
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index 3106eec257..860799442f 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -147,6 +147,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
private String _defaultProtocol;
private ConnectionFactory _defaultConnectionFactory;
private String _name;
+ private int _acceptorPriorityDelta;
/**
@@ -399,6 +400,30 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
}
}
+ @ManagedAttribute("The priority delta to apply to acceptor threads")
+ public int getAcceptorPriorityDelta()
+ {
+ return _acceptorPriorityDelta;
+ }
+
+ /* ------------------------------------------------------------ */
+ /** Set the acceptor thread priority delta.
+ * <p>This allows the acceptor thread to run at a different priority.
+ * Typically this would be used to lower the priority to give preference
+ * to handling previously accepted connections rather than accepting
+ * new connections</p>
+ * @param acceptorPriorityDelta
+ */
+ public void setAcceptorPriorityDelta(int acceptorPriorityDelta)
+ {
+ int old=_acceptorPriorityDelta;
+ _acceptorPriorityDelta = acceptorPriorityDelta;
+ if (old!=acceptorPriorityDelta && isStarted())
+ {
+ for (Thread thread : _acceptors)
+ thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,thread.getPriority()-old+acceptorPriorityDelta)));
+ }
+ }
@Override
@ManagedAttribute("Protocols supported by this connector")
@@ -452,14 +477,18 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
@Override
public void run()
{
- Thread current = Thread.currentThread();
- String name=current.getName();
+ final Thread thread = Thread.currentThread();
+ String name=thread.getName();
_name=String.format("%s-acceptor-%d@%x-%s",name,_acceptor,hashCode(),AbstractConnector.this.toString());
- current.setName(_name);
+ thread.setName(_name);
+
+ int priority=thread.getPriority();
+ if (_acceptorPriorityDelta!=0)
+ thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,priority+_acceptorPriorityDelta)));
synchronized (AbstractConnector.this)
{
- _acceptors[_acceptor] = current;
+ _acceptors[_acceptor] = thread;
}
try
@@ -481,7 +510,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
}
finally
{
- current.setName(name);
+ thread.setName(name);
+ if (_acceptorPriorityDelta!=0)
+ thread.setPriority(priority);
synchronized (AbstractConnector.this)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
index ee99477ef8..530776971b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
@@ -149,6 +149,26 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
{
return _transport;
}
+
+ /**
+ * Get the idle timeout.
+ * <p>This is implemented as a call to {@link EndPoint#getIdleTimeout()}, but may be
+ * overridden by channels that have timeouts different from their connections.
+ */
+ public long getIdleTimeout()
+ {
+ return _endPoint.getIdleTimeout();
+ }
+
+ /**
+ * Set the idle timeout.
+ * <p>This is implemented as a call to {@link EndPoint#setIdleTimeout(long), but may be
+ * overridden by channels that have timeouts different from their connections.
+ */
+ public void setIdleTimeout(long timeoutMs)
+ {
+ _endPoint.setIdleTimeout(timeoutMs);
+ }
public ByteBufferPool getByteBufferPool()
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
index d7cea8b4e5..4454f01e43 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
@@ -24,6 +24,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritePendingException;
import java.util.concurrent.atomic.AtomicReference;
+
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
@@ -52,7 +53,14 @@ public class HttpOutput extends ServletOutputStream implements Runnable
{
private static Logger LOG = Log.getLogger(HttpOutput.class);
private final HttpChannel<?> _channel;
- private final SharedBlockingCallback _writeblock=new SharedBlockingCallback();
+ private final SharedBlockingCallback _writeblock=new SharedBlockingCallback()
+ {
+ @Override
+ protected long getIdleTimeout()
+ {
+ return _channel.getIdleTimeout();
+ }
+ };
private long _written;
private ByteBuffer _aggregate;
private int _bufferSize;
@@ -770,14 +778,15 @@ public class HttpOutput extends ServletOutputStream implements Runnable
}
continue;
}
-
+
switch(_state.get())
{
- case READY:
case CLOSED:
// even though a write is not possible, because a close has
// occurred, we need to call onWritePossible to tell async
// producer that the last write completed.
+ // so fall through
+ case READY:
try
{
_writeListener.onWritePossible();
@@ -788,8 +797,9 @@ public class HttpOutput extends ServletOutputStream implements Runnable
_onError=e;
}
break;
+
default:
-
+ _onError=new IllegalStateException("state="+_state.get());
}
}
}
@@ -834,7 +844,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
@Override
public void onCompleteFailure(Throwable e)
{
- _onError=e;
+ _onError=e==null?new IOException():e;
_channel.getState().onWritePossible();
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java
index 7058425f65..1a1f5a78eb 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java
@@ -24,7 +24,7 @@ import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.util.Callback;
public interface HttpTransport
-{
+{
void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback);
void send(ByteBuffer content, boolean lastContent, Callback callback);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
index f4da30c004..e37b27dacf 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
@@ -113,6 +113,26 @@ public class ServerConnector extends AbstractNetworkConnector
{
this(server,null,null,null,acceptors,selectors,new HttpConnectionFactory());
}
+
+ /* ------------------------------------------------------------ */
+ /** HTTP Server Connection.
+ * <p>Construct a ServerConnector with a private instance of {@link HttpConnectionFactory} as the only factory.</p>
+ * @param server The {@link Server} this connector will accept connection for.
+ * @param acceptors
+ * the number of acceptor threads to use, or -1 for a default value. Acceptors accept new TCP/IP connections. If 0, then
+ * the selector threads are used to accept connections.
+ * @param selectors
+ * the number of selector threads, or -1 for a default value. Selectors notice and schedule established connection that can make IO progress.
+ * @param factories Zero or more {@link ConnectionFactory} instances used to create and configure connections.
+ */
+ public ServerConnector(
+ @Name("server") Server server,
+ @Name("acceptors") int acceptors,
+ @Name("selectors") int selectors,
+ @Name("factories") ConnectionFactory... factories)
+ {
+ this(server,null,null,null,acceptors,selectors,factories);
+ }
/* ------------------------------------------------------------ */
/** Generic Server Connection with default configuration.
@@ -229,6 +249,29 @@ public class ServerConnector extends AbstractNetworkConnector
return channel!=null && channel.isOpen();
}
+
+ @ManagedAttribute("The priority delta to apply to selector threads")
+ public int getSelectorPriorityDelta()
+ {
+ return _manager.getSelectorPriorityDelta();
+ }
+
+ /**
+ * Sets the selector thread priority delta to the given amount.
+ * <p>This allows the selector threads to run at a different priority.
+ * Typically this would be used to lower the priority to give preference
+ * to handling previously accepted connections rather than accepting
+ * new connections.</p>
+ *
+ * @param selectorPriorityDelta the amount to set the thread priority delta to
+ * (may be negative)
+ * @see Thread#getPriority()
+ */
+ public void setSelectorPriorityDelta(int selectorPriorityDelta)
+ {
+ _manager.setSelectorPriorityDelta(selectorPriorityDelta);
+ }
+
/**
* @return whether this connector uses a channel inherited from the JVM.
* @see System#inheritedChannel()
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java
index 04a90f17bc..e0b0276e46 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java
@@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
@@ -79,17 +80,9 @@ public class IdleTimeoutHandler extends HandlerWrapper
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
- HttpConnection connection = HttpConnection.getCurrentConnection();
- final EndPoint endp = connection==null?null:connection.getEndPoint();
-
- final long idle_timeout;
- if (endp==null)
- idle_timeout=-1;
- else
- {
- idle_timeout=endp.getIdleTimeout();
- endp.setIdleTimeout(_idleTimeoutMs);
- }
+ final HttpChannel<?> channel = baseRequest.getHttpChannel();
+ final long idle_timeout=baseRequest.getHttpChannel().getIdleTimeout();
+ channel.setIdleTimeout(_idleTimeoutMs);
try
{
@@ -97,8 +90,6 @@ public class IdleTimeoutHandler extends HandlerWrapper
}
finally
{
- if (endp!=null)
- {
if (_applyToAsync && request.isAsyncStarted())
{
request.getAsyncContext().addListener(new AsyncListener()
@@ -116,19 +107,18 @@ public class IdleTimeoutHandler extends HandlerWrapper
@Override
public void onError(AsyncEvent event) throws IOException
{
- endp.setIdleTimeout(idle_timeout);
+ channel.setIdleTimeout(idle_timeout);
}
@Override
public void onComplete(AsyncEvent event) throws IOException
{
- endp.setIdleTimeout(idle_timeout);
+ channel.setIdleTimeout(idle_timeout);
}
});
}
else
- endp.setIdleTimeout(idle_timeout);
- }
+ channel.setIdleTimeout(idle_timeout);
}
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
index 535dc5f02e..434cf9dfde 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
@@ -992,6 +992,8 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
_ownScheduler = true;
_scheduler.start();
}
+ else if (!_scheduler.isStarted())
+ throw new IllegalStateException("Shared scheduler not started");
setScavengeInterval(getScavengeInterval());
}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
index b810e5cff4..43e7c3626a 100644
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
+++ b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
@@ -156,7 +156,6 @@ public class SPDYClient
channel.bind(bindAddress);
configure(channel);
channel.configureBlocking(false);
- channel.connect(address);
context.put(SslClientConnectionFactory.SSL_PEER_HOST_CONTEXT_KEY, ((InetSocketAddress)address).getHostString());
context.put(SslClientConnectionFactory.SSL_PEER_PORT_CONTEXT_KEY, ((InetSocketAddress)address).getPort());
@@ -164,7 +163,10 @@ public class SPDYClient
context.put(SPDYClientConnectionFactory.SPDY_SESSION_LISTENER_CONTEXT_KEY, listener);
context.put(SPDYClientConnectionFactory.SPDY_SESSION_PROMISE_CONTEXT_KEY, promise);
- factory.selector.connect(channel, context);
+ if (channel.connect(address))
+ factory.selector.accept(channel, context);
+ else
+ factory.selector.connect(channel, context);
}
catch (IOException x)
{
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod
index 040aad1019..49024a7e0a 100644
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod
+++ b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod
@@ -29,3 +29,9 @@ etc/protonego-npn.xml
[files]
lib/
lib/npn/
+
+[license]
+NPN is a hosted at github under the GPL v2 with ClassPath Exception.
+NPN replaces/modified OpenJDK classes in the java.sun.security.ssl package.
+http://github.com/jetty-project/jetty-npn
+http://openjdk.java.net/legal/gplv2+ce.html
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java
index 3a19386a3d..113e31eba2 100644
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java
+++ b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java
@@ -53,6 +53,12 @@ public class HttpChannelOverSPDY extends HttpChannel<DataInfo>
}
@Override
+ public long getIdleTimeout()
+ {
+ return stream.getIdleTimeout();
+ }
+
+ @Override
public boolean headerComplete()
{
headersComplete = true;
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
index ce4cf601c9..22b8377deb 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
@@ -86,6 +86,8 @@ public class Main
public static String join(Collection<?> objs, String delim)
{
+ if (objs==null)
+ return "";
StringBuilder str = new StringBuilder();
boolean needDelim = false;
for (Object obj : objs)
@@ -392,17 +394,45 @@ public class Main
}
boolean transitive = module.isEnabled() && (module.getSources().size() == 0);
- boolean hasDefinedDefaults = module.getDefaultConfig().size() > 0;
-
- // If it is not enabled or is transitive with ini template lines or toplevel and doesn't exist
- if (!module.isEnabled() || (transitive && (hasDefinedDefaults || module.hasLicense()) ) || (topLevel && !FS.exists(startd_ini) && !appendStartIni))
+ boolean buildIni=false;
+ if (module.isEnabled())
+ {
+ // is it an explicit request to create an ini file?
+ if (topLevel && !FS.exists(startd_ini) && !appendStartIni)
+ buildIni=true;
+
+ // else is it transitive
+ else if (transitive)
+ {
+ // do we need an ini anyway?
+ if (module.hasDefaultConfig() || module.hasLicense())
+ buildIni=true;
+ else
+ StartLog.info("%-15s initialised transitively",name);
+ }
+
+ // else must be initialized explicitly
+ else
+ {
+ for (String source : module.getSources())
+ StartLog.info("%-15s initialised in %s",name,baseHome.toShortForm(source));
+ }
+ }
+ else
+ {
+ buildIni=true;
+ }
+
+
+ // If we need an ini
+ if (buildIni)
{
if (module.hasLicense())
{
- System.err.printf("%nModule %s LICENSE%n",module.getName());
- System.err.printf("This module is not provided by the Eclipse Foundation!%n");
- System.err.printf("It contains software not covered by the Eclipse Public License%n");
- System.err.printf("The software has not been audited for compliance with its license%n");
+ System.err.printf("%nModule %s:%n",module.getName());
+ System.err.printf(" + contains software not provided by the Eclipse Foundation!%n");
+ System.err.printf(" + contains software not covered by the Eclipse Public License!%n");
+ System.err.printf(" + has not been audited for compliance with its license%n");
System.err.printf("%n");
for (String l : module.getLicense())
System.err.printf(" %s%n",l);
@@ -484,14 +514,6 @@ public class Main
}
}
}
- else if (FS.exists(startd_ini))
- {
- StartLog.info("%-15s initialised in %s",name,short_startd_ini);
- }
- else
- {
- StartLog.info("%-15s initialised transitively",name);
- }
// Also list other places this module is enabled
for (String source : module.getSources())
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java
index 3b1f79e227..a55fd9e77b 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java
@@ -265,6 +265,12 @@ public class Modules implements Iterable<Module>
}
}
+ public void enable(String name) throws IOException
+ {
+ List<String> empty = Collections.emptyList();
+ enable(name,empty);
+ }
+
public void enable(String name, List<String> sources) throws IOException
{
if (name.contains("*"))
@@ -310,9 +316,14 @@ public class Modules implements Iterable<Module>
private void enableModule(Module module, List<String> sources) throws IOException
{
+ // Always add the sources
+ if (sources != null)
+ module.addSources(sources);
+
+ // If already enabled, nothing else to do
if (module.isEnabled())
{
- // already enabled, skip
+ StartLog.debug("Enabled module: %s (via %s)",module.getName(),Main.join(sources,", "));
return;
}
@@ -320,10 +331,6 @@ public class Modules implements Iterable<Module>
module.setEnabled(true);
args.parseModule(module);
module.expandProperties(args.getProperties());
- if (sources != null)
- {
- module.addSources(sources);
- }
// enable any parents that haven't been enabled (yet)
Set<String> parentNames = new HashSet<>();
@@ -349,7 +356,7 @@ public class Modules implements Iterable<Module>
}
if (parent != null)
{
- enableModule(parent,sources);
+ enableModule(parent,null);
}
}
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java
index 53d24db966..7f0b785a8e 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java
@@ -920,6 +920,11 @@ public class BufferUtil
return builder.toString();
}
+ /* ------------------------------------------------------------ */
+ /** Convert Buffer to a detail debug string of pointers and content
+ * @param buffer
+ * @return A string showing the pointers and content of the buffer
+ */
public static String toDetailString(ByteBuffer buffer)
{
if (buffer == null)
@@ -942,15 +947,33 @@ public class BufferUtil
buf.append(buffer.remaining());
buf.append("]={");
+ appendDebugString(buf,buffer);
+
+ buf.append("}");
+
+ return buf.toString();
+ }
+
+ /* ------------------------------------------------------------ */
+ /** Convert buffer to a Debug String.
+ * @param buffer
+ * @return A string showing the escaped content of the buffer around the
+ * position and limit (marked with &lt;&lt;&lt; and &gt;&gt;&gt;)
+ */
+ public static String toDebugString(ByteBuffer buffer)
+ {
+ if (buffer == null)
+ return "null";
+ StringBuilder buf = new StringBuilder();
+ appendDebugString(buf,buffer);
+ return buf.toString();
+ }
+
+ private static void appendDebugString(StringBuilder buf,ByteBuffer buffer)
+ {
for (int i = 0; i < buffer.position(); i++)
{
- char c = (char)buffer.get(i);
- if (c >= ' ' && c <= 127)
- buf.append(c);
- else if (c == '\r' || c == '\n')
- buf.append('|');
- else
- buf.append('\ufffd');
+ appendContentChar(buf,buffer.get(i));
if (i == 16 && buffer.position() > 32)
{
buf.append("...");
@@ -960,13 +983,7 @@ public class BufferUtil
buf.append("<<<");
for (int i = buffer.position(); i < buffer.limit(); i++)
{
- char c = (char)buffer.get(i);
- if (c >= ' ' && c <= 127)
- buf.append(c);
- else if (c == '\r' || c == '\n')
- buf.append('|');
- else
- buf.append('\ufffd');
+ appendContentChar(buf,buffer.get(i));
if (i == buffer.position() + 16 && buffer.limit() > buffer.position() + 32)
{
buf.append("...");
@@ -978,13 +995,7 @@ public class BufferUtil
buffer.limit(buffer.capacity());
for (int i = limit; i < buffer.capacity(); i++)
{
- char c = (char)buffer.get(i);
- if (c >= ' ' && c <= 127)
- buf.append(c);
- else if (c == '\r' || c == '\n')
- buf.append('|');
- else
- buf.append('\ufffd');
+ appendContentChar(buf,buffer.get(i));
if (i == limit + 16 && buffer.capacity() > limit + 32)
{
buf.append("...");
@@ -992,11 +1003,23 @@ public class BufferUtil
}
}
buffer.limit(limit);
- buf.append("}");
-
- return buf.toString();
}
+ private static void appendContentChar(StringBuilder buf, byte b)
+ {
+ if (b == '\\')
+ buf.append("\\\\");
+ else if (b >= ' ')
+ buf.append((char)b);
+ else if (b == '\r')
+ buf.append("\\r");
+ else if (b == '\n')
+ buf.append("\\n");
+ else if (b == '\t')
+ buf.append("\\t");
+ else
+ buf.append("\\x").append(TypeUtil.toHexString(b));
+ }
private final static int[] decDivisors =
{1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java b/jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java
index 55aab63fa5..becabc1cd6 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java
@@ -20,6 +20,7 @@ package org.eclipse.jetty.util;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -124,8 +125,8 @@ public class LeakDetector<T> extends AbstractLifeCycle implements Runnable
@Override
protected void doStop() throws Exception
{
- thread.interrupt();
super.doStop();
+ thread.interrupt();
}
@Override
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java b/jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java
index 1813f57570..1c4ff3404d 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.concurrent.CancellationException;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@@ -47,7 +48,11 @@ import org.eclipse.jetty.util.thread.NonBlockingThread;
*/
public class SharedBlockingCallback
{
- private static final Logger LOG = Log.getLogger(SharedBlockingCallback.class);
+ static final Logger LOG = Log.getLogger(SharedBlockingCallback.class);
+
+ final ReentrantLock _lock = new ReentrantLock();
+ final Condition _idle = _lock.newCondition();
+ final Condition _complete = _lock.newCondition();
private static Throwable IDLE = new Throwable()
@@ -77,56 +82,64 @@ public class SharedBlockingCallback
}
};
- final Blocker _blocker;
+ Blocker _blocker;
public SharedBlockingCallback()
{
- this(new Blocker());
+ _blocker=new Blocker();
}
- protected SharedBlockingCallback(Blocker blocker)
+ protected long getIdleTimeout()
{
- _blocker=blocker;
+ return -1;
}
public Blocker acquire() throws IOException
{
- _blocker._lock.lock();
+ _lock.lock();
+ long idle = getIdleTimeout();
try
{
while (_blocker._state != IDLE)
- _blocker._idle.await();
+ {
+ if (idle>0)
+ {
+ // Wait a little bit longer than the blocker might block
+ if (!_idle.await(idle*2,TimeUnit.MILLISECONDS))
+ throw new IOException(new TimeoutException());
+ }
+ else
+ _idle.await();
+ }
_blocker._state = null;
}
catch (final InterruptedException e)
{
- throw new InterruptedIOException()
- {
- {
- initCause(e);
- }
- };
+ throw new InterruptedIOException();
}
finally
{
- _blocker._lock.unlock();
+ _lock.unlock();
}
return _blocker;
}
+ protected void notComplete(Blocker blocker)
+ {
+ LOG.warn("Blocker not complete {}",blocker);
+ if (LOG.isDebugEnabled())
+ LOG.debug(new Throwable());
+ }
/* ------------------------------------------------------------ */
/** A Closeable Callback.
* Uses the auto close mechanism to check block has been called OK.
*/
- public static class Blocker implements Callback, Closeable
+ public class Blocker implements Callback, Closeable
{
- final ReentrantLock _lock = new ReentrantLock();
- final Condition _idle = _lock.newCondition();
- final Condition _complete = _lock.newCondition();
Throwable _state = IDLE;
-
- public Blocker()
+
+ protected Blocker()
{
}
@@ -141,8 +154,8 @@ public class SharedBlockingCallback
_state = SUCCEEDED;
_complete.signalAll();
}
- else if (_state == IDLE)
- throw new IllegalStateException("IDLE");
+ else
+ throw new IllegalStateException(_state);
}
finally
{
@@ -158,11 +171,17 @@ public class SharedBlockingCallback
{
if (_state == null)
{
- _state = cause==null?FAILED:cause;
+ if (cause==null)
+ _state=FAILED;
+ else if (cause instanceof BlockerTimeoutException)
+ // Not this blockers timeout
+ _state=new IOException(cause);
+ else
+ _state=cause;
_complete.signalAll();
}
- else if (_state == IDLE)
- throw new IllegalStateException("IDLE",cause);
+ else
+ throw new IllegalStateException(_state);
}
finally
{
@@ -183,10 +202,22 @@ public class SharedBlockingCallback
LOG.warn("Blocking a NonBlockingThread: ",new Throwable());
_lock.lock();
+ long idle = getIdleTimeout();
try
{
while (_state == null)
- _complete.await();
+ {
+ if (idle>0)
+ {
+ // Wait a little bit longer than expected callback idle timeout
+ if (!_complete.await(idle+idle/2,TimeUnit.MILLISECONDS))
+ // The callback has not arrived in sufficient time.
+ // We will synthesize a TimeoutException
+ _state=new BlockerTimeoutException();
+ }
+ else
+ _complete.await();
+ }
if (_state == SUCCEEDED)
return;
@@ -204,12 +235,7 @@ public class SharedBlockingCallback
}
catch (final InterruptedException e)
{
- throw new InterruptedIOException()
- {
- {
- initCause(e);
- }
- };
+ throw new InterruptedIOException();
}
finally
{
@@ -232,17 +258,19 @@ public class SharedBlockingCallback
if (_state == IDLE)
throw new IllegalStateException("IDLE");
if (_state == null)
- {
- LOG.warn("Blocker not complete {}",this);
- if (LOG.isDebugEnabled())
- LOG.debug(new Throwable());
- }
+ notComplete(this);
}
finally
{
try
{
- _state = IDLE;
+ // If the blocker timed itself out, remember the state
+ if (_state instanceof BlockerTimeoutException)
+ // and create a new Blocker
+ _blocker=new Blocker();
+ else
+ // else reuse Blocker
+ _state = IDLE;
_idle.signalAll();
_complete.signalAll();
}
@@ -267,4 +295,8 @@ public class SharedBlockingCallback
}
}
}
+
+ private class BlockerTimeoutException extends TimeoutException
+ {
+ }
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
index 79629eb1ec..1e81258a08 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
@@ -479,7 +479,10 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
@Override
public void dump(Appendable out, String indent) throws IOException
{
- out.append(String.valueOf(thread.getId())).append(' ').append(thread.getName()).append(' ').append(thread.getState().toString()).append(idle ? " IDLE" : "").append('\n');
+ out.append(String.valueOf(thread.getId())).append(' ').append(thread.getName()).append(' ').append(thread.getState().toString()).append(idle ? " IDLE" : "");
+ if (thread.getPriority()!=Thread.NORM_PRIORITY)
+ out.append(" prio="+thread.getPriority());
+ out.append('\n');
if (!idle)
ContainerLifeCycle.dump(out, indent, Arrays.asList(trace));
}
@@ -493,7 +496,8 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
}
else
{
- dump.add(thread.getId() + " " + thread.getName() + " " + thread.getState() + " @ " + (trace.length > 0 ? trace[0] : "???") + (idle ? " IDLE" : ""));
+ int p=thread.getPriority();
+ dump.add(thread.getId() + " " + thread.getName() + " " + thread.getState() + " @ " + (trace.length > 0 ? trace[0] : "???") + (idle ? " IDLE" : "")+ (p==Thread.NORM_PRIORITY?"":(" prio="+p)));
}
}
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java
index 4ee93a6b19..c06e5070d1 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java
@@ -18,9 +18,17 @@
package org.eclipse.jetty.util;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.util.SharedBlockingCallback.Blocker;
import org.hamcrest.Matchers;
@@ -29,7 +37,23 @@ import org.junit.Test;
public class SharedBlockingCallbackTest
{
- final SharedBlockingCallback sbcb= new SharedBlockingCallback();
+ final AtomicInteger notComplete = new AtomicInteger();
+ final SharedBlockingCallback sbcb= new SharedBlockingCallback()
+ {
+ @Override
+ protected long getIdleTimeout()
+ {
+ return 150;
+ }
+
+ @Override
+ protected void notComplete(Blocker blocker)
+ {
+ super.notComplete(blocker);
+ notComplete.incrementAndGet();
+ }
+
+ };
public SharedBlockingCallbackTest()
{
@@ -46,7 +70,8 @@ public class SharedBlockingCallbackTest
start=System.currentTimeMillis();
blocker.block();
}
- Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(500L));
+ Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(500L));
+ Assert.assertEquals(0,notComplete.get());
}
@Test
@@ -74,6 +99,7 @@ public class SharedBlockingCallbackTest
}
Assert.assertThat(System.currentTimeMillis()-start,Matchers.greaterThan(10L));
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(1000L));
+ Assert.assertEquals(0,notComplete.get());
}
@Test
@@ -95,7 +121,8 @@ public class SharedBlockingCallbackTest
start=System.currentTimeMillis();
Assert.assertEquals(ex,ee.getCause());
}
- Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(100L));
+ Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(100L));
+ Assert.assertEquals(0,notComplete.get());
}
@Test
@@ -133,6 +160,7 @@ public class SharedBlockingCallbackTest
}
Assert.assertThat(System.currentTimeMillis()-start,Matchers.greaterThan(10L));
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(1000L));
+ Assert.assertEquals(0,notComplete.get());
}
@@ -174,6 +202,58 @@ public class SharedBlockingCallbackTest
blocker.succeeded();
blocker.block();
};
- Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(600L));
+ Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(600L));
+ Assert.assertEquals(0,notComplete.get());
+ }
+
+ @Test
+ public void testBlockerClose() throws Exception
+ {
+ try (Blocker blocker=sbcb.acquire())
+ {
+ SharedBlockingCallback.LOG.info("Blocker not complete "+blocker+" warning is expected...");
+ }
+
+ Assert.assertEquals(1,notComplete.get());
+ }
+
+ @Test
+ public void testBlockerTimeout() throws Exception
+ {
+ Blocker b0=null;
+ try
+ {
+ try (Blocker blocker=sbcb.acquire())
+ {
+ b0=blocker;
+ Thread.sleep(400);
+ blocker.block();
+ }
+ fail();
+ }
+ catch(IOException e)
+ {
+ Throwable cause = e.getCause();
+ assertThat(cause,instanceOf(TimeoutException.class));
+ }
+
+ Assert.assertEquals(0,notComplete.get());
+
+
+ try (Blocker blocker=sbcb.acquire())
+ {
+ assertThat(blocker,not(equalTo(b0)));
+ try
+ {
+ b0.succeeded();
+ fail();
+ }
+ catch(Exception e)
+ {
+ assertThat(e,instanceOf(IllegalStateException.class));
+ assertThat(e.getCause(),instanceOf(TimeoutException.class));
+ }
+ blocker.succeeded();
+ }
}
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java
index 4617c02550..b2291012b6 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java
@@ -71,6 +71,17 @@ public class MetaInfConfiguration extends AbstractConfiguration
useContainerCache = attr.booleanValue();
if (LOG.isDebugEnabled()) LOG.debug("{} = {}", USE_CONTAINER_METAINF_CACHE, useContainerCache);
+
+ //pre-emptively create empty lists for tlds, fragments and resources as context attributes
+ //this signals that this class has been called. This differentiates the case where this class
+ //has been called but finds no META-INF data from the case where this class was never called
+ if (context.getAttribute(METAINF_TLDS) == null)
+ context.setAttribute(METAINF_TLDS, new HashSet<URL>());
+ if (context.getAttribute(METAINF_RESOURCES) == null)
+ context.setAttribute(METAINF_RESOURCES, new HashSet<Resource>());
+ if (context.getAttribute(METAINF_FRAGMENTS) == null)
+ context.setAttribute(METAINF_FRAGMENTS, new HashMap<Resource, Resource>());
+
scanJars(context, context.getMetaData().getContainerResources(), useContainerCache);
scanJars(context, context.getMetaData().getWebInfJars(), false);
}
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java
index 487002f145..729483cdcb 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java
@@ -251,7 +251,7 @@ public class WebDescriptor extends Descriptor
}
}
- if (_majorVersion < 2 && _minorVersion < 5)
+ if (_majorVersion <= 2 && _minorVersion < 5)
_metaDataComplete = MetaDataComplete.True; // does not apply before 2.5
else
{
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
index 1e4096c19c..1e68b1991f 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
@@ -175,7 +175,7 @@ public class WebInfConfiguration extends AbstractConfiguration
// Look for extra resource
@SuppressWarnings("unchecked")
Set<Resource> resources = (Set<Resource>)context.getAttribute(RESOURCE_DIRS);
- if (resources!=null)
+ if (resources!=null && !resources.isEmpty())
{
Resource[] collection=new Resource[resources.size()+1];
int i=0;
diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java
index ab20d77d9d..cb04029882 100644
--- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java
+++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java
@@ -74,8 +74,14 @@ public class ConnectionManager extends ContainerLifeCycle
InetSocketAddress address = toSocketAddress(wsUri);
- channel.connect(address);
- getSelector().connect(channel,this);
+ if (channel.connect(address))
+ {
+ getSelector().accept(channel, this);
+ }
+ else
+ {
+ getSelector().connect(channel, this);
+ }
}
catch (Throwable t)
{
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/BlockingWriteCallback.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/BlockingWriteCallback.java
index 4fdc68072f..838afc93e5 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/BlockingWriteCallback.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/BlockingWriteCallback.java
@@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.common;
import java.io.IOException;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.SharedBlockingCallback;
import org.eclipse.jetty.websocket.api.WriteCallback;
@@ -31,26 +32,55 @@ public class BlockingWriteCallback extends SharedBlockingCallback
{
public BlockingWriteCallback()
{
- super(new WriteBlocker());
}
public WriteBlocker acquireWriteBlocker() throws IOException
{
- return (WriteBlocker)acquire();
+ return new WriteBlocker(acquire());
}
- public static class WriteBlocker extends Blocker implements WriteCallback
+ public static class WriteBlocker implements WriteCallback, Callback, AutoCloseable
{
+ Blocker blocker;
+
+ WriteBlocker(Blocker blocker)
+ {
+ this.blocker=blocker;
+ }
+
@Override
public void writeFailed(Throwable x)
{
- failed(x);
+ blocker.failed(x);
}
@Override
public void writeSuccess()
{
- succeeded();
+ blocker.succeeded();
+ }
+
+ @Override
+ public void succeeded()
+ {
+ blocker.succeeded();
+ }
+
+ @Override
+ public void failed(Throwable x)
+ {
+ blocker.failed(x);
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ blocker.close();
+ }
+
+ public void block() throws IOException
+ {
+ blocker.block();
}
}
}
diff --git a/tests/pom.xml b/tests/pom.xml
index de745caa09..9524a5d609 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -47,5 +47,6 @@
<module>test-continuation</module>
<module>test-loginservice</module>
<module>test-integration</module>
+ <module>test-quickstart</module>
</modules>
</project>
diff --git a/examples/quickstart/pom.xml b/tests/test-quickstart/pom.xml
index 08e46952d5..2874c68008 100644
--- a/examples/quickstart/pom.xml
+++ b/tests/test-quickstart/pom.xml
@@ -1,22 +1,21 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
- <groupId>org.eclipse.jetty.examples</groupId>
- <artifactId>examples-parent</artifactId>
+ <groupId>org.eclipse.jetty.tests</groupId>
+ <artifactId>tests-parent</artifactId>
<version>9.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty</groupId>
- <artifactId>example-jetty-quickstart</artifactId>
- <name>Example :: Jetty Quick Start</name>
- <description>Jetty Quick Start Example</description>
+ <artifactId>test-quickstart</artifactId>
+ <name>Test :: Jetty Quick Start</name>
+ <description>Jetty Quick Start Test</description>
<url>http://www.eclipse.org/jetty</url>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-quickstart</artifactId>
<version>${project.version}</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
@@ -42,75 +41,63 @@
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>1.2</version>
- <scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-mock-resources</artifactId>
<version>${project.version}</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.mail.glassfish</artifactId>
<version>1.4.1.v201005082020</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>${project.version}</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-jndi-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-spec-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>test-jetty-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<version>${project.version}</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-server</artifactId>
<version>${project.version}</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jsp</artifactId>
<version>${project.version}</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jstl</artifactId>
<version>${project.version}</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
- <scope>test</scope>
</dependency>
</dependencies>
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java
index a8f636945a..a8f636945a 100644
--- a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java
+++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java
index 7dd62d83ed..7dd62d83ed 100644
--- a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java
+++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java
index 2dcfeb7eab..2dcfeb7eab 100644
--- a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java
+++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java
index 07bc1b6648..07bc1b6648 100644
--- a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java
+++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java
index b84a12f298..b84a12f298 100644
--- a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java
+++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java
index 7da8b23465..7da8b23465 100644
--- a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java
+++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java
index 4ff5fff00f..4ff5fff00f 100644
--- a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java
+++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java
index 75dc114e10..75dc114e10 100644
--- a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java
+++ b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java
diff --git a/examples/quickstart/src/test/resources/realm.properties b/tests/test-quickstart/src/test/resources/realm.properties
index 9d88b852b7..9d88b852b7 100644
--- a/examples/quickstart/src/test/resources/realm.properties
+++ b/tests/test-quickstart/src/test/resources/realm.properties
diff --git a/examples/quickstart/src/test/resources/test-jndi.xml b/tests/test-quickstart/src/test/resources/test-jndi.xml
index 14c0934845..14c0934845 100644
--- a/examples/quickstart/src/test/resources/test-jndi.xml
+++ b/tests/test-quickstart/src/test/resources/test-jndi.xml
diff --git a/examples/quickstart/src/test/resources/test-spec.xml b/tests/test-quickstart/src/test/resources/test-spec.xml
index 99fc577205..99fc577205 100644
--- a/examples/quickstart/src/test/resources/test-spec.xml
+++ b/tests/test-quickstart/src/test/resources/test-spec.xml
diff --git a/examples/quickstart/src/test/resources/test.xml b/tests/test-quickstart/src/test/resources/test.xml
index bbdf08a23a..41eba0c290 100644
--- a/examples/quickstart/src/test/resources/test.xml
+++ b/tests/test-quickstart/src/test/resources/test.xml
@@ -30,6 +30,8 @@ detected.
<Set name="checkWelcomeFiles">true</Set>
</Get>
+ <Set name="parentLoaderPriority">true</Set>
+
<!-- Non standard error page mapping -->
<!--
<Get name="errorHandler">
diff --git a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini b/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini
deleted file mode 100644
index 9607fd29f9..0000000000
--- a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# HTTP connector
-#
---module=http
-jetty.port=8080
-

Back to the top