Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2011-11-28 17:06:25 -0500
committerGreg Wilkins2011-11-28 17:06:25 -0500
commit55d5020980aa0b2118f8a3f00e5306bb264fe689 (patch)
tree4da0894a745e23db2941a61aeb5e238aaec11fdb
parentcbec18af6028105cfa5261c6176c29ac210140bc (diff)
parent4ce72ee5498149536c695211ea1a43329863b203 (diff)
downloadorg.eclipse.jetty.project-55d5020980aa0b2118f8a3f00e5306bb264fe689.tar.gz
org.eclipse.jetty.project-55d5020980aa0b2118f8a3f00e5306bb264fe689.tar.xz
org.eclipse.jetty.project-55d5020980aa0b2118f8a3f00e5306bb264fe689.zip
Merge remote-tracking branch 'origin/master' into jetty-8
Conflicts: VERSION.txt jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java jetty-server/src/main/java/org/eclipse/jetty/server/Response.java jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
-rw-r--r--VERSION.txt2
-rw-r--r--jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java5
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpConnection.java24
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/AsyncHttpConnection.java12
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java24
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java5
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java9
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java53
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java7
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java4
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/Curl.java2
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java9
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java78
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/HttpsViaBrokenHttpProxyTest.java5
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SluggishServerTest.java4
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesClientTest.java148
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java377
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesTest.java337
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java2
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/UnexpectedDataTest.java1
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AbstractSslServerAndClientCreator.java1
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AsyncSslServerAndClientCreator.java2
-rw-r--r--jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Jetty6Continuation.java8
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java2
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java39
-rw-r--r--jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java25
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java23
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java22
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java18
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java45
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java137
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java31
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java61
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java1
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/nio/ChannelEndPointTest.java1
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/nio/NIOTest.java131
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointSslTest.java2
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java84
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java2
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java30
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java34
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java6
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/BlockingHttpConnection.java17
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/Response.java25
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java27
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java1
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java2
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java60
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java7
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java94
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java368
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java1
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java22
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java19
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java1
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSelectChannelTimeoutTest.java1
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java1
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java2
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java2
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java2
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java2
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java53
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java13
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/log/CapturingJULHandler.java2
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/log/JavaUtilLogTest.java2
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java2
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrCapture.java3
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java3
-rw-r--r--jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java1
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java42
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java44
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD08.java44
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD13.java93
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java3
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD13.java1
-rw-r--r--jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD13.java1
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketClientTest.java2
-rw-r--r--jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD13Test.java5
-rw-r--r--jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java65
-rw-r--r--test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java56
-rw-r--r--test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/HttpTesterTest.java16
-rw-r--r--test-jetty-webapp/src/main/java/com/acme/Dump.java41
85 files changed, 1641 insertions, 1324 deletions
diff --git a/VERSION.txt b/VERSION.txt
index 796bd76ed6..28e26050db 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -92,7 +92,7 @@ jetty-7.5.3.v20111011 - 11 October 2011
+ 358649 StdErrLog system properties for package/class logging LEVEL.
jetty-7.5.2.v20111006 - 06 October 2011
- + 336443 add missing comma in DigestAuthenticator string
+ + 336443 check nonce count is increasing
+ 342161 ScannerTest fails intermittently on Mac OS X
+ 346419 testing HttpClient FDs
+ 353267 Request._parameters initialization bug
diff --git a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java
index 1afc64facf..f29159b870 100644
--- a/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java
+++ b/jetty-ajp/src/main/java/org/eclipse/jetty/ajp/Ajp13Connection.java
@@ -216,7 +216,10 @@ public class Ajp13Connection extends BlockingHttpConnection
public void parsedRequestAttribute(String key, Buffer value) throws IOException
{
- _request.setAttribute(key, value.toString());
+ if (value==null)
+ _request.removeAttribute(key);
+ else
+ _request.setAttribute(key,value.toString());
}
public void parsedRequestAttribute(String key, int value) throws IOException
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpConnection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpConnection.java
index 868dbd4ba5..20a5d04aa6 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpConnection.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpConnection.java
@@ -29,7 +29,6 @@ import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersions;
import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.ByteArrayBuffer;
@@ -149,7 +148,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection implemen
}
public abstract Connection handle() throws IOException;
-
+
public boolean isIdle()
{
@@ -275,7 +274,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection implemen
_endp.close();
return;
}
-
+
switch(status)
{
case HttpStatus.CONTINUE_100:
@@ -295,7 +294,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection implemen
_status=status;
exchange.getEventListener().onResponseStatus(version,status,reason);
exchange.setStatus(HttpExchange.STATUS_PARSING_HEADERS);
-
+
}
@Override
@@ -315,8 +314,6 @@ public abstract class AbstractHttpConnection extends AbstractConnection implemen
@Override
public void headerComplete() throws IOException
{
- if (_endp instanceof AsyncEndPoint)
- ((AsyncEndPoint)_endp).scheduleIdle();
HttpExchange exchange = _exchange;
if (exchange!=null)
exchange.setStatus(HttpExchange.STATUS_PARSING_CONTENT);
@@ -325,8 +322,6 @@ public abstract class AbstractHttpConnection extends AbstractConnection implemen
@Override
public void content(Buffer ref) throws IOException
{
- if (_endp instanceof AsyncEndPoint)
- ((AsyncEndPoint)_endp).scheduleIdle();
HttpExchange exchange = _exchange;
if (exchange!=null)
exchange.getEventListener().onResponseContent(ref);
@@ -353,16 +348,19 @@ public abstract class AbstractHttpConnection extends AbstractConnection implemen
}
}
}
-
-
+
+
}
@Override
public String toString()
{
- return "HttpConnection@" + hashCode() + "//" +
- (_destination==null?"?.?.?.?:??":(_destination.getAddress().getHost() + ":" + _destination.getAddress().getPort()))+
- ",g="+_generator.getState()+",p="+_parser.getState();
+ return String.format("%s@%x//%s,g=%s,p=%s",
+ getClass().getSimpleName(),
+ hashCode(),
+ _destination == null ? "?.?.?.?:??" : _destination.getAddress(),
+ _generator,
+ _parser);
}
public String toDetailString()
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncHttpConnection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncHttpConnection.java
index 43596fb026..455edfbeb9 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncHttpConnection.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncHttpConnection.java
@@ -122,16 +122,16 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
exchange.getEventListener().onRequestComplete();
}
- // Flush output
- _endp.flush();
-
// Read any input that is available
if (!_parser.isComplete() && _parser.parseAvailable())
{
- LOG.debug("parsed");
+ LOG.debug("parsed {}",exchange);
progress=true;
}
+ // Flush output
+ _endp.flush();
+
// Has any IO been done by the endpoint itself since last loop
if (_asyncEndp.hasProgressed())
{
@@ -139,10 +139,6 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
progress=true;
}
}
- catch (ThreadDeath e)
- {
- throw e;
- }
catch (Throwable e)
{
LOG.debug("Failure on " + _exchange, e);
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java
index a8bd928bcd..d241699bda 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java
@@ -31,16 +31,14 @@ import org.eclipse.jetty.util.log.Logger;
*/
public class BlockingHttpConnection extends AbstractHttpConnection
{
-
private static final Logger LOG = Log.getLogger(BlockingHttpConnection.class);
private boolean _requestComplete;
- private int _status;
private Buffer _requestContentChunk;
- BlockingHttpConnection(Buffers requestBuffers, Buffers responseBuffers, EndPoint endp)
+ BlockingHttpConnection(Buffers requestBuffers, Buffers responseBuffers, EndPoint endPoint)
{
- super(requestBuffers,responseBuffers,endp);
+ super(requestBuffers, responseBuffers, endPoint);
}
protected void reset() throws IOException
@@ -131,19 +129,14 @@ public class BlockingHttpConnection extends AbstractHttpConnection
exchange.getEventListener().onRequestComplete();
}
- // Flush output
- _endp.flush();
-
// Read any input that is available
if (!_parser.isComplete() && _parser.parseAvailable())
{
LOG.debug("parsed");
}
- }
- catch (ThreadDeath e)
- {
- throw e;
+ // Flush output
+ _endp.flush();
}
catch (Throwable e)
{
@@ -235,7 +228,6 @@ public class BlockingHttpConnection extends AbstractHttpConnection
if (_exchange==null && !isReserved()) // TODO how do we return switched connections?
_destination.returnConnection(this, !persistent);
}
-
}
}
}
@@ -249,14 +241,6 @@ public class BlockingHttpConnection extends AbstractHttpConnection
return connection;
}
-
- public void onInputShutdown() throws IOException
- {
- if (_generator.isIdle())
- _endp.shutdownOutput();
- }
-
-
@Override
public boolean send(HttpExchange ex) throws IOException
{
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
index 0b168be513..21e8b0f89e 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
@@ -16,6 +16,7 @@ package org.eclipse.jetty.client;
import java.io.IOException;
import java.io.InputStream;
import java.net.UnknownHostException;
+import java.util.Arrays;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.Set;
@@ -164,7 +165,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
public void dump(Appendable out, String indent) throws IOException
{
out.append(String.valueOf(this)).append("\n");
- AggregateLifeCycle.dump(out,indent,_destinations.values());
+ AggregateLifeCycle.dump(out,indent,Arrays.asList(_threadPool,_connector),_destinations.values());
}
/* ------------------------------------------------------------------------------- */
@@ -190,7 +191,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable
pool.setName("HttpClient");
_threadPool = pool;
}
-
+
return _threadPool;
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java
index a0e40ef15f..3992a5cef5 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java
@@ -439,14 +439,7 @@ public class HttpDestination implements Dumpable
public void returnIdleConnection(AbstractHttpConnection connection)
{
- try
- {
- connection.close();
- }
- catch (IOException e)
- {
- LOG.ignore(e);
- }
+ connection.onIdleExpired();
boolean startConnection = false;
synchronized (this)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
index 33585f9d05..efb39f39f8 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java
@@ -18,8 +18,10 @@ import java.net.SocketTimeoutException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.channels.UnresolvedAddressException;
+import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.AsyncEndPoint;
@@ -31,13 +33,15 @@ import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager;
import org.eclipse.jetty.io.nio.SslConnection;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.Timeout;
import org.eclipse.jetty.util.thread.Timeout.Task;
-class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
+class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector, Dumpable
{
private static final Logger LOG = Log.getLogger(SelectConnector.class);
@@ -69,6 +73,17 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
_selectorManager.stop();
}
+ public String dump()
+ {
+ return AggregateLifeCycle.dump(this);
+ }
+
+ public void dump(Appendable out, String indent) throws IOException
+ {
+ out.append(String.valueOf(this)).append("\n");
+ AggregateLifeCycle.dump(out, indent, Arrays.asList(_selectorManager));
+ }
+
/* ------------------------------------------------------------ */
public void startConnection( HttpDestination destination )
throws IOException
@@ -155,10 +170,8 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
// key should have destination at this point (will be replaced by endpoint after this call)
HttpDestination dest=(HttpDestination)key.attachment();
- AsyncEndPoint ep=null;
-
- SelectChannelEndPoint scep= new SelectChannelEndPoint(channel, selectSet, key, (int)_httpClient.getIdleTimeout());
- ep = scep;
+ SelectChannelEndPoint scep = new SelectChannelEndPoint(channel, selectSet, key, (int)_httpClient.getIdleTimeout());
+ AsyncEndPoint ep = scep;
if (dest.isSecure())
{
@@ -262,10 +275,10 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
public void upgrade()
{
- AsyncHttpConnection connection = (AsyncHttpConnection) ((SelectChannelEndPoint)_endp).getConnection();
+ AsyncHttpConnection connection = (AsyncHttpConnection)_endp.getConnection();
SslConnection sslConnection = new SslConnection(_engine,_endp);
- ((SelectChannelEndPoint)_endp).setConnection(sslConnection);
+ _endp.setConnection(sslConnection);
_endp=sslConnection.getSslEndPoint();
sslConnection.getSslEndPoint().setConnection(connection);
@@ -319,21 +332,11 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
_endp.close();
}
- public void scheduleIdle()
- {
- _endp.scheduleIdle();
- }
-
public int fill(Buffer buffer) throws IOException
{
return _endp.fill(buffer);
}
- public void cancelIdle()
- {
- _endp.cancelIdle();
- }
-
public boolean isWritable()
{
return _endp.isWritable();
@@ -434,9 +437,25 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
_endp.setMaxIdleTime(timeMs);
}
+ public void onIdleExpired()
+ {
+ _endp.onIdleExpired();
+ }
+
+ public void setCheckForIdle(boolean check)
+ {
+ _endp.setCheckForIdle(check);
+ }
+
+ public boolean isCheckForIdle()
+ {
+ return _endp.isCheckForIdle();
+ }
+
public String toString()
{
return "Upgradable:"+_endp.toString();
}
+
}
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java
index 0319e0b735..923d686766 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java
@@ -14,8 +14,11 @@
package org.eclipse.jetty.client;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.SocketTimeoutException;
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java
index 6e6e3e01e9..875e224594 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java
@@ -40,9 +40,9 @@ public class AsyncSslHttpExchangeTest extends SslHttpExchangeTest
@Override
- public void testGetWithContentExchange() throws Exception
+ public void testBigPostWithContentExchange() throws Exception
{
- super.testGetWithContentExchange();
+ super.testBigPostWithContentExchange();
}
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/Curl.java b/jetty-client/src/test/java/org/eclipse/jetty/client/Curl.java
index be0368b75c..6c4d510270 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/Curl.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/Curl.java
@@ -1,8 +1,6 @@
package org.eclipse.jetty.client;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java
index 178b88412f..c61f767e5c 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java
@@ -16,7 +16,6 @@ package org.eclipse.jetty.client;
import org.eclipse.jetty.client.helperClasses.ExternalKeyStoreAsyncSslServerAndClientCreator;
import org.eclipse.jetty.client.helperClasses.ServerAndClientCreator;
import org.junit.Before;
-import org.junit.Test;
public class ExternalKeyStoreAsyncSslHttpExchangeTest extends SslHttpExchangeTest
{
@@ -30,12 +29,4 @@ public class ExternalKeyStoreAsyncSslHttpExchangeTest extends SslHttpExchangeTes
_httpClient = serverAndClientCreator.createClient(3000L,3500L,2000);
_port = _server.getConnectors()[0].getLocalPort();
}
-
- @Override
- @Test
- public void testBigPostWithContentExchange() throws Exception
- {
- super.testBigPostWithContentExchange();
- }
-
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java
index dba5bc9732..d4fbf0fdd4 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java
@@ -38,7 +38,6 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.Connection;
-import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.nio.DirectNIOBuffer;
import org.eclipse.jetty.server.Server;
@@ -62,7 +61,7 @@ public class HttpExchangeTest
protected static HttpClient _httpClient;
protected static AtomicInteger _count = new AtomicInteger();
protected static ServerAndClientCreator serverAndClientCreator = new HttpServerAndClientCreator();
-
+
protected static URI getBaseURI()
{
return URI.create(_scheme + "://localhost:" + _port + "/");
@@ -123,7 +122,7 @@ public class HttpExchangeTest
/* ------------------------------------------------------------ */
/**
* Test sending data through the exchange.
- *
+ *
* @throws IOException
*/
public void sender(final int nb, final boolean close) throws Exception
@@ -262,12 +261,12 @@ public class HttpExchangeTest
_httpClient.send(httpExchange[n]);
}
-
+
if (!complete.await(2,TimeUnit.SECONDS))
System.err.println(_httpClient.dump());
-
+
assertTrue(complete.await(20,TimeUnit.SECONDS));
-
+
assertEquals("nb="+nb+" close="+close,0,allcontent.get());
}
@@ -301,7 +300,7 @@ public class HttpExchangeTest
httpExchange.setURI(uri);
httpExchange.setMethod(HttpMethods.GET);
_httpClient.send(httpExchange);
- int status = httpExchange.waitForDone();
+ int status = httpExchange.waitForDone();
//httpExchange.waitForStatus(HttpExchange.STATUS_COMPLETED);
String result=httpExchange.getResponseContent();
assertNotNull("Should have received response content", result);
@@ -311,7 +310,7 @@ public class HttpExchangeTest
Thread.sleep(5);
}
}
-
+
/* ------------------------------------------------------------ */
@Test
public void testLocalAddressAvailabilityWithContentExchange() throws Exception
@@ -324,9 +323,9 @@ public class HttpExchangeTest
httpExchange.setMethod(HttpMethods.GET);
_httpClient.send(httpExchange);
int status = httpExchange.waitForDone();
-
+
assertNotNull(httpExchange.getLocalAddress());
-
+
String result=httpExchange.getResponseContent();
assertNotNull("Should have received response content", result);
assertEquals("i="+i,0,result.indexOf("<hello>"));
@@ -335,13 +334,13 @@ public class HttpExchangeTest
Thread.sleep(5);
}
}
-
+
/* ------------------------------------------------------------ */
@Test
public void testShutdownWithExchange() throws Exception
{
final AtomicReference<Throwable> throwable=new AtomicReference<Throwable>();
-
+
HttpExchange httpExchange=new HttpExchange()
{
@@ -373,8 +372,8 @@ public class HttpExchangeTest
@Override
public void run()
{
- try {
- Thread.sleep(500);
+ try {
+ Thread.sleep(500);
_httpClient.stop();
} catch(Exception e) {e.printStackTrace();}
}
@@ -390,12 +389,12 @@ public class HttpExchangeTest
/* ------------------------------------------------------------ */
@Test
public void testBigPostWithContentExchange() throws Exception
- {
+ {
int size =32;
ContentExchange httpExchange=new ContentExchange()
{
int total;
-
+
@Override
protected synchronized void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
{
@@ -438,7 +437,7 @@ public class HttpExchangeTest
System.err.println("] --");
super.onResponseHeaderComplete();
}
-
+
};
Buffer babuf = new ByteArrayBuffer(size*36*1024);
@@ -451,13 +450,28 @@ public class HttpExchangeTest
babuf.put(bytes);
niobuf.put(bytes);
}
-
+
httpExchange.setURI(getBaseURI());
httpExchange.setMethod(HttpMethods.POST);
httpExchange.setRequestContentType("application/data");
httpExchange.setRequestContent(babuf);
-
_httpClient.send(httpExchange);
+
+ long start=System.currentTimeMillis();
+ while(!httpExchange.isDone())
+ {
+ long now=System.currentTimeMillis();
+ if ((now-start)>=10000)
+ {
+ System.err.println("TEST IS TAKING TOOOOO LONG!!!!!!!!!!!!!!!!!!!!");
+ System.err.println("CLIENT:");
+ System.err.println(_httpClient.dump());
+ System.err.println("SERVER:");
+ _server.dumpStdErr();
+ break;
+ }
+ Thread.sleep(100);
+ }
int status = httpExchange.waitForDone();
assertEquals(HttpExchange.STATUS_COMPLETED,status);
String result=httpExchange.getResponseContent();
@@ -469,6 +483,22 @@ public class HttpExchangeTest
httpExchange.setRequestContentType("application/data");
httpExchange.setRequestContent(niobuf);
_httpClient.send(httpExchange);
+
+ start=System.currentTimeMillis();
+ while(!httpExchange.isDone())
+ {
+ long now=System.currentTimeMillis();
+ if ((now-start)>=10000)
+ {
+ System.err.println("TEST IS TAKING TOOOOO LONG!!!!!!!!!!!!!!!!!!!!");
+ System.err.println("CLIENT:");
+ System.err.println(_httpClient.dump());
+ System.err.println("SERVER:");
+ _server.dumpStdErr();
+ break;
+ }
+ Thread.sleep(100);
+ }
status = httpExchange.waitForDone();
assertEquals(HttpExchange.STATUS_COMPLETED, status);
result=httpExchange.getResponseContent();
@@ -605,13 +635,13 @@ public class HttpExchangeTest
// reserving one should now work
c = destination.reserveConnection(500);
assertNotNull(c);
-
+
// release connections
for (AbstractHttpConnection httpConnection : connections){
destination.returnConnection(httpConnection,false);
}
}
-
+
@Test
public void testOptionsWithExchange() throws Exception
{
@@ -621,15 +651,15 @@ public class HttpExchangeTest
httpExchange.setMethod(HttpMethods.OPTIONS);
// httpExchange.setRequestHeader("Connection","close");
_httpClient.send(httpExchange);
-
+
int state = httpExchange.waitForDone();
assertEquals(HttpExchange.STATUS_COMPLETED, state);
assertEquals(HttpStatus.OK_200,httpExchange.getResponseStatus());
-
+
HttpFields headers = httpExchange.getResponseFields();
HttpAsserts.assertContainsHeaderKey("Content-Length", headers);
assertEquals("Content-Length header value", 0, headers.getLongField("Content-Length"));
-
+
HttpAsserts.assertContainsHeaderKey("Allow",headers);
String allow = headers.getStringField("Allow");
String expectedMethods[] =
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpsViaBrokenHttpProxyTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpsViaBrokenHttpProxyTest.java
index ce3b1b49d3..91d241f0b0 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpsViaBrokenHttpProxyTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpsViaBrokenHttpProxyTest.java
@@ -13,8 +13,11 @@
package org.eclipse.jetty.client;
+import static org.junit.Assert.assertEquals;
+
import java.io.IOException;
import java.net.ProtocolException;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -29,8 +32,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-
/* ------------------------------------------------------------ */
/**
* This UnitTest class executes two tests. Both will send a http request to https://google.com through a misbehaving proxy server.
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SluggishServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SluggishServerTest.java
index 1df4b292cd..65252038b7 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/SluggishServerTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SluggishServerTest.java
@@ -3,8 +3,6 @@ package org.eclipse.jetty.client;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
@@ -13,8 +11,6 @@ import javax.servlet.http.HttpServletResponse;
import junit.framework.Assert;
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.http.HttpHeaderValues;
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.io.Buffer;
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesClientTest.java
new file mode 100644
index 0000000000..a2f041b7d0
--- /dev/null
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesClientTest.java
@@ -0,0 +1,148 @@
+package org.eclipse.jetty.client;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SslBytesClientTest extends SslBytesTest
+{
+ private ExecutorService threadPool;
+ private HttpClient client;
+ private SimpleProxy proxy;
+ private SSLServerSocket acceptor;
+
+ @Before
+ public void init() throws Exception
+ {
+ threadPool = Executors.newCachedThreadPool();
+
+ client = new HttpClient();
+ client.setMaxConnectionsPerAddress(1);
+ client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
+ File keyStore = MavenTestingUtils.getTestResourceFile("keystore");
+ SslContextFactory cf = client.getSslContextFactory();
+ cf.setKeyStorePath(keyStore.getAbsolutePath());
+ cf.setKeyStorePassword("storepwd");
+ cf.setKeyManagerPassword("keypwd");
+ client.start();
+
+ SSLContext sslContext = cf.getSslContext();
+ acceptor = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(0);
+
+ int serverPort = acceptor.getLocalPort();
+
+ proxy = new SimpleProxy(threadPool, "localhost", serverPort);
+ proxy.start();
+ logger.debug(":{} <==> :{}", proxy.getPort(), serverPort);
+ }
+
+ @After
+ public void destroy() throws Exception
+ {
+ if (acceptor != null)
+ acceptor.close();
+ if (proxy != null)
+ proxy.stop();
+ if (client != null)
+ client.stop();
+ if (threadPool != null)
+ threadPool.shutdownNow();
+ }
+
+ @Test
+ public void testHandshake() throws Exception
+ {
+ ContentExchange exchange = new ContentExchange(true);
+ exchange.setURL("https://localhost:" + proxy.getPort());
+ String method = HttpMethods.GET;
+ exchange.setMethod(method);
+ client.send(exchange);
+ Assert.assertTrue(proxy.awaitClient(5, TimeUnit.SECONDS));
+
+ final SSLSocket server = (SSLSocket)acceptor.accept();
+ server.setUseClientMode(false);
+
+ Future<Object> handshake = threadPool.submit(new Callable<Object>()
+ {
+ public Object call() throws Exception
+ {
+ server.startHandshake();
+ return null;
+ }
+ });
+
+ // Client Hello
+ TLSRecord record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToServer(record);
+
+ // Server Hello + Certificate + Server Done
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToClient(record);
+
+ // Client Key Exchange
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToServer(record);
+
+ // Change Cipher Spec
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
+ proxy.flushToServer(record);
+
+ // Client Done
+ record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToServer(record);
+
+ // Change Cipher Spec
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.CHANGE_CIPHER_SPEC, record.getType());
+ proxy.flushToClient(record);
+
+ // Server Done
+ record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
+ proxy.flushToClient(record);
+
+ Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
+
+ SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
+ // Read request
+ BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream(), "UTF-8"));
+ String line = reader.readLine();
+ Assert.assertTrue(line.startsWith(method));
+ while (line.length() > 0)
+ line = reader.readLine();
+ // Write response
+ OutputStream output = server.getOutputStream();
+ output.write(("HTTP/1.1 200 OK\r\n" +
+ "Content-Length: 0\r\n" +
+ "\r\n").getBytes("UTF-8"));
+ output.flush();
+ Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
+
+ Assert.assertEquals(HttpExchange.STATUS_COMPLETED, exchange.waitForDone());
+ Assert.assertEquals(HttpStatus.OK_200, exchange.getResponseStatus());
+ }
+}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java
index 68e9f28018..f6b919ed64 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java
@@ -1,27 +1,25 @@
package org.eclipse.jetty.client;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.lessThan;
+
import java.io.BufferedReader;
-import java.io.EOFException;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.InterruptedIOException;
import java.io.OutputStream;
-import java.net.ServerSocket;
-import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSocket;
@@ -42,20 +40,16 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.After;
import org.junit.Assert;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
-import static org.hamcrest.Matchers.lessThan;
-
-public class SslBytesServerTest
+public class SslBytesServerTest extends SslBytesTest
{
- private final Logger logger = Log.getLogger(getClass());
private final AtomicInteger sslHandles = new AtomicInteger();
private final AtomicInteger httpParses = new AtomicInteger();
private ExecutorService threadPool;
@@ -64,7 +58,7 @@ public class SslBytesServerTest
private SimpleProxy proxy;
@Before
- public void startServer() throws Exception
+ public void init() throws Exception
{
threadPool = Executors.newCachedThreadPool();
server = new Server();
@@ -107,7 +101,8 @@ public class SslBytesServerTest
}
};
- connector.setPort(5870); // TODO: make this random
+// connector.setPort(5870);
+ connector.setPort(0);
File keyStore = MavenTestingUtils.getTestResourceFile("keystore");
SslContextFactory cf = connector.getSslContextFactory();
@@ -131,16 +126,17 @@ public class SslBytesServerTest
}
});
server.start();
+ int serverPort = connector.getLocalPort();
sslContext = cf.getSslContext();
- proxy = new SimpleProxy(threadPool, "localhost", connector.getLocalPort());
+ proxy = new SimpleProxy(threadPool, "localhost", serverPort);
proxy.start();
- logger.debug(":{} <==> :{}", proxy.getPort(), connector.getLocalPort());
+ logger.debug(":{} <==> :{}", proxy.getPort(), serverPort);
}
@After
- public void stopServer() throws Exception
+ public void destroy() throws Exception
{
if (proxy != null)
proxy.stop();
@@ -466,7 +462,7 @@ public class SslBytesServerTest
}
// Check that we did not spin
- Assert.assertThat(sslHandles.get(), lessThan(500));
+ Assert.assertThat(sslHandles.get(), lessThan(750));
Assert.assertThat(httpParses.get(), lessThan(150));
client.close();
@@ -867,7 +863,7 @@ public class SslBytesServerTest
// Check that we did not spin
Assert.assertThat(sslHandles.get(), lessThan(20));
- Assert.assertThat(httpParses.get(), lessThan(50));
+ Assert.assertThat(httpParses.get(), lessThan(150));
Assert.assertNull(request.get(5, TimeUnit.SECONDS));
@@ -887,7 +883,7 @@ public class SslBytesServerTest
// Check that we did not spin
Assert.assertThat(sslHandles.get(), lessThan(20));
- Assert.assertThat(httpParses.get(), lessThan(50));
+ Assert.assertThat(httpParses.get(), lessThan(150));
closeClient(client);
}
@@ -895,6 +891,8 @@ public class SslBytesServerTest
@Test
public void testRequestWithBigContentWithRenegotiationInMiddleOfContent() throws Exception
{
+ assumeJavaVersionSupportsTLSRenegotiations();
+
final SSLSocket client = newClient();
final OutputStream clientOutput = client.getOutputStream();
@@ -934,10 +932,12 @@ public class SslBytesServerTest
// Renegotiation Handshake
TLSRecord record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
// Renegotiation Handshake
record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Renegotiation Change Cipher
@@ -947,6 +947,7 @@ public class SslBytesServerTest
// Renegotiation Handshake
record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Trigger a read to have the client write the final renegotiation steps
@@ -968,6 +969,7 @@ public class SslBytesServerTest
// Renegotiation Handshake
record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToServer(record);
Assert.assertNull(renegotiation.get(5, TimeUnit.SECONDS));
@@ -1019,6 +1021,8 @@ public class SslBytesServerTest
@Test
public void testRequestWithBigContentWithRenegotiationInMiddleOfContentWithSplitBoundary() throws Exception
{
+ assumeJavaVersionSupportsTLSRenegotiations();
+
final SSLSocket client = newClient();
final OutputStream clientOutput = client.getOutputStream();
@@ -1058,6 +1062,7 @@ public class SslBytesServerTest
// Renegotiation Handshake
TLSRecord record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
byte[] bytes = record.getBytes();
byte[] chunk1 = new byte[2 * bytes.length / 3];
System.arraycopy(bytes, 0, chunk1, 0, chunk1.length);
@@ -1070,6 +1075,7 @@ public class SslBytesServerTest
// Renegotiation Handshake
record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Renegotiation Change Cipher
@@ -1079,6 +1085,7 @@ public class SslBytesServerTest
// Renegotiation Handshake
record = proxy.readFromServer();
+ Assert.assertEquals(TLSRecord.Type.HANDSHAKE, record.getType());
proxy.flushToClient(record);
// Trigger a read to have the client write the final renegotiation steps
@@ -1169,11 +1176,25 @@ public class SslBytesServerTest
// Check that we did not spin
Assert.assertThat(sslHandles.get(), lessThan(20));
- Assert.assertThat(httpParses.get(), lessThan(50));
+ Assert.assertThat(httpParses.get(), lessThan(100));
closeClient(client);
}
+ private void assumeJavaVersionSupportsTLSRenegotiations()
+ {
+ // Due to a security bug, TLS renegotiations were disabled in JDK 1.6.0_19-21
+ // so we check the java version in order to avoid to fail the test.
+ String javaVersion = System.getProperty("java.version");
+ Pattern regexp = Pattern.compile("1\\.6\\.0_(\\d{2})");
+ Matcher matcher = regexp.matcher(javaVersion);
+ if (matcher.matches())
+ {
+ String nano = matcher.group(1);
+ Assume.assumeThat(Integer.parseInt(nano), greaterThan(21));
+ }
+ }
+
private SSLSocket newClient() throws IOException, InterruptedException
{
SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket("localhost", proxy.getPort());
@@ -1203,314 +1224,4 @@ public class SslBytesServerTest
proxy.flushToClient(record);
}
- public class SimpleProxy implements Runnable
- {
- private final CountDownLatch latch = new CountDownLatch(1);
- private final ExecutorService threadPool;
- private final String serverHost;
- private final int serverPort;
- private volatile ServerSocket serverSocket;
- private volatile Socket server;
- private volatile Socket client;
-
- public SimpleProxy(ExecutorService threadPool, String serverHost, int serverPort)
- {
- this.threadPool = threadPool;
- this.serverHost = serverHost;
- this.serverPort = serverPort;
- }
-
- public void start() throws Exception
- {
- serverSocket = new ServerSocket(5871); // TODO: make this random
- Thread acceptor = new Thread(this);
- acceptor.start();
- server = new Socket(serverHost, serverPort);
- }
-
- public void stop() throws Exception
- {
- serverSocket.close();
- }
-
- public void run()
- {
- try
- {
- client = serverSocket.accept();
- latch.countDown();
- }
- catch (IOException x)
- {
- x.printStackTrace();
- }
- }
-
- public int getPort()
- {
- return serverSocket.getLocalPort();
- }
-
- public TLSRecord readFromClient() throws IOException
- {
- TLSRecord record = read(client);
- logger.debug("C --> P {}", record);
- return record;
- }
-
- private TLSRecord read(Socket socket) throws IOException
- {
- InputStream input = socket.getInputStream();
- int first = -2;
- while (true)
- {
- try
- {
- socket.setSoTimeout(500);
- first = input.read();
- break;
- }
- catch (SocketTimeoutException x)
- {
- if (Thread.currentThread().isInterrupted())
- break;
- }
- }
- if (first == -2)
- throw new InterruptedIOException();
- else if (first == -1)
- return null;
-
- if (first >= 0x80)
- {
- // SSLv2 Record
- int hiLength = first & 0x3F;
- int loLength = input.read();
- int length = (hiLength << 8) + loLength;
- byte[] bytes = new byte[2 + length];
- bytes[0] = (byte)first;
- bytes[1] = (byte)loLength;
- return read(TLSRecord.Type.HANDSHAKE, input, bytes, 2, length);
- }
- else
- {
- // TLS Record
- int major = input.read();
- int minor = input.read();
- int hiLength = input.read();
- int loLength = input.read();
- int length = (hiLength << 8) + loLength;
- byte[] bytes = new byte[1 + 2 + 2 + length];
- bytes[0] = (byte)first;
- bytes[1] = (byte)major;
- bytes[2] = (byte)minor;
- bytes[3] = (byte)hiLength;
- bytes[4] = (byte)loLength;
- return read(TLSRecord.Type.from(first), input, bytes, 5, length);
- }
- }
-
- private TLSRecord read(TLSRecord.Type type, InputStream input, byte[] bytes, int offset, int length) throws IOException
- {
- while (length > 0)
- {
- int read = input.read(bytes, offset, length);
- if (read < 0)
- throw new EOFException();
- offset += read;
- length -= read;
- }
- return new TLSRecord(type, bytes);
- }
-
- public void flushToServer(TLSRecord record) throws IOException
- {
- if (record == null)
- {
- server.shutdownOutput();
- if (client.isOutputShutdown())
- {
- client.close();
- server.close();
- }
- }
- else
- {
- flush(server, record.getBytes());
- }
- }
-
- public void flushToServer(byte... bytes) throws IOException
- {
- flush(server, bytes);
- }
-
- private void flush(Socket socket, byte... bytes) throws IOException
- {
- OutputStream output = socket.getOutputStream();
- output.write(bytes);
- output.flush();
- }
-
- public TLSRecord readFromServer() throws IOException
- {
- TLSRecord record = read(server);
- logger.debug("P <-- S {}", record);
- return record;
- }
-
- public void flushToClient(TLSRecord record) throws IOException
- {
- if (record == null)
- {
- client.shutdownOutput();
- if (server.isOutputShutdown())
- {
- server.close();
- client.close();
- }
- }
- else
- {
- flush(client, record.getBytes());
- }
- }
-
- public AutomaticFlow startAutomaticFlow() throws InterruptedException
- {
- final CountDownLatch startLatch = new CountDownLatch(2);
- final CountDownLatch stopLatch = new CountDownLatch(2);
- Future<Object> clientToServer = threadPool.submit(new Callable<Object>()
- {
- public Object call() throws Exception
- {
- startLatch.countDown();
- logger.debug("Automatic flow C --> S started");
- try
- {
- while (true)
- {
- flushToServer(readFromClient());
- }
- }
- catch (InterruptedIOException x)
- {
- return null;
- }
- finally
- {
- stopLatch.countDown();
- logger.debug("Automatic flow C --> S finished");
- }
- }
- });
- Future<Object> serverToClient = threadPool.submit(new Callable<Object>()
- {
- public Object call() throws Exception
- {
- startLatch.countDown();
- logger.debug("Automatic flow C <-- S started");
- try
- {
- while (true)
- {
- flushToClient(readFromServer());
- }
- }
- catch (InterruptedIOException x)
- {
- return null;
- }
- finally
- {
- stopLatch.countDown();
- logger.debug("Automatic flow C <-- S finished");
- }
- }
- });
- Assert.assertTrue(startLatch.await(5, TimeUnit.SECONDS));
- return new AutomaticFlow(stopLatch, clientToServer, serverToClient);
- }
-
- public boolean awaitClient(int time, TimeUnit unit) throws InterruptedException
- {
- return latch.await(time, unit);
- }
-
- public class AutomaticFlow
- {
- private final CountDownLatch stopLatch;
- private final Future<Object> clientToServer;
- private final Future<Object> serverToClient;
-
- public AutomaticFlow(CountDownLatch stopLatch, Future<Object> clientToServer, Future<Object> serverToClient)
- {
- this.stopLatch = stopLatch;
- this.clientToServer = clientToServer;
- this.serverToClient = serverToClient;
- }
-
- public boolean stop(long time, TimeUnit unit) throws InterruptedException
- {
- clientToServer.cancel(true);
- serverToClient.cancel(true);
- return stopLatch.await(time, unit);
- }
- }
- }
-
- public static class TLSRecord
- {
- private final Type type;
- private final byte[] bytes;
-
- public TLSRecord(Type type, byte[] bytes)
- {
- this.type = type;
- this.bytes = bytes;
- }
-
- public Type getType()
- {
- return type;
- }
-
- public byte[] getBytes()
- {
- return bytes;
- }
-
- @Override
- public String toString()
- {
- return "TLSRecord [" + type + "] " + bytes.length + " bytes";
- }
-
- public enum Type
- {
- CHANGE_CIPHER_SPEC(20), ALERT(21), HANDSHAKE(22), APPLICATION(23);
-
- private int code;
-
- private Type(int code)
- {
- this.code = code;
- Mapper.codes.put(this.code, this);
- }
-
- public static Type from(int code)
- {
- Type result = Mapper.codes.get(code);
- if (result == null)
- throw new IllegalArgumentException("Invalid TLSRecord.Type " + code);
- return result;
- }
-
- private static class Mapper
- {
- private static final Map<Integer, Type> codes = new HashMap<Integer, Type>();
- }
- }
- }
-
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesTest.java
new file mode 100644
index 0000000000..4ad5c68c56
--- /dev/null
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesTest.java
@@ -0,0 +1,337 @@
+package org.eclipse.jetty.client;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.junit.Assert;
+
+public abstract class SslBytesTest
+{
+ protected final Logger logger = Log.getLogger(getClass());
+
+ public static class TLSRecord
+ {
+ private final SslBytesServerTest.TLSRecord.Type type;
+ private final byte[] bytes;
+
+ public TLSRecord(SslBytesServerTest.TLSRecord.Type type, byte[] bytes)
+ {
+ this.type = type;
+ this.bytes = bytes;
+ }
+
+ public SslBytesServerTest.TLSRecord.Type getType()
+ {
+ return type;
+ }
+
+ public byte[] getBytes()
+ {
+ return bytes;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "TLSRecord [" + type + "] " + bytes.length + " bytes";
+ }
+
+ public enum Type
+ {
+ CHANGE_CIPHER_SPEC(20), ALERT(21), HANDSHAKE(22), APPLICATION(23);
+
+ private int code;
+
+ private Type(int code)
+ {
+ this.code = code;
+ SslBytesServerTest.TLSRecord.Type.Mapper.codes.put(this.code, this);
+ }
+
+ public static SslBytesServerTest.TLSRecord.Type from(int code)
+ {
+ SslBytesServerTest.TLSRecord.Type result = SslBytesServerTest.TLSRecord.Type.Mapper.codes.get(code);
+ if (result == null)
+ throw new IllegalArgumentException("Invalid TLSRecord.Type " + code);
+ return result;
+ }
+
+ private static class Mapper
+ {
+ private static final Map<Integer, SslBytesServerTest.TLSRecord.Type> codes = new HashMap<Integer, SslBytesServerTest.TLSRecord.Type>();
+ }
+ }
+ }
+
+ public class SimpleProxy implements Runnable
+ {
+ private final CountDownLatch latch = new CountDownLatch(1);
+ private final ExecutorService threadPool;
+ private final String serverHost;
+ private final int serverPort;
+ private volatile ServerSocket serverSocket;
+ private volatile Socket server;
+ private volatile Socket client;
+
+ public SimpleProxy(ExecutorService threadPool, String serverHost, int serverPort)
+ {
+ this.threadPool = threadPool;
+ this.serverHost = serverHost;
+ this.serverPort = serverPort;
+ }
+
+ public void start() throws Exception
+ {
+// serverSocket = new ServerSocket(5871);
+ serverSocket = new ServerSocket(0);
+ Thread acceptor = new Thread(this);
+ acceptor.start();
+ server = new Socket(serverHost, serverPort);
+ }
+
+ public void stop() throws Exception
+ {
+ serverSocket.close();
+ }
+
+ public void run()
+ {
+ try
+ {
+ client = serverSocket.accept();
+ latch.countDown();
+ }
+ catch (IOException x)
+ {
+ x.printStackTrace();
+ }
+ }
+
+ public int getPort()
+ {
+ return serverSocket.getLocalPort();
+ }
+
+ public TLSRecord readFromClient() throws IOException
+ {
+ TLSRecord record = read(client);
+ logger.debug("C --> P {}", record);
+ return record;
+ }
+
+ private TLSRecord read(Socket socket) throws IOException
+ {
+ InputStream input = socket.getInputStream();
+ int first = -2;
+ while (true)
+ {
+ try
+ {
+ socket.setSoTimeout(500);
+ first = input.read();
+ break;
+ }
+ catch (SocketTimeoutException x)
+ {
+ if (Thread.currentThread().isInterrupted())
+ break;
+ }
+ }
+ if (first == -2)
+ throw new InterruptedIOException();
+ else if (first == -1)
+ return null;
+
+ if (first >= 0x80)
+ {
+ // SSLv2 Record
+ int hiLength = first & 0x3F;
+ int loLength = input.read();
+ int length = (hiLength << 8) + loLength;
+ byte[] bytes = new byte[2 + length];
+ bytes[0] = (byte)first;
+ bytes[1] = (byte)loLength;
+ return read(TLSRecord.Type.HANDSHAKE, input, bytes, 2, length);
+ }
+ else
+ {
+ // TLS Record
+ int major = input.read();
+ int minor = input.read();
+ int hiLength = input.read();
+ int loLength = input.read();
+ int length = (hiLength << 8) + loLength;
+ byte[] bytes = new byte[1 + 2 + 2 + length];
+ bytes[0] = (byte)first;
+ bytes[1] = (byte)major;
+ bytes[2] = (byte)minor;
+ bytes[3] = (byte)hiLength;
+ bytes[4] = (byte)loLength;
+ return read(TLSRecord.Type.from(first), input, bytes, 5, length);
+ }
+ }
+
+ private TLSRecord read(SslBytesServerTest.TLSRecord.Type type, InputStream input, byte[] bytes, int offset, int length) throws IOException
+ {
+ while (length > 0)
+ {
+ int read = input.read(bytes, offset, length);
+ if (read < 0)
+ throw new EOFException();
+ offset += read;
+ length -= read;
+ }
+ return new TLSRecord(type, bytes);
+ }
+
+ public void flushToServer(TLSRecord record) throws IOException
+ {
+ if (record == null)
+ {
+ server.shutdownOutput();
+ if (client.isOutputShutdown())
+ {
+ client.close();
+ server.close();
+ }
+ }
+ else
+ {
+ flush(server, record.getBytes());
+ }
+ }
+
+ public void flushToServer(byte... bytes) throws IOException
+ {
+ flush(server, bytes);
+ }
+
+ private void flush(Socket socket, byte... bytes) throws IOException
+ {
+ OutputStream output = socket.getOutputStream();
+ output.write(bytes);
+ output.flush();
+ }
+
+ public TLSRecord readFromServer() throws IOException
+ {
+ TLSRecord record = read(server);
+ logger.debug("P <-- S {}", record);
+ return record;
+ }
+
+ public void flushToClient(TLSRecord record) throws IOException
+ {
+ if (record == null)
+ {
+ client.shutdownOutput();
+ if (server.isOutputShutdown())
+ {
+ server.close();
+ client.close();
+ }
+ }
+ else
+ {
+ flush(client, record.getBytes());
+ }
+ }
+
+ public SslBytesServerTest.SimpleProxy.AutomaticFlow startAutomaticFlow() throws InterruptedException
+ {
+ final CountDownLatch startLatch = new CountDownLatch(2);
+ final CountDownLatch stopLatch = new CountDownLatch(2);
+ Future<Object> clientToServer = threadPool.submit(new Callable<Object>()
+ {
+ public Object call() throws Exception
+ {
+ startLatch.countDown();
+ logger.debug("Automatic flow C --> S started");
+ try
+ {
+ while (true)
+ {
+ flushToServer(readFromClient());
+ }
+ }
+ catch (InterruptedIOException x)
+ {
+ return null;
+ }
+ finally
+ {
+ stopLatch.countDown();
+ logger.debug("Automatic flow C --> S finished");
+ }
+ }
+ });
+ Future<Object> serverToClient = threadPool.submit(new Callable<Object>()
+ {
+ public Object call() throws Exception
+ {
+ startLatch.countDown();
+ logger.debug("Automatic flow C <-- S started");
+ try
+ {
+ while (true)
+ {
+ flushToClient(readFromServer());
+ }
+ }
+ catch (InterruptedIOException x)
+ {
+ return null;
+ }
+ finally
+ {
+ stopLatch.countDown();
+ logger.debug("Automatic flow C <-- S finished");
+ }
+ }
+ });
+ Assert.assertTrue(startLatch.await(5, TimeUnit.SECONDS));
+ return new SslBytesServerTest.SimpleProxy.AutomaticFlow(stopLatch, clientToServer, serverToClient);
+ }
+
+ public boolean awaitClient(int time, TimeUnit unit) throws InterruptedException
+ {
+ return latch.await(time, unit);
+ }
+
+ public class AutomaticFlow
+ {
+ private final CountDownLatch stopLatch;
+ private final Future<Object> clientToServer;
+ private final Future<Object> serverToClient;
+
+ public AutomaticFlow(CountDownLatch stopLatch, Future<Object> clientToServer, Future<Object> serverToClient)
+ {
+ this.stopLatch = stopLatch;
+ this.clientToServer = clientToServer;
+ this.serverToClient = serverToClient;
+ }
+
+ public boolean stop(long time, TimeUnit unit) throws InterruptedException
+ {
+ clientToServer.cancel(true);
+ serverToClient.cancel(true);
+ return stopLatch.await(time, unit);
+ }
+ }
+ }
+}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java
index 766b118c18..2493a1b2f5 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java
@@ -19,8 +19,6 @@ import static org.hamcrest.Matchers.not;
import org.eclipse.jetty.client.helperClasses.ServerAndClientCreator;
import org.eclipse.jetty.client.helperClasses.SslServerAndClientCreator;
import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.toolchain.test.OS;
-import org.eclipse.jetty.toolchain.test.Stress;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/UnexpectedDataTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/UnexpectedDataTest.java
index f1c550a00b..74dd69d43d 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/UnexpectedDataTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/UnexpectedDataTest.java
@@ -20,6 +20,7 @@ import java.io.OutputStream;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AbstractSslServerAndClientCreator.java b/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AbstractSslServerAndClientCreator.java
index 4208eb6bab..f7d13cb4c7 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AbstractSslServerAndClientCreator.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AbstractSslServerAndClientCreator.java
@@ -16,7 +16,6 @@ package org.eclipse.jetty.client.helperClasses;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.log.Log;
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AsyncSslServerAndClientCreator.java b/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AsyncSslServerAndClientCreator.java
index 6e13cd44f1..b9627e47db 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AsyncSslServerAndClientCreator.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AsyncSslServerAndClientCreator.java
@@ -1,7 +1,5 @@
package org.eclipse.jetty.client.helperClasses;
-import java.io.FileInputStream;
-
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Jetty6Continuation.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Jetty6Continuation.java
index da0c080ea3..142b675ec2 100644
--- a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Jetty6Continuation.java
+++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Jetty6Continuation.java
@@ -23,7 +23,7 @@ public class Jetty6Continuation implements ContinuationFilter.FilteredContinuati
// Exception reused for all continuations
// Turn on debug in ContinuationFilter to see real stack trace.
private final static ContinuationThrowable __exception = new ContinuationThrowable();
-
+
private final ServletRequest _request;
private ServletResponse _response;
private final org.mortbay.util.ajax.Continuation _j6Continuation;
@@ -66,7 +66,7 @@ public class Jetty6Continuation implements ContinuationFilter.FilteredContinuati
_j6Continuation.resume();
}
}
-
+
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String)
@@ -233,8 +233,6 @@ public class Jetty6Continuation implements ContinuationFilter.FilteredContinuati
Throwable th=_retry;
_retry=null;
- if (th instanceof ThreadDeath)
- throw (ThreadDeath)th;
if (th instanceof Error)
throw (Error)th;
if (th instanceof RuntimeException)
@@ -245,7 +243,7 @@ public class Jetty6Continuation implements ContinuationFilter.FilteredContinuati
for (ContinuationListener l: _listeners)
l.onComplete(this);
}
-
+
return true;
}
}
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java
index 4e1348ad46..28c5ad13bd 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java
@@ -24,7 +24,7 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
*/
public class HttpBuffers extends AbstractLifeCycle
{
- private int _requestBufferSize=12*1024;
+ private int _requestBufferSize=16*1024;
private int _requestHeaderSize=6*1024;
private int _responseBufferSize=32*1024;
private int _responseHeaderSize=6*1024;
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
index a238ecf40d..89926a77ca 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
@@ -177,7 +177,7 @@ public class HttpGenerator extends AbstractGenerator
return;
}
_last = last;
-
+
// Handle any unfinished business?
if (_content!=null && _content.length()>0 || _bufferChunked)
{
@@ -829,7 +829,7 @@ public class HttpGenerator extends AbstractGenerator
{
try
{
-
+
if (_state == STATE_HEADER)
throw new IllegalStateException("State==HEADER");
@@ -851,7 +851,7 @@ public class HttpGenerator extends AbstractGenerator
int len = -1;
int to_flush = flushMask();
int last_flush;
-
+
do
{
last_flush=to_flush;
@@ -914,18 +914,18 @@ public class HttpGenerator extends AbstractGenerator
_state = STATE_END;
if (_state==STATE_END && _persistent != null && !_persistent && _status!=100 && _method==null)
- _endp.shutdownOutput();
+ _endp.shutdownOutput();
}
else
// Try to prepare more to write.
prepareBuffers();
}
-
- }
+
+ }
if (len > 0)
total+=len;
-
+
to_flush = flushMask();
}
// loop while progress is being made (OR we have prepared some buffers that might make progress)
@@ -939,15 +939,15 @@ public class HttpGenerator extends AbstractGenerator
throw (e instanceof EofException) ? e:new EofException(e);
}
}
-
+
/* ------------------------------------------------------------ */
- private int flushMask()
+ private int flushMask()
{
return ((_header != null && _header.length() > 0)?4:0)
| ((_buffer != null && _buffer.length() > 0)?2:0)
| ((_bypass && _content != null && _content.length() > 0)?1:0);
}
-
+
/* ------------------------------------------------------------ */
private void prepareBuffers()
{
@@ -962,7 +962,7 @@ public class HttpGenerator extends AbstractGenerator
if (_content.length() == 0)
_content = null;
}
-
+
// Chunk buffer if need be
if (_contentLength == HttpTokens.CHUNKED_CONTENT)
{
@@ -974,7 +974,7 @@ public class HttpGenerator extends AbstractGenerator
if (_header == null)
_header = _buffers.getHeader();
-
+
// if we need CRLF add this to header
if (_needCRLF)
{
@@ -985,7 +985,7 @@ public class HttpGenerator extends AbstractGenerator
// Add the chunk size to the header
BufferUtil.putHexInt(_header, size);
_header.put(HttpTokens.CRLF);
-
+
// Need a CRLF after the content
_needCRLF=true;
}
@@ -1018,7 +1018,7 @@ public class HttpGenerator extends AbstractGenerator
// No space so lets use a header buffer.
if (_header == null)
_header = _buffers.getHeader();
-
+
if (_needCRLF)
{
if (_header.length() > 0) throw new IllegalStateException("EOC");
@@ -1101,10 +1101,11 @@ public class HttpGenerator extends AbstractGenerator
@Override
public String toString()
{
- return "HttpGenerator{s="+_state+
- ",h="+(_header==null?"":_header.length())+
- ",b="+(_buffer==null?"":_buffer.length())+
- ",c="+(_content==null?"":_content.length())+
- "}";
+ return String.format("%s{s=%d,h=%d,b=%d,c=%d}",
+ getClass().getSimpleName(),
+ _state,
+ _header == null ? -1 : _header.length(),
+ _buffer == null ? -1 : _buffer.length(),
+ _content == null ? -1 : _content.length());
}
}
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 d27bf5913e..950d439036 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
@@ -14,8 +14,6 @@
package org.eclipse.jetty.http;
import java.io.IOException;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
@@ -82,7 +80,7 @@ public class HttpParser implements Parser
protected int _chunkLength;
protected int _chunkPosition;
private boolean _headResponse;
-
+
/* ------------------------------------------------------------------------------- */
/**
* Constructor.
@@ -233,7 +231,7 @@ public class HttpParser implements Parser
public boolean parseAvailable() throws IOException
{
boolean progress=parseNext()>0;
-
+
// continue parsing
while (!isComplete() && _buffer!=null && _buffer.length()>0)
{
@@ -249,7 +247,7 @@ public class HttpParser implements Parser
* @return an indication of progress <0 EOF, 0 no progress, >0 progress.
*/
public int parseNext() throws IOException
- {
+ {
try
{
int progress=0;
@@ -300,7 +298,7 @@ public class HttpParser implements Parser
if (filled > 0 )
progress++;
else if (filled < 0 )
- {
+ {
_persistent=false;
// do we have content to deliver?
@@ -330,7 +328,8 @@ public class HttpParser implements Parser
default:
_state=STATE_END;
- _handler.earlyEOF();
+ if (!_headResponse)
+ _handler.earlyEOF();
_handler.messageComplete(_contentPosition);
}
@@ -1136,7 +1135,11 @@ public class HttpParser implements Parser
@Override
public String toString()
{
- return "HttpParser{s=" + _state + ",l=" + _length + ",c=" + _contentLength+"}";
+ return String.format("%s{s=%d,l=%d,c=%d}",
+ getClass().getSimpleName(),
+ _state,
+ _length,
+ _contentLength);
}
/* ------------------------------------------------------------ */
@@ -1169,7 +1172,7 @@ public class HttpParser implements Parser
{
if (_contentView.length()>0)
return _contentView;
-
+
if (getState() <= STATE_END || isState(STATE_SEEKING_EOF))
return null;
@@ -1201,7 +1204,7 @@ public class HttpParser implements Parser
_endp.close();
throw e;
}
-
+
return _contentView.length()>0?_contentView:null;
}
@@ -1259,7 +1262,7 @@ public class HttpParser implements Parser
*/
public abstract void startResponse(Buffer version, int status, Buffer reason)
throws IOException;
-
+
public void earlyEOF()
{}
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
index 088102b9b6..a6004a9e10 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java
@@ -11,14 +11,14 @@ public abstract class AbstractConnection implements Connection
private static final Logger LOG = Log.getLogger(AbstractConnection.class);
private final long _timeStamp;
- protected final EndPoint _endp;
+ protected final EndPoint _endp;
public AbstractConnection(EndPoint endp)
{
_endp=(EndPoint)endp;
_timeStamp = System.currentTimeMillis();
}
-
+
public AbstractConnection(EndPoint endp,long timestamp)
{
_endp=(EndPoint)endp;
@@ -29,7 +29,7 @@ public abstract class AbstractConnection implements Connection
{
return _timeStamp;
}
-
+
public EndPoint getEndPoint()
{
return _endp;
@@ -39,7 +39,11 @@ public abstract class AbstractConnection implements Connection
{
try
{
- _endp.shutdownOutput();
+ LOG.debug("onIdleExpired {} {}",this,_endp);
+ if (_endp.isInputShutdown() || _endp.isOutputShutdown())
+ _endp.close();
+ else
+ _endp.shutdownOutput();
}
catch(IOException e)
{
@@ -52,13 +56,18 @@ public abstract class AbstractConnection implements Connection
catch(IOException e2)
{
LOG.ignore(e2);
-
}
}
}
-
+
public String toString()
{
- return this.getClass().getSimpleName()+"@"+_endp.getLocalAddr()+":"+_endp.getLocalPort()+"<->"+_endp.getRemoteAddr()+":"+_endp.getRemotePort();
+ return String.format("%s@%x//%s:%d<->%s:%d",
+ getClass().getSimpleName(),
+ hashCode(),
+ _endp.getLocalAddr(),
+ _endp.getLocalPort(),
+ _endp.getRemoteAddr(),
+ _endp.getRemotePort());
}
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java
index d11f1bc230..630fe1133a 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AsyncEndPoint.java
@@ -29,19 +29,27 @@ public interface AsyncEndPoint extends ConnectedEndPoint
* Set the endpoint to not be writable and schedule a dispatch when
* it becomes writable.
*/
- public void scheduleWrite();
-
+ public void scheduleWrite();
+
/* ------------------------------------------------------------ */
- /** Schedule a call to the idle timeout
+ /** Callback when idle.
+ * <p>An endpoint is idle if there has been no IO activity for
+ * {@link #getMaxIdleTime()} and {@link #isCheckForIdle()} is true.
*/
- public void scheduleIdle();
-
+ public void onIdleExpired();
+
/* ------------------------------------------------------------ */
- /** Cancel a call to the idle timeout
+ /** Set if the endpoint should be checked for idleness
*/
- public void cancelIdle();
+ public void setCheckForIdle(boolean check);
/* ------------------------------------------------------------ */
+ /** Get if the endpoint should be checked for idleness
+ */
+ public boolean isCheckForIdle();
+
+
+ /* ------------------------------------------------------------ */
public boolean isWritable();
/* ------------------------------------------------------------ */
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
index 7c9eb0719c..67fb8ab214 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
@@ -24,11 +24,6 @@ import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-/**
- *
- * To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
- */
public class SocketEndPoint extends StreamEndPoint
{
private static final Logger LOG = Log.getLogger(SocketEndPoint.class);
@@ -88,13 +83,13 @@ public class SocketEndPoint extends StreamEndPoint
/* ------------------------------------------------------------ */
@Override
public boolean isOutputShutdown()
- {
+ {
if (_socket instanceof SSLSocket)
return super.isOutputShutdown();
-
+
return _socket.isClosed() || _socket.isOutputShutdown();
}
-
+
/* ------------------------------------------------------------ */
/*
@@ -137,7 +132,7 @@ public class SocketEndPoint extends StreamEndPoint
_socket.close();
}
}
-
+
/* ------------------------------------------------------------ */
/*
* @see org.eclipse.jetty.io.bio.StreamEndPoint#shutdownOutput()
@@ -278,4 +273,9 @@ public class SocketEndPoint extends StreamEndPoint
}
}
+ @Override
+ public String toString()
+ {
+ return _local + " <--> " + _remote;
+ }
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
index a9e4c5fd1e..f4a0d527b9 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
@@ -43,8 +43,9 @@ public class ChannelEndPoint implements EndPoint
protected final Socket _socket;
protected final InetSocketAddress _local;
protected final InetSocketAddress _remote;
- protected int _maxIdleTime;
- private boolean _ishut;
+ protected volatile int _maxIdleTime;
+ private volatile boolean _ishut;
+ private volatile boolean _oshut;
public ChannelEndPoint(ByteChannel channel) throws IOException
{
@@ -109,34 +110,32 @@ public class ChannelEndPoint implements EndPoint
*/
protected final void shutdownChannelInput() throws IOException
{
- LOG.debug("ishut {}",this);
+ LOG.debug("ishut {}", this);
+ _ishut = true;
if (_channel.isOpen())
{
- if (_socket!=null)
+ if (_socket != null)
{
try
{
if (!_socket.isInputShutdown())
{
- // System.err.println("ISHUT "+_socket);
_socket.shutdownInput();
}
}
- catch(SocketException e)
- {
- // System.err.println(e);
+ catch (SocketException e)
+ {
LOG.debug(e.toString());
LOG.ignore(e);
}
finally
{
- _ishut=true;
- if(_socket.isOutputShutdown() && !_socket.isClosed())
+ if (_oshut)
+ {
close();
+ }
}
}
- else
- _ishut=true;
}
}
@@ -151,33 +150,31 @@ public class ChannelEndPoint implements EndPoint
protected final void shutdownChannelOutput() throws IOException
{
LOG.debug("oshut {}",this);
+ _oshut = true;
if (_channel.isOpen())
{
- if (_socket!=null)
+ if (_socket != null)
{
try
{
if (!_socket.isOutputShutdown())
{
- // System.err.println("OSHUT "+_socket);
_socket.shutdownOutput();
}
}
- catch(SocketException e)
+ catch (SocketException e)
{
LOG.debug(e.toString());
LOG.ignore(e);
- if (!_socket.isClosed())
- close();
}
finally
{
- if ((_ishut||_socket.isInputShutdown()) && !_socket.isClosed())
+ if (_ishut)
+ {
close();
+ }
}
}
- else
- close();
}
}
@@ -191,12 +188,12 @@ public class ChannelEndPoint implements EndPoint
public boolean isOutputShutdown()
{
- return !_channel.isOpen() || _socket!=null && _socket.isOutputShutdown();
+ return _oshut || !_channel.isOpen() || _socket != null && _socket.isOutputShutdown();
}
public boolean isInputShutdown()
{
- return !_channel.isOpen() || _ishut || _socket!=null && _socket.isInputShutdown();
+ return _ishut || !_channel.isOpen() || _socket != null && _socket.isInputShutdown();
}
/* (non-Javadoc)
@@ -205,8 +202,6 @@ public class ChannelEndPoint implements EndPoint
public void close() throws IOException
{
LOG.debug("close {}",this);
-
- // System.err.println("CLOSE "+_socket);
_channel.close();
}
@@ -359,7 +354,7 @@ public class ChannelEndPoint implements EndPoint
trailer!=null && trailer.length()>0)
length+=flush(trailer);
}
-
+
return length;
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
index bedc36ef84..cf69878278 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
@@ -36,7 +36,7 @@ import org.eclipse.jetty.util.thread.Timeout.Task;
public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPoint, ConnectedEndPoint
{
public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio");
-
+
private final SelectorManager.SelectSet _selectSet;
private final SelectorManager _manager;
private SelectionKey _key;
@@ -47,38 +47,38 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
/** The desired value for {@link SelectionKey#interestOps()} */
private int _interestOps;
-
+
/**
* The connection instance is the handler for any IO activity on the endpoint.
- * There is a different type of connection for HTTP, AJP, WebSocket and
- * ProxyConnect. The connection may change for an SCEP as it is upgraded
+ * There is a different type of connection for HTTP, AJP, WebSocket and
+ * ProxyConnect. The connection may change for an SCEP as it is upgraded
* from HTTP to proxy connect or websocket.
*/
private volatile AsyncConnection _connection;
-
+
/** true if a thread has been dispatched to handle this endpoint */
private boolean _dispatched = false;
-
+
/** true if a non IO dispatch (eg async resume) is outstanding */
private boolean _asyncDispatch = false;
-
+
/** true if the last write operation succeed and wrote all offered bytes */
private volatile boolean _writable = true;
-
+
/** True if a thread has is blocked in {@link #blockReadable(long)} */
private boolean _readBlocked;
/** True if a thread has is blocked in {@link #blockWritable(long)} */
private boolean _writeBlocked;
-
+
/** true if {@link SelectSet#destroyEndPoint(SelectChannelEndPoint)} has not been called */
private boolean _open;
-
+
private volatile long _idleTimestamp;
-
+
private boolean _ishut;
-
+
/* ------------------------------------------------------------ */
public SelectChannelEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key, int maxIdleTime)
throws IOException
@@ -92,9 +92,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
_open=true;
_key = key;
- scheduleIdle();
+ setCheckForIdle(true);
}
-
+
/* ------------------------------------------------------------ */
public SelectionKey getSelectionKey()
{
@@ -130,7 +130,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
return _idleTimestamp;
}
-
+
/* ------------------------------------------------------------ */
/** Called by selectSet to schedule handling
*
@@ -148,7 +148,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
return;
}
- // If there are threads dispatched reading and writing
+ // If there are threads dispatched reading and writing
if (_readBlocked || _writeBlocked)
{
// assert _dispatched;
@@ -199,7 +199,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
dispatch();
}
}
-
+
/* ------------------------------------------------------------ */
public void dispatch()
{
@@ -256,39 +256,59 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
getSelectSet().scheduleTimeout(task,timeoutMs);
}
+
+ /* ------------------------------------------------------------ */
+ public void setCheckForIdle(boolean check)
+ {
+ _idleTimestamp=check?System.currentTimeMillis():0;
+ }
/* ------------------------------------------------------------ */
- public void scheduleIdle()
+ public boolean isCheckForIdle()
{
- _idleTimestamp=System.currentTimeMillis();
+ return _idleTimestamp!=0;
}
-
+
/* ------------------------------------------------------------ */
- public void cancelIdle()
+ protected void notIdle()
{
- _idleTimestamp=0;
+ if (_idleTimestamp!=0)
+ _idleTimestamp=System.currentTimeMillis();
}
-
+
/* ------------------------------------------------------------ */
public void checkIdleTimestamp(long now)
{
long idleTimestamp=_idleTimestamp;
if (!getChannel().isOpen() || idleTimestamp!=0 && _maxIdleTime>0 && now>(idleTimestamp+_maxIdleTime))
- idleExpired();
+ {
+ onIdleExpired();
+ _idleTimestamp=now;
+ }
}
/* ------------------------------------------------------------ */
- protected void idleExpired()
+ public void onIdleExpired()
{
_connection.onIdleExpired();
}
-
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public int fill(Buffer buffer) throws IOException
+ {
+ int fill=super.fill(buffer);
+ if (fill>0)
+ notIdle();
+ return fill;
+ }
+
/* ------------------------------------------------------------ */
@Override
public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
{
int l = super.flush(header, buffer, trailer);
-
+
// If there was something to write and it wasn't written, then we are not writable.
if (l==0 && ( header!=null && header.hasContent() || buffer!=null && buffer.hasContent() || trailer!=null && trailer.hasContent()))
{
@@ -302,6 +322,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
else if (l>0)
{
_writable=true;
+ notIdle();
}
return l;
}
@@ -313,7 +334,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
public int flush(Buffer buffer) throws IOException
{
int l = super.flush(buffer);
-
+
// If there was something to write and it wasn't written, then we are not writable.
if (l==0 && buffer!=null && buffer.hasContent())
{
@@ -327,8 +348,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
else if (l>0)
{
_writable=true;
+ notIdle();
}
-
+
return l;
}
@@ -343,9 +365,11 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
if (isInputShutdown())
throw new EofException();
-
+
long now=_selectSet.getNow();
long end=now+timeoutMs;
+ boolean check=isCheckForIdle();
+ setCheckForIdle(true);
try
{
_readBlocked=true;
@@ -372,6 +396,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
finally
{
_readBlocked=false;
+ setCheckForIdle(check);
}
}
return true;
@@ -388,9 +413,11 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
if (isOutputShutdown())
throw new EofException();
-
+
long now=_selectSet.getNow();
long end=now+timeoutMs;
+ boolean check=isCheckForIdle();
+ setCheckForIdle(true);
try
{
_writeBlocked=true;
@@ -416,8 +443,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
finally
{
_writeBlocked=false;
- if (_idleTimestamp!=-1)
- scheduleIdle();
+ setCheckForIdle(check);
}
}
return true;
@@ -429,7 +455,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
_writable=false;
}
-
+
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.io.AsyncEndPoint#scheduleWrite()
@@ -438,11 +464,11 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
if (_writable==true)
LOG.debug("Required scheduleWrite {}",this);
-
+
_writable=false;
updateKey();
}
-
+
/* ------------------------------------------------------------ */
public boolean isWritable()
{
@@ -471,7 +497,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
boolean read_interest = _readBlocked || (!_dispatched && !_connection.isSuspended());
boolean write_interest= _writeBlocked || (!_dispatched && !_writable);
-
+
_interestOps =
((!_socket.isInputShutdown() && read_interest ) ? SelectionKey.OP_READ : 0)
| ((!_socket.isOutputShutdown()&& write_interest) ? SelectionKey.OP_WRITE : 0);
@@ -494,7 +520,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
_selectSet.wakeup();
}
}
-
+
/* ------------------------------------------------------------ */
/**
@@ -528,7 +554,6 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
_key.cancel();
}
- cancelIdle();
if (_open)
{
@@ -557,7 +582,6 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
if (_key!=null && _key.isValid())
_key.cancel();
- cancelIdle();
if (_open)
{
_open=false;
@@ -626,10 +650,6 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
_connection.onInputShutdown();
}
- catch (ThreadDeath e)
- {
- throw e;
- }
catch(Throwable x)
{
LOG.warn("onInputShutdown failed", x);
@@ -686,20 +706,21 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{
synchronized(this)
{
- return "SCEP@" + hashCode() +
- "{"+_socket.getRemoteSocketAddress()+"->"+_socket.getLocalSocketAddress()+
- (_dispatched?",D":"") +
- (isOpen()?",open":"") +
- (isInputShutdown()?",ishut":"") +
- (isOutputShutdown()?",oshut":"") +
- (_readBlocked?",RB":"") +
- (_writeBlocked?",WB":"") +
- (_writable?"":",!W") +
- ","+_interestOps +
- ((_key==null || !_key.isValid())?"!":(
- (_key.isReadable()?"R":"")+
- (_key.isWritable()?"W":"")))+
- "}";
+ return String.format("SCEP@%x{%s->%s,d=%b,open=%b,ishut=%b,oshut=%b,rb=%b,wb=%b,w=%b,i=%d%s%s%s}",
+ hashCode(),
+ _socket.getRemoteSocketAddress(),
+ _socket.getLocalSocketAddress(),
+ _dispatched,
+ isOpen(),
+ isInputShutdown(),
+ isOutputShutdown(),
+ _readBlocked,
+ _writeBlocked,
+ _writable,
+ _interestOps,
+ _key != null && _key.isValid() ? "" : "!",
+ _key != null && _key.isValid() && _key.isReadable() ? "r" : "",
+ _key != null && _key.isValid() && _key.isWritable() ? "w" : "");
}
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
index 8c6db52fb6..eaeabc8862 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java
@@ -283,10 +283,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
set.doSelect();
}
- catch(ThreadDeath e)
- {
- throw e;
- }
catch(IOException e)
{
LOG.ignore(e);
@@ -444,7 +440,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
// Stopped concurrently ?
if (selector == null)
return;
-
+
// Make any key changes required
Object change;
int changes=_changes.size();
@@ -507,10 +503,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
LOG.ignore(e);
}
- catch (ThreadDeath e)
- {
- throw e;
- }
catch (Throwable e)
{
if (isRunning())
@@ -578,7 +570,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
// Start injecting pauses
_pausing=true;
-
+
// if this is the first pause
if (!_paused)
{
@@ -715,16 +707,16 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
}
public String toString() {return "Idle-"+super.toString();}
});
-
+
}
-
+
// Reset busy select monitor counts
if (__MONITOR_PERIOD>0 && now>_monitorNext)
{
_busySelects=0;
_pausing=false;
_monitorNext=now+__MONITOR_PERIOD;
-
+
}
}
catch (ClosedSelectorException e)
@@ -977,20 +969,21 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
for (SelectionKey key: selector.keys())
{
if (key.isValid())
- dumpto.add(key.attachment()+" "+key.interestOps()+" "+key.readyOps());
+ dumpto.add(key.attachment()+" iOps="+key.interestOps()+" rOps="+key.readyOps());
else
- dumpto.add(key.attachment()+" - - ");
+ dumpto.add(key.attachment()+" iOps=-1 rOps=-1");
}
}
/* ------------------------------------------------------------ */
public String toString()
{
- String s=super.toString()+" "+SelectorManager.this.getState();
Selector selector=_selector;
- if (selector!=null && selector.isOpen())
- s+=",k="+selector.keys().size()+",s="+selector.selectedKeys().size();
- return s;
+ return String.format("%s %s keys=%d selected=%d",
+ super.toString(),
+ SelectorManager.this.getState(),
+ selector != null && selector.isOpen() ? selector.keys().size() : -1,
+ selector != null && selector.isOpen() ? selector.selectedKeys().size() : -1);
}
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java
index a27f2d45a3..9bda79b919 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java
@@ -16,6 +16,7 @@ package org.eclipse.jetty.io.nio;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
+
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
@@ -178,7 +179,9 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
// If we are handshook let the delegate connection
if (_engine.getHandshakeStatus()!=HandshakeStatus.NOT_HANDSHAKING)
- progress|=process(null,null);
+ {
+ progress=process(null,null);
+ }
else
{
// handle the delegate connection
@@ -204,10 +207,6 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
{
_connection.onInputShutdown();
}
- catch (ThreadDeath e)
- {
- throw e;
- }
catch(Throwable x)
{
LOG.warn("onInputShutdown failed", x);
@@ -251,7 +250,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
super.onIdleExpired();
}
}
-
+
/* ------------------------------------------------------------ */
public void onInputShutdown() throws IOException
{
@@ -393,7 +392,8 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
finally
{
releaseBuffers();
- _progressed.set(some_progress);
+ if (some_progress)
+ _progressed.set(true);
}
return some_progress;
}
@@ -586,11 +586,6 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
return _engine;
}
- public SslConnection getSslConnection()
- {
- return SslConnection.this;
- }
-
public void shutdownOutput() throws IOException
{
synchronized (SslConnection.this)
@@ -647,10 +642,9 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
public int flush(Buffer buffer) throws IOException
{
- int size=buffer.length();
- process(null,buffer);
- int flushed=size-buffer.length();
- return flushed;
+ int size = buffer.length();
+ process(null, buffer);
+ return size-buffer.length();
}
public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
@@ -710,14 +704,19 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
_aEndp.scheduleWrite();
}
- public void scheduleIdle()
+ public void onIdleExpired()
+ {
+ _aEndp.onIdleExpired();
+ }
+
+ public void setCheckForIdle(boolean check)
{
- _aEndp.scheduleIdle();
+ _aEndp.setCheckForIdle(check);
}
- public void cancelIdle()
+ public boolean isCheckForIdle()
{
- _aEndp.cancelIdle();
+ return _aEndp.isCheckForIdle();
}
public void scheduleTimeout(Task task, long timeoutMs)
@@ -797,20 +796,20 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
public String toString()
{
- Buffer i;
- Buffer o;
- Buffer u;
-
+ int i;
+ int o;
+ int u;
synchronized(SslConnection.this)
{
- i=_inbound;
- o=_outbound;
- u=_unwrapBuf;
+ i=_inbound==null?-1:_inbound.length();
+ o=_outbound==null?-1:_outbound.length();
+ u=_unwrapBuf==null?-1:_unwrapBuf.length();
}
- return "SSL:"+_endp+" "+_engine.getHandshakeStatus()+" i/u/o="+(i==null?0:i.length())+"/"+(u==null?0:u.length())+"/"+(o==null?0:o.length()+(_ishut?" ishut":"")+(_oshut?" oshut":""));
+ return String.format("SSL:%s %s i/u/o=%d/%d/%d ishut=%b oshut=%b",
+ _endp,
+ _engine.getHandshakeStatus(),
+ i, u, o,
+ _ishut, _oshut);
}
-
}
-
-
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java
index 699ea8a722..8575ab7f22 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java
@@ -27,7 +27,6 @@ import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import org.eclipse.jetty.util.IO;
-import org.junit.Assert;
import org.junit.Test;
/**
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/ChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/ChannelEndPointTest.java
index 7a1c5a07c6..1d8d5b2c7e 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/ChannelEndPointTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/ChannelEndPointTest.java
@@ -6,7 +6,6 @@ import java.nio.channels.SocketChannel;
import org.eclipse.jetty.io.EndPointTest;
import org.junit.AfterClass;
import org.junit.BeforeClass;
-import org.junit.Test;
public class ChannelEndPointTest extends EndPointTest<ChannelEndPoint>
{
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/NIOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/NIOTest.java
new file mode 100644
index 0000000000..9366d8ce84
--- /dev/null
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/NIOTest.java
@@ -0,0 +1,131 @@
+// ========================================================================
+// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.io.nio;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+
+import org.junit.Test;
+
+/**
+ *
+ */
+public class NIOTest
+{
+ @Test
+ public void testSelector() throws Exception
+ {
+ ServerSocket acceptor = new ServerSocket(0);
+
+ Selector selector = Selector.open();
+
+ // Create client server socket pair
+ SocketChannel client = SocketChannel.open(acceptor.getLocalSocketAddress());
+ Socket server = acceptor.accept();
+ server.setTcpNoDelay(true);
+
+ // Make the client non blocking and register it with selector for reads
+ client.configureBlocking(false);
+ SelectionKey key = client.register(selector,SelectionKey.OP_READ);
+
+ // assert it is not selected
+ assertTrue(key.isValid());
+ assertFalse(key.isReadable());
+ assertEquals(0,key.readyOps());
+
+ // try selecting and assert nothing selected
+ int selected = selector.selectNow();
+ assertEquals(0,selected);
+ assertEquals(0,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertFalse(key.isReadable());
+ assertEquals(0,key.readyOps());
+
+ // Write a byte from server to client
+ server.getOutputStream().write(42);
+ server.getOutputStream().flush();
+
+ // select again and assert selection found for read
+ selected = selector.select(1000);
+ assertEquals(1,selected);
+ assertEquals(1,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // select again and see that it is not reselect, but stays selected
+ selected = selector.select(100);
+ assertEquals(0,selected);
+ assertEquals(1,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // read the byte
+ ByteBuffer buf = ByteBuffer.allocate(1024);
+ int len=client.read(buf);
+ assertEquals(1,len);
+ buf.flip();
+ assertEquals(42,buf.get());
+ buf.clear();
+
+ // But this does not change the key
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // Even if we select again ?
+ selected = selector.select(100);
+ assertEquals(0,selected);
+ assertEquals(1,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // Unless we remove the key from the select set
+ // and then it is still flagged as isReadable()
+ selector.selectedKeys().clear();
+ assertEquals(0,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // Now if we select again - it is still flagged as readable!!!
+ selected = selector.select(100);
+ assertEquals(0,selected);
+ assertEquals(0,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isReadable());
+ assertEquals(1,key.readyOps());
+
+ // Only when it is selected for something else does that state change.
+ key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE);
+ selected = selector.select(1000);
+ assertEquals(1,selected);
+ assertEquals(1,selector.selectedKeys().size());
+ assertTrue(key.isValid());
+ assertTrue(key.isWritable());
+ assertFalse(key.isReadable());
+ assertEquals(SelectionKey.OP_WRITE,key.readyOps());
+ }
+
+}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointSslTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointSslTest.java
index dad39ac900..d6a6a46a06 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointSslTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointSslTest.java
@@ -8,8 +8,8 @@ import java.nio.channels.SocketChannel;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLSocket;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java
index d35d62d843..5190935ea3 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/nio/SelectChannelEndPointTest.java
@@ -1,5 +1,10 @@
package org.eclipse.jetty.io.nio;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -22,12 +27,9 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import static org.hamcrest.Matchers.greaterThanOrEqualTo;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
public class SelectChannelEndPointTest
{
+ protected SelectChannelEndPoint _lastEndp;
protected ServerSocketChannel _connector;
protected QueuedThreadPool _threadPool = new QueuedThreadPool();
protected SelectorManager _manager = new SelectorManager()
@@ -64,6 +66,7 @@ public class SelectChannelEndPointTest
{
SelectChannelEndPoint endp = new SelectChannelEndPoint(channel,selectSet,key,2000);
endp.setConnection(selectSet.getManager().newConnection(channel,endp, key.attachment()));
+ _lastEndp=endp;
return endp;
}
};
@@ -116,10 +119,7 @@ public class SelectChannelEndPointTest
progress=false;
_in.compact();
if (_in.space()>0 && _endp.fill(_in)>0)
- {
progress=true;
- ((AsyncEndPoint)_endp).cancelIdle();
- }
while (_blockAt>0 && _in.length()>0 && _in.length()<_blockAt)
{
@@ -210,7 +210,7 @@ public class SelectChannelEndPointTest
assertEquals(c,(char)b);
}
client.close();
-
+
int i=0;
while (server.isOpen())
{
@@ -325,6 +325,54 @@ public class SelectChannelEndPointTest
assertEquals(c,(char)b);
}
}
+
+ @Test
+ public void testIdle() throws Exception
+ {
+ Socket client = newClient();
+
+ client.setSoTimeout(3000);
+
+ SocketChannel server = _connector.accept();
+ server.configureBlocking(false);
+
+ _manager.register(server);
+
+ // Write client to server
+ client.getOutputStream().write("HelloWorld".getBytes("UTF-8"));
+
+ // Verify echo server to client
+ for (char c : "HelloWorld".toCharArray())
+ {
+ int b = client.getInputStream().read();
+ assertTrue(b>0);
+ assertEquals(c,(char)b);
+ }
+
+ // Set Max idle
+ _lastEndp.setMaxIdleTime(500);
+
+ // read until idle shutdown received
+ long start=System.currentTimeMillis();
+ int b=client.getInputStream().read();
+ assertEquals(-1,b);
+ long idle=System.currentTimeMillis()-start;
+ assertTrue(idle>400);
+ assertTrue(idle<2000);
+
+ // But endpoint is still open.
+ assertTrue(_lastEndp.isOpen());
+
+
+ // Wait for another idle callback
+ Thread.sleep(1000);
+ // endpoint is closed.
+
+ assertFalse(_lastEndp.isOpen());
+
+ }
+
+
@Test
public void testStress() throws Exception
@@ -338,8 +386,12 @@ public class SelectChannelEndPointTest
_manager.register(server);
int writes = 100000;
+ final byte[] bytes="HelloWorld".getBytes("UTF-8");
final CountDownLatch latch = new CountDownLatch(writes);
final InputStream in = new BufferedInputStream(client.getInputStream());
+ final long start = System.currentTimeMillis();
+ client.getOutputStream().write(bytes);
+ client.getOutputStream().flush();
new Thread()
{
@@ -350,29 +402,33 @@ public class SelectChannelEndPointTest
while (latch.getCount()>0)
{
// Verify echo server to client
- for (char c : "HelloWorld".toCharArray())
+ for (byte b0 : bytes)
{
int b = in.read();
assertTrue(b>0);
- assertEquals(c,(char)b);
+ assertEquals(0xff&b0,b);
}
latch.countDown();
}
}
- catch(Exception e)
+ catch(Throwable e)
{
+ System.err.println("latch="+latch.getCount());
+ System.err.println("time="+(System.currentTimeMillis()-start));
e.printStackTrace();
}
}
}.start();
- byte[] bytes="HelloWorld".getBytes("UTF-8");
// Write client to server
- for (int i=0;i<writes;i++)
+ for (int i=1;i<writes;i++)
+ {
client.getOutputStream().write(bytes);
+ Thread.yield();
+ }
+ client.getOutputStream().flush();
assertTrue(latch.await(100,TimeUnit.SECONDS));
-
}
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
index 3b427e8826..44280872b4 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
@@ -25,8 +25,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import org.eclipse.jetty.http.PathMap;
-import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.UserIdentity;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java
index 38b486560e..c21768fde1 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java
@@ -32,9 +32,9 @@ import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.security.ServerAuthException;
import org.eclipse.jetty.security.UserAuthentication;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.Authentication.User;
-import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.MultiMap;
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 3efa01fd43..6f349ca4f8 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
@@ -48,8 +48,8 @@ import org.eclipse.jetty.util.thread.ThreadPool;
* <li>Base acceptor thread</li>
* <li>Optional reverse proxy headers checking</li>
* </ul>
- *
- *
+ *
+ *
*/
public abstract class AbstractConnector extends HttpBuffers implements Connector, Dumpable
{
@@ -181,7 +181,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
* <p>
* Previously, Jetty supported separate idle timeouts and IO operation timeouts, however the expense of changing the value of soTimeout was significant, so
* these timeouts were merged. With the advent of NIO, it may be possible to again differentiate these values (if there is demand).
- *
+ *
* @param maxIdleTime
* The maxIdleTime to set.
*/
@@ -414,13 +414,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
request.setScheme(HttpSchemes.HTTPS);
}
}
-
+
// Retrieving headers from the request
String forwardedHost = getLeftMostFieldValue(httpFields,getForwardedHostHeader());
String forwardedServer = getLeftMostFieldValue(httpFields,getForwardedServerHeader());
String forwardedFor = getLeftMostFieldValue(httpFields,getForwardedForHeader());
String forwardedProto = getLeftMostFieldValue(httpFields,getForwardedProtoHeader());
-
+
if (_hostHeader != null)
{
// Update host header
@@ -462,7 +462,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
request.setRemoteHost(inetAddress == null?forwardedFor:inetAddress.getHostName());
}
-
+
if (forwardedProto != null)
{
request.setScheme(forwardedProto);
@@ -615,7 +615,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/**
* Is reverse proxy handling on?
- *
+ *
* @return true if this connector is checking the x-forwarded-for/host/server headers
*/
public boolean isForwarded()
@@ -627,7 +627,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/**
* Set reverse proxy handling. If set to true, then the X-Forwarded headers (or the headers set in their place) are looked for to set the request protocol,
* host, server and client ip.
- *
+ *
* @param check
* true if this connector is checking the x-forwarded-for/host/server headers
* @set {@link #setForwardedForHeader(String)}
@@ -652,7 +652,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/**
* Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
* This value is only used if {@link #isForwarded()} is true.
- *
+ *
* @param hostHeader
* The value of the host header to force.
*/
@@ -663,7 +663,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/*
- *
+ *
* @see #setForwarded(boolean)
*/
public String getForwardedHostHeader()
@@ -726,7 +726,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/**
* Get the forwardedProtoHeader.
- *
+ *
* @return the forwardedProtoHeader (default X-Forwarded-For)
* @see #setForwarded(boolean)
*/
@@ -738,7 +738,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */
/**
* Set the forwardedProtoHeader.
- *
+ *
* @param forwardedProtoHeader
* the forwardedProtoHeader to set (default X-Forwarded-For)
* @see #setForwarded(boolean)
@@ -849,10 +849,6 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
// Connector has been stopped
LOG.ignore(x);
}
- catch (ThreadDeath e)
- {
- throw e;
- }
catch (Throwable e)
{
LOG.warn(e);
@@ -1075,7 +1071,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/**
* Set the priority offset of the acceptor threads. The priority is adjusted by this amount (default 0) to either favour the acceptance of new threads and
* newly active connections or to favour the handling of already dispatched connections.
- *
+ *
* @param offset
* the amount to alter the priority of the acceptor threads.
*/
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java
index 68a6aacc57..26db3ab9d8 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java
@@ -39,7 +39,6 @@ import org.eclipse.jetty.http.HttpVersions;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.http.Parser;
import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.io.Buffers;
@@ -56,7 +55,6 @@ import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.util.thread.Timeout;
/**
* <p>A HttpConnection represents the connection of a HTTP client to the server
@@ -371,24 +369,6 @@ public abstract class AbstractHttpConnection extends AbstractConnection
}
/* ------------------------------------------------------------ */
- /**
- * @deprecated
- */
- public final void scheduleTimeout(Timeout.Task task, long timeoutMs)
- {
- throw new UnsupportedOperationException();
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @deprecated
- */
- public final void cancelTimeout(Timeout.Task task)
- {
- throw new UnsupportedOperationException();
- }
-
- /* ------------------------------------------------------------ */
public void reset()
{
_parser.reset();
@@ -481,10 +461,6 @@ public abstract class AbstractHttpConnection extends AbstractConnection
_request.setHandled(true);
_response.sendError(e.getStatus(), e.getReason());
}
- catch (ThreadDeath e)
- {
- throw e;
- }
catch (Throwable e)
{
async_exception=e;
@@ -704,7 +680,11 @@ public abstract class AbstractHttpConnection extends AbstractConnection
/* ------------------------------------------------------------ */
public String toString()
{
- return super.toString()+" "+_parser+" "+_generator+" "+_requests;
+ return String.format("%s,g=%s,p=%s,r=%d",
+ super.toString(),
+ _generator,
+ _parser,
+ _requests);
}
/* ------------------------------------------------------------ */
@@ -850,8 +830,6 @@ public abstract class AbstractHttpConnection extends AbstractConnection
@Override
public void headerComplete() throws IOException
{
- if (_endp instanceof AsyncEndPoint)
- ((AsyncEndPoint)_endp).scheduleIdle();
_requests++;
_generator.setVersion(_version);
switch (_version)
@@ -927,8 +905,6 @@ public abstract class AbstractHttpConnection extends AbstractConnection
@Override
public void content(Buffer ref) throws IOException
{
- if (_endp instanceof AsyncEndPoint)
- ((AsyncEndPoint)_endp).scheduleIdle();
if (_delayedHandling)
{
_delayedHandling=false;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java
index 203af125d9..9d79c6cd78 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncHttpConnection.java
@@ -79,7 +79,6 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
// Has any IO been done by the endpoint itself since last loop
if (_asyncEndp.hasProgressed())
progress=true;
-
}
catch (HttpException e)
{
@@ -122,6 +121,7 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
{
// The request is suspended, so even though progress has been made, break the while loop
LOG.debug("suspended {}",this);
+ // TODO: breaking inside finally blocks is bad: rethink how we should exit from here
break;
}
}
@@ -131,11 +131,11 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async
{
setCurrentConnection(null);
if (!_request.isAsyncStarted())
- {
+ {
_parser.returnBuffers();
_generator.returnBuffers();
}
-
+
// Safety net to catch spinning
if (some_progress)
_total_no_progress=0;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/BlockingHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/BlockingHttpConnection.java
index 20797d9a62..ec15289f91 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/BlockingHttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/BlockingHttpConnection.java
@@ -31,32 +31,26 @@ public class BlockingHttpConnection extends AbstractHttpConnection
{
private static final Logger LOG = Log.getLogger(BlockingHttpConnection.class);
- private volatile boolean _handling;
-
public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server)
{
super(connector,endpoint,server);
}
-
public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server, Parser parser, Generator generator, Request request)
{
super(connector,endpoint,server,parser,generator,request);
}
-
@Override
protected void handleRequest() throws IOException
{
super.handleRequest();
}
-
public Connection handle() throws IOException
{
Connection connection = this;
- boolean progress=true;
try
{
setCurrentConnection(this);
@@ -67,17 +61,16 @@ public class BlockingHttpConnection extends AbstractHttpConnection
{
try
{
- progress=false;
// If we are not ended then parse available
if (!_parser.isComplete() && !_endp.isInputShutdown())
- progress |= _parser.parseAvailable();
+ _parser.parseAvailable();
// Do we have more generating to do?
// Loop here because some writes may take multiple steps and
// we need to flush them all before potentially blocking in the
// next loop.
if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown())
- progress |= _generator.flushBuffer()>0;
+ _generator.flushBuffer();
// Flush buffers
_endp.flush();
@@ -100,9 +93,7 @@ public class BlockingHttpConnection extends AbstractHttpConnection
if (_parser.isComplete() && _generator.isComplete())
{
// Reset the parser/generator
- progress=true;
reset();
- _endp.flush();
// look for a switched connection instance?
if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
@@ -121,6 +112,8 @@ public class BlockingHttpConnection extends AbstractHttpConnection
}
}
}
+
+ return connection;
}
finally
{
@@ -128,7 +121,5 @@ public class BlockingHttpConnection extends AbstractHttpConnection
_parser.returnBuffers();
_generator.returnBuffers();
}
- return connection;
}
-
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
index 7af4953dcb..a29f4bf730 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
@@ -54,6 +54,7 @@ public class Response implements HttpServletResponse
{
private static final Logger LOG = Log.getLogger(Response.class);
+
public static final int
NONE=0,
STREAM=1,
@@ -66,6 +67,12 @@ public class Response implements HttpServletResponse
*/
public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include.";
+ /**
+ * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie
+ * will be set as HTTP ONLY.
+ */
+ public final static String HTTP_ONLY_COMMENT="__HTTP_ONLY__";
+
private final AbstractHttpConnection _connection;
private int _status=SC_OK;
private String _reason;
@@ -121,14 +128,28 @@ public class Response implements HttpServletResponse
*/
public void addCookie(Cookie cookie)
{
+ String comment=cookie.getComment();
+ boolean http_only=false;
+
+ if (comment!=null)
+ {
+ int i=comment.indexOf(HTTP_ONLY_COMMENT);
+ if (i>=0)
+ {
+ http_only=true;
+ comment=comment.substring(i,i+HTTP_ONLY_COMMENT.length()).trim();
+ if (comment.length()==0)
+ comment=null;
+ }
+ }
_connection.getResponseFields().addSetCookie(cookie.getName(),
cookie.getValue(),
cookie.getDomain(),
cookie.getPath(),
cookie.getMaxAge(),
- cookie.getComment(),
+ comment,
cookie.getSecure(),
- cookie.isHttpOnly(),
+ http_only || cookie.isHttpOnly(),
cookie.getVersion());
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java
index 5066606567..28efa1bef7 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/bio/SocketConnector.java
@@ -19,7 +19,6 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.Set;
import org.eclipse.jetty.http.HttpException;
@@ -30,9 +29,10 @@ import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.bio.SocketEndPoint;
import org.eclipse.jetty.server.AbstractConnector;
-import org.eclipse.jetty.server.BlockingHttpConnection;
import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.BlockingHttpConnection;
import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -156,21 +156,30 @@ public class SocketConnector extends AbstractConnector
protected void doStop() throws Exception
{
super.doStop();
- Set set=null;
-
+ Set<EndPoint> set = new HashSet<EndPoint>();
synchronized(_connections)
{
- set= new HashSet(_connections);
+ set.addAll(_connections);
}
-
- Iterator iter=set.iterator();
- while(iter.hasNext())
+ for (EndPoint endPoint : set)
{
- ConnectorEndPoint connection = (ConnectorEndPoint)iter.next();
+ ConnectorEndPoint connection = (ConnectorEndPoint)endPoint;
connection.close();
}
}
+ @Override
+ public void dump(Appendable out, String indent) throws IOException
+ {
+ super.dump(out, indent);
+ Set<EndPoint> connections = new HashSet<EndPoint>();
+ synchronized (_connections)
+ {
+ connections.addAll(_connections);
+ }
+ AggregateLifeCycle.dump(out, indent, connections);
+ }
+
/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java
index e6144f8146..b1fb779f5b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java
@@ -26,8 +26,8 @@ import org.eclipse.jetty.io.nio.AsyncConnection;
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager;
-import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.HostMap;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index 2147f4e772..7a02ac52ca 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -58,10 +58,10 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpException;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HandlerContainer;
-import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Attributes;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
index 30b2bddcfc..f9319837dd 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java
@@ -29,7 +29,6 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
index 2615ab8448..e240aef47d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
@@ -29,8 +29,8 @@ import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.WriterOutputStream;
-import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
index ebe605aec5..98716285b7 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
@@ -4,13 +4,13 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
-// The Eclipse Public License is available at
+// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
-// You may elect to redistribute this code under either of these licenses.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
-
+
package org.eclipse.jetty.server.nio;
import java.io.IOException;
@@ -39,25 +39,25 @@ import org.eclipse.jetty.util.log.Logger;
/** Blocking NIO connector.
* This connector uses efficient NIO buffers with a traditional blocking thread model.
* Direct NIO buffers are used and a thread is allocated per connections.
- *
+ *
* This connector is best used when there are a few very active connections.
- *
+ *
* @org.apache.xbean.XBean element="blockingNioConnector" description="Creates a blocking NIO based socket connector"
- *
- *
+ *
+ *
*
*/
-public class BlockingChannelConnector extends AbstractNIOConnector
+public class BlockingChannelConnector extends AbstractNIOConnector
{
private static final Logger LOG = Log.getLogger(BlockingChannelConnector.class);
private transient ServerSocketChannel _acceptChannel;
private final Set<BlockingChannelEndPoint> _endpoints = new ConcurrentHashSet<BlockingChannelEndPoint>();
-
-
+
+
/* ------------------------------------------------------------ */
/** Constructor.
- *
+ *
*/
public BlockingChannelConnector()
{
@@ -103,12 +103,12 @@ public class BlockingChannelConnector extends AbstractNIOConnector
}
}
}
-
+
});
-
+
}
-
+
/* ------------------------------------------------------------ */
public void open() throws IOException
{
@@ -128,12 +128,12 @@ public class BlockingChannelConnector extends AbstractNIOConnector
_acceptChannel.close();
_acceptChannel=null;
}
-
+
/* ------------------------------------------------------------ */
@Override
public void accept(int acceptorID)
throws IOException, InterruptedException
- {
+ {
SocketChannel channel = _acceptChannel.accept();
channel.configureBlocking(true);
Socket socket=channel.socket();
@@ -142,7 +142,7 @@ public class BlockingChannelConnector extends AbstractNIOConnector
BlockingChannelEndPoint connection=new BlockingChannelEndPoint(channel);
connection.dispatch();
}
-
+
/* ------------------------------------------------------------------------------- */
@Override
public void customize(EndPoint endpoint, Request request)
@@ -161,7 +161,7 @@ public class BlockingChannelConnector extends AbstractNIOConnector
return -1;
return _acceptChannel.socket().getLocalPort();
}
-
+
/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */
@@ -170,14 +170,14 @@ public class BlockingChannelConnector extends AbstractNIOConnector
private Connection _connection;
private int _timeout;
private volatile long _idleTimestamp;
-
- BlockingChannelEndPoint(ByteChannel channel)
+
+ BlockingChannelEndPoint(ByteChannel channel)
throws IOException
{
super(channel,BlockingChannelConnector.this._maxIdleTime);
_connection = new BlockingHttpConnection(BlockingChannelConnector.this,this,getServer());
}
-
+
/* ------------------------------------------------------------ */
/** Get the connection.
* @return the connection
@@ -186,7 +186,7 @@ public class BlockingChannelConnector extends AbstractNIOConnector
{
return _connection;
}
-
+
/* ------------------------------------------------------------ */
public void setConnection(Connection connection)
{
@@ -214,7 +214,7 @@ public class BlockingChannelConnector extends AbstractNIOConnector
LOG.ignore(e);
}
}
-
+
/* ------------------------------------------------------------ */
void dispatch() throws IOException
{
@@ -224,7 +224,7 @@ public class BlockingChannelConnector extends AbstractNIOConnector
super.close();
}
}
-
+
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.io.nio.ChannelEndPoint#fill(org.eclipse.jetty.io.Buffer)
@@ -288,9 +288,9 @@ public class BlockingChannelConnector extends AbstractNIOConnector
_timeout=getMaxIdleTime();
}
}
-
+
_connection = _connection.handle();
-
+
}
}
catch (EofException e)
@@ -305,10 +305,6 @@ public class BlockingChannelConnector extends AbstractNIOConnector
try{super.close();}
catch(IOException e2){LOG.ignore(e2);}
}
- catch(ThreadDeath e)
- {
- throw e;
- }
catch(Throwable e)
{
LOG.warn("handle failed",e);
@@ -319,14 +315,14 @@ public class BlockingChannelConnector extends AbstractNIOConnector
{
connectionClosed(_connection);
_endpoints.remove(this);
-
+
// wait for client to close, but if not, close ourselves.
try
{
if (!_socket.isClosed())
{
long timestamp=System.currentTimeMillis();
- int max_idle=getMaxIdleTime();
+ int max_idle=getMaxIdleTime();
_socket.setSoTimeout(getMaxIdleTime());
int c=0;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
index 6b37246a91..998dc76638 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
@@ -122,7 +122,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
public void customize(EndPoint endpoint, Request request) throws IOException
{
AsyncEndPoint aEndp = ((AsyncEndPoint)endpoint);
- aEndp.cancelIdle();
+ aEndp.setCheckForIdle(false);
request.setTimeStamp(System.currentTimeMillis());
endpoint.setMaxIdleTime(_maxIdleTime);
super.customize(endpoint, request);
@@ -132,7 +132,8 @@ public class SelectChannelConnector extends AbstractNIOConnector
@Override
public void persist(EndPoint endpoint) throws IOException
{
- ((AsyncEndPoint)endpoint).scheduleIdle();
+ AsyncEndPoint aEndp = ((AsyncEndPoint)endpoint);
+ aEndp.setCheckForIdle(true);
super.persist(endpoint);
}
@@ -300,7 +301,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
/* ------------------------------------------------------------ */
public void dump(Appendable out, String indent) throws IOException
{
- out.append(String.valueOf(this)).append("\n");
+ super.dump(out, indent);
ServerSocketChannel channel;
synchronized (this)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
index 7e3821982e..1f3c3d0443 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
@@ -4,11 +4,11 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
-// The Eclipse Public License is available at
+// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
-// You may elect to redistribute this code under either of these licenses.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.server.session;
@@ -43,12 +43,12 @@ import org.eclipse.jetty.util.log.Logger;
* <p>
* This manager will create it's own Timer instance to scavenge threads, unless it discovers a shared Timer instance
* set as the "org.eclipse.jetty.server.session.timer" attribute of the ContextHandler.
- *
+ *
*/
public class HashSessionManager extends AbstractSessionManager
{
final static Logger __log = SessionHandler.LOG;
-
+
protected final ConcurrentMap<String,HashedSession> _sessions=new ConcurrentHashMap<String,HashedSession>();
private static int __id;
private Timer _timer;
@@ -61,7 +61,7 @@ public class HashSessionManager extends AbstractSessionManager
File _storeDir;
private boolean _lazyLoad=false;
private volatile boolean _sessionsLoaded=false;
-
+
/* ------------------------------------------------------------ */
public HashSessionManager()
{
@@ -86,7 +86,7 @@ public class HashSessionManager extends AbstractSessionManager
_timerStop=true;
_timer=new Timer("HashSessionScavenger-"+__id++, true);
}
-
+
setScavengePeriod(getScavengePeriod());
if (_storeDir!=null)
@@ -97,7 +97,7 @@ public class HashSessionManager extends AbstractSessionManager
if (!_lazyLoad)
restoreSessions();
}
-
+
setSavePeriod(getSavePeriod());
}
@@ -107,7 +107,7 @@ public class HashSessionManager extends AbstractSessionManager
*/
@Override
public void doStop() throws Exception
- {
+ {
// stop the scavengers
synchronized(this)
{
@@ -121,16 +121,16 @@ public class HashSessionManager extends AbstractSessionManager
_timer.cancel();
_timer=null;
}
-
- // This will callback invalidate sessions - where we decide if we will save
+
+ // This will callback invalidate sessions - where we decide if we will save
super.doStop();
-
+
_sessions.clear();
}
/* ------------------------------------------------------------ */
- /**
+ /**
* @return the period in seconds at which a check is made for sessions to be invalidated.
*/
public int getScavengePeriod()
@@ -154,7 +154,7 @@ public class HashSessionManager extends AbstractSessionManager
/* ------------------------------------------------------------ */
/**
- * @return seconds Idle period after which a session is saved
+ * @return seconds Idle period after which a session is saved
*/
public int getIdleSavePeriod()
{
@@ -163,15 +163,15 @@ public class HashSessionManager extends AbstractSessionManager
return _idleSavePeriodMs / 1000;
}
-
+
/* ------------------------------------------------------------ */
/**
- * Configures the period in seconds after which a session is deemed idle and saved
- * to save on session memory.
- *
- * The session is persisted, the values attribute map is cleared and the session set to idled.
- *
- * @param seconds Idle period after which a session is saved
+ * Configures the period in seconds after which a session is deemed idle and saved
+ * to save on session memory.
+ *
+ * The session is persisted, the values attribute map is cleared and the session set to idled.
+ *
+ * @param seconds Idle period after which a session is saved
*/
public void setIdleSavePeriod(int seconds)
{
@@ -197,7 +197,7 @@ public class HashSessionManager extends AbstractSessionManager
if (period < 0)
period=0;
_savePeriodMs=period;
-
+
if (_timer!=null)
{
synchronized (this)
@@ -219,7 +219,7 @@ public class HashSessionManager extends AbstractSessionManager
{
__log.warn(e);
}
- }
+ }
};
_timer.schedule(_saveTask,_savePeriodMs,_savePeriodMs);
}
@@ -235,10 +235,10 @@ public class HashSessionManager extends AbstractSessionManager
{
if (_savePeriodMs<=0)
return 0;
-
+
return _savePeriodMs/1000;
}
-
+
/* ------------------------------------------------------------ */
/**
* @param seconds the period in seconds at which a check is made for sessions to be invalidated.
@@ -268,13 +268,13 @@ public class HashSessionManager extends AbstractSessionManager
public void run()
{
scavenge();
- }
+ }
};
_timer.schedule(_task,_scavengePeriodMs,_scavengePeriodMs);
}
}
}
-
+
/* -------------------------------------------------------------- */
/**
* Find sessions that have timed out and invalidate them. This runs in the
@@ -285,14 +285,14 @@ public class HashSessionManager extends AbstractSessionManager
//don't attempt to scavenge if we are shutting down
if (isStopping() || isStopped())
return;
-
+
Thread thread=Thread.currentThread();
ClassLoader old_loader=thread.getContextClassLoader();
try
{
if (_loader!=null)
thread.setContextClassLoader(_loader);
-
+
// For each session
long now=System.currentTimeMillis();
for (Iterator<HashedSession> i=_sessions.values().iterator(); i.hasNext();)
@@ -306,14 +306,10 @@ public class HashSessionManager extends AbstractSessionManager
}
else if (_idleSavePeriodMs>0&&session.getAccessed()+_idleSavePeriodMs<now)
{
- session.idle();
+ session.idle();
}
}
}
- catch (ThreadDeath e)
- {
- throw e;
- }
catch (Throwable t)
{
__log.warn("Problem scavenging sessions", t);
@@ -323,7 +319,7 @@ public class HashSessionManager extends AbstractSessionManager
thread.setContextClassLoader(old_loader);
}
}
-
+
/* ------------------------------------------------------------ */
@Override
protected void addSession(AbstractSession session)
@@ -331,7 +327,7 @@ public class HashSessionManager extends AbstractSessionManager
if (isRunning())
_sessions.put(session.getClusterId(),(HashedSession)session);
}
-
+
/* ------------------------------------------------------------ */
@Override
public AbstractSession getSession(String idInCluster)
@@ -351,7 +347,7 @@ public class HashSessionManager extends AbstractSessionManager
Map<String,HashedSession> sessions=_sessions;
if (sessions==null)
return null;
-
+
HashedSession session = sessions.get(idInCluster);
if (session == null && _lazyLoad)
@@ -361,7 +357,7 @@ public class HashSessionManager extends AbstractSessionManager
if (_idleSavePeriodMs!=0)
session.deIdle();
-
+
return session;
}
@@ -389,7 +385,7 @@ public class HashSessionManager extends AbstractSessionManager
for (HashedSession session : sessions)
session.invalidate();
}
-
+
// check that no new sessions were created while we were iterating
sessions=new ArrayList<HashedSession>(_sessions.values());
}
@@ -401,13 +397,13 @@ public class HashSessionManager extends AbstractSessionManager
{
return new HashedSession(this, request);
}
-
+
/* ------------------------------------------------------------ */
protected AbstractSession newSession(long created, long accessed, String clusterId)
{
return new HashedSession(this, created,accessed, clusterId);
}
-
+
/* ------------------------------------------------------------ */
@Override
protected boolean removeSession(String clusterId)
@@ -432,7 +428,7 @@ public class HashSessionManager extends AbstractSessionManager
{
_lazyLoad = lazyLoad;
}
-
+
/* ------------------------------------------------------------ */
public boolean isLazyLoad()
{
@@ -443,7 +439,7 @@ public class HashSessionManager extends AbstractSessionManager
public void restoreSessions () throws Exception
{
_sessionsLoaded = true;
-
+
if (_storeDir==null || !_storeDir.exists())
{
return;
@@ -470,9 +466,9 @@ public class HashSessionManager extends AbstractSessionManager
File file = new File(_storeDir,idInCuster);
if (file.exists())
{
- FileInputStream in = new FileInputStream(file);
+ FileInputStream in = new FileInputStream(file);
HashedSession session = restoreSession(in, null);
- in.close();
+ in.close();
addSession(session, false);
session.didActivate();
file.delete();
@@ -485,7 +481,7 @@ public class HashSessionManager extends AbstractSessionManager
}
return null;
}
-
+
/* ------------------------------------------------------------ */
public void saveSessions(boolean reactivate) throws Exception
{
@@ -493,7 +489,7 @@ public class HashSessionManager extends AbstractSessionManager
{
return;
}
-
+
if (!_storeDir.canWrite())
{
__log.warn ("Unable to save Sessions: Session persistence storage directory "+_storeDir.getAbsolutePath()+ " is not writeable");
@@ -508,7 +504,7 @@ public class HashSessionManager extends AbstractSessionManager
public HashedSession restoreSession (InputStream is, HashedSession session) throws Exception
{
/*
- * Take care of this class's fields first by calling
+ * Take care of this class's fields first by calling
* defaultReadObject
*/
DataInputStream in = new DataInputStream(is);
@@ -517,7 +513,7 @@ public class HashSessionManager extends AbstractSessionManager
long created = in.readLong();
long accessed = in.readLong();
int requests = in.readInt();
-
+
if (session == null)
session = (HashedSession)newSession(created, accessed, clusterId);
session.setRequests(requests);
@@ -538,7 +534,7 @@ public class HashSessionManager extends AbstractSessionManager
return session;
}
-
+
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
protected class ClassLoadingObjectInputStream extends ObjectInputStream
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
index 6a91c98ef6..f09dab5ea9 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
@@ -4,11 +4,11 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
-// The Eclipse Public License is available at
+// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
-// You may elect to redistribute this code under either of these licenses.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
@@ -46,9 +46,9 @@ import org.eclipse.jetty.util.log.Logger;
* JDBCSessionManager
*
* SessionManager that persists sessions to a database to enable clustering.
- *
+ *
* Session data is persisted to the JettySessions table:
- *
+ *
* rowId (unique in cluster: webapp name/path + virtualhost + sessionId)
* contextPath (of the context owning the session)
* sessionId (unique in a context)
@@ -60,7 +60,7 @@ import org.eclipse.jetty.util.log.Logger;
* lastSavedTime (last time in milliseconds session access times were saved)
* expiryTime (time in milliseconds that the session is due to expire)
* map (attribute map)
- *
+ *
* As an optimization, to prevent thrashing the database, we do not persist
* the accessTime and lastAccessTime every time the session is accessed. Rather,
* we write it out every so often. The frequency is controlled by the saveIntervalSec
@@ -69,18 +69,18 @@ import org.eclipse.jetty.util.log.Logger;
public class JDBCSessionManager extends AbstractSessionManager
{
private static final Logger LOG = Log.getLogger(JDBCSessionManager.class);
-
- protected String __insertSession;
- protected String __deleteSession;
- protected String __selectSession;
- protected String __updateSession;
- protected String __updateSessionNode;
+
+ protected String __insertSession;
+ protected String __deleteSession;
+ protected String __selectSession;
+ protected String __updateSession;
+ protected String __updateSessionNode;
protected String __updateSessionAccessTime;
protected String __sessionTableRowId;
-
+
private ConcurrentHashMap<String, AbstractSession> _sessions;
protected long _saveIntervalSec = 60; //only persist changes to session access times every 60 secs
-
+
/**
* SessionData
*
@@ -110,7 +110,7 @@ public class JDBCSessionManager extends AbstractSessionManager
_attributes = new HashMap<String,Object>();
_lastNode = getSessionIdManager().getWorkerName();
}
-
+
public SessionData (String sessionId,Map<String,Object> attributes)
{
_id=sessionId;
@@ -129,23 +129,23 @@ public class JDBCSessionManager extends AbstractSessionManager
{
return _created;
}
-
+
protected synchronized void setCreated (long ms)
{
_created = ms;
}
-
+
public synchronized long getAccessed ()
{
return _accessed;
}
-
+
protected synchronized void setAccessed (long ms)
{
_accessed = ms;
}
-
-
+
+
public synchronized void setMaxIdleMs (long ms)
{
_maxIdleMs = ms;
@@ -175,77 +175,77 @@ public class JDBCSessionManager extends AbstractSessionManager
{
return _cookieSet;
}
-
+
public synchronized void setRowId (String rowId)
{
_rowId=rowId;
}
-
+
protected synchronized String getRowId()
{
return _rowId;
}
-
+
protected synchronized Map<String,Object> getAttributeMap ()
{
return _attributes;
}
-
+
protected synchronized void setAttributeMap (Map<String,Object> map)
{
_attributes = map;
- }
-
+ }
+
public synchronized void setLastNode (String node)
{
_lastNode=node;
}
-
+
public synchronized String getLastNode ()
{
return _lastNode;
}
-
+
public synchronized void setCanonicalContext(String str)
{
_canonicalContext=str;
}
-
+
public synchronized String getCanonicalContext ()
{
return _canonicalContext;
}
-
+
public synchronized long getLastSaved ()
{
return _lastSaved;
}
-
+
public synchronized void setLastSaved (long time)
{
_lastSaved=time;
}
-
+
public synchronized void setExpiryTime (long time)
{
- _expiryTime=time;
+ _expiryTime=time;
}
-
+
public synchronized long getExpiryTime ()
{
return _expiryTime;
}
-
+
public synchronized void setVirtualHost (String vhost)
{
_virtualHost=vhost;
}
-
+
public synchronized String getVirtualHost ()
{
return _virtualHost;
}
-
+
@Override
public String toString ()
{
@@ -256,8 +256,8 @@ public class JDBCSessionManager extends AbstractSessionManager
}
}
-
-
+
+
/**
* Session
*
@@ -271,12 +271,12 @@ public class JDBCSessionManager extends AbstractSessionManager
/**
* Session from a request.
- *
+ *
* @param request
*/
protected Session (HttpServletRequest request)
{
- super(JDBCSessionManager.this,request);
+ super(JDBCSessionManager.this,request);
_data = new SessionData(getClusterId(),_jdbcAttributes);
if (_dftMaxIdleSecs>0)
_data.setMaxIdleMs(_dftMaxIdleSecs*1000);
@@ -299,7 +299,7 @@ public class JDBCSessionManager extends AbstractSessionManager
_jdbcAttributes.putAll(_data.getAttributeMap());
_data.setAttributeMap(_jdbcAttributes);
}
-
+
@Override
public void setAttribute (String name, Object value)
{
@@ -310,20 +310,20 @@ public class JDBCSessionManager extends AbstractSessionManager
@Override
public void removeAttribute (String name)
{
- super.removeAttribute(name);
+ super.removeAttribute(name);
_dirty=true;
}
-
+
@Override
protected void cookieSet()
{
_data.setCookieSet(_data.getAccessed());
}
- /**
+ /**
* Entry to session.
* Called by SessionHandler on inbound request and the session already exists in this node's memory.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSession#access(long)
*/
@Override
@@ -341,7 +341,7 @@ public class JDBCSessionManager extends AbstractSessionManager
return false;
}
- /**
+ /**
* Exit from session
* @see org.eclipse.jetty.server.session.AbstractSession#complete()
*/
@@ -352,7 +352,7 @@ public class JDBCSessionManager extends AbstractSessionManager
try
{
if (_dirty)
- {
+ {
//The session attributes have changed, write to the db, ensuring
//http passivation/activation listeners called
willPassivate();
@@ -360,7 +360,7 @@ public class JDBCSessionManager extends AbstractSessionManager
didActivate();
}
else if ((_data._accessed - _data._lastSaved) >= (getSaveInterval() * 1000))
- {
+ {
updateSessionAccessTime(_data);
}
}
@@ -373,19 +373,19 @@ public class JDBCSessionManager extends AbstractSessionManager
_dirty=false;
}
}
-
+
@Override
protected void timeout() throws IllegalStateException
{
- if (LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled())
LOG.debug("Timing out session id="+getClusterId());
super.timeout();
}
}
-
-
-
-
+
+
+
+
/**
* ClassLoadingObjectInputStream
*
@@ -416,46 +416,46 @@ public class JDBCSessionManager extends AbstractSessionManager
}
}
}
-
-
+
+
/**
* Set the time in seconds which is the interval between
* saving the session access time to the database.
- *
+ *
* This is an optimization that prevents the database from
* being overloaded when a session is accessed very frequently.
- *
+ *
* On session exit, if the session attributes have NOT changed,
* the time at which we last saved the accessed
* time is compared to the current accessed time. If the interval
* is at least saveIntervalSecs, then the access time will be
* persisted to the database.
- *
+ *
* If any session attribute does change, then the attributes and
* the accessed time are persisted.
- *
+ *
* @param sec
*/
public void setSaveInterval (long sec)
{
_saveIntervalSec=sec;
}
-
+
public long getSaveInterval ()
{
return _saveIntervalSec;
}
-
-
+
+
/**
* A method that can be implemented in subclasses to support
* distributed caching of sessions. This method will be
* called whenever the session is written to the database
* because the session data has changed.
- *
+ *
* This could be used eg with a JMS backplane to notify nodes
* that the session has changed and to delete the session from
* the node's cache, and re-read it from the database.
@@ -463,46 +463,46 @@ public class JDBCSessionManager extends AbstractSessionManager
*/
public void cacheInvalidate (Session session)
{
-
+
}
-
-
- /**
+
+
+ /**
* A session has been requested by it's id on this node.
- *
+ *
* Load the session by id AND context path from the database.
* Multiple contexts may share the same session id (due to dispatching)
* but they CANNOT share the same contents.
- *
+ *
* Check if last node id is my node id, if so, then the session we have
* in memory cannot be stale. If another node used the session last, then
* we need to refresh from the db.
- *
- * NOTE: this method will go to the database, so if you only want to check
+ *
+ * NOTE: this method will go to the database, so if you only want to check
* for the existence of a Session in memory, use _sessions.get(id) instead.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String)
*/
@Override
public Session getSession(String idInCluster)
{
Session session = (Session)_sessions.get(idInCluster);
-
+
synchronized (this)
- {
+ {
try
- {
- //check if we need to reload the session -
+ {
+ //check if we need to reload the session -
//as an optimization, don't reload on every access
- //to reduce the load on the database. This introduces a window of
+ //to reduce the load on the database. This introduces a window of
//possibility that the node may decide that the session is local to it,
//when the session has actually been live on another node, and then
//re-migrated to this node. This should be an extremely rare occurrence,
- //as load-balancers are generally well-behaved and consistently send
- //sessions to the same node, changing only iff that node fails.
+ //as load-balancers are generally well-behaved and consistently send
+ //sessions to the same node, changing only iff that node fails.
SessionData data = null;
long now = System.currentTimeMillis();
- if (LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled())
{
if (session==null)
LOG.debug("getSession("+idInCluster+"): not in session map,"+
@@ -518,9 +518,9 @@ public class JDBCSessionManager extends AbstractSessionManager
" thisNode="+getSessionIdManager().getWorkerName()+
" difference="+(now - session._data._lastSaved));
}
-
+
if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000)))
- {
+ {
LOG.debug("getSession("+idInCluster+"): no session in session map or stale session. Reloading session data from db.");
data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
}
@@ -531,10 +531,10 @@ public class JDBCSessionManager extends AbstractSessionManager
}
else
{
- LOG.debug("getSession("+idInCluster+"): session in session map");
+ LOG.debug("getSession("+idInCluster+"): session in session map");
data = session._data;
}
-
+
if (data != null)
{
if (!data.getLastNode().equals(getSessionIdManager().getWorkerName()) || session==null)
@@ -554,7 +554,7 @@ public class JDBCSessionManager extends AbstractSessionManager
}
else
if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): Session has expired");
-
+
}
else
if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): Session not stale "+session._data);
@@ -566,7 +566,7 @@ public class JDBCSessionManager extends AbstractSessionManager
session=null;
if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): No session in database matching id="+idInCluster);
}
-
+
return session;
}
catch (Exception e)
@@ -576,10 +576,10 @@ public class JDBCSessionManager extends AbstractSessionManager
}
}
}
-
- /**
+
+ /**
* Get the number of sessions.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#getSessions()
*/
@Override
@@ -594,9 +594,9 @@ public class JDBCSessionManager extends AbstractSessionManager
}
- /**
+ /**
* Start the session manager.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#doStart()
*/
@Override
@@ -604,17 +604,17 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (_sessionIdManager==null)
throw new IllegalStateException("No session id manager defined");
-
+
prepareTables();
-
+
_sessions = new ConcurrentHashMap<String, AbstractSession>();
super.doStart();
}
-
-
- /**
+
+
+ /**
* Stop the session manager.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#doStop()
*/
@Override
@@ -622,10 +622,10 @@ public class JDBCSessionManager extends AbstractSessionManager
{
_sessions.clear();
_sessions = null;
-
+
super.doStop();
- }
-
+ }
+
@Override
protected void invalidateSessions()
{
@@ -637,10 +637,10 @@ public class JDBCSessionManager extends AbstractSessionManager
//any other nodes
}
-
+
/**
* Invalidate a session.
- *
+ *
* @param idInCluster
*/
protected void invalidateSession (String idInCluster)
@@ -650,24 +650,24 @@ public class JDBCSessionManager extends AbstractSessionManager
{
session = (Session)_sessions.get(idInCluster);
}
-
+
if (session != null)
{
session.invalidate();
}
}
-
- /**
+
+ /**
* Delete an existing session, both from the in-memory map and
* the database.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String)
*/
@Override
protected boolean removeSession(String idInCluster)
{
synchronized (this)
- {
+ {
Session session = (Session)_sessions.remove(idInCluster);
try
{
@@ -683,9 +683,9 @@ public class JDBCSessionManager extends AbstractSessionManager
}
- /**
+ /**
* Add a newly created session to our in-memory list for this node and persist it.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession)
*/
@Override
@@ -698,7 +698,7 @@ public class JDBCSessionManager extends AbstractSessionManager
{
_sessions.put(session.getClusterId(), session);
}
-
+
//TODO or delay the store until exit out of session? If we crash before we store it
//then session data will be lost.
try
@@ -714,9 +714,9 @@ public class JDBCSessionManager extends AbstractSessionManager
}
- /**
+ /**
* Make a new Session.
- *
+ *
* @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest)
*/
@Override
@@ -724,9 +724,9 @@ public class JDBCSessionManager extends AbstractSessionManager
{
return new Session(request);
}
-
+
/* ------------------------------------------------------------ */
- /** Remove session from manager
+ /** Remove session from manager
* @param session The session to remove
* @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
* {@link SessionIdManager#invalidateAll(String)} should be called.
@@ -736,7 +736,7 @@ public class JDBCSessionManager extends AbstractSessionManager
{
// Remove session from context and global maps
boolean removed = false;
-
+
synchronized (this)
{
//take this session out of the map of sessions for this context
@@ -751,10 +751,10 @@ public class JDBCSessionManager extends AbstractSessionManager
{
// Remove session from all context and global id maps
_sessionIdManager.removeSession(session);
-
+
if (invalidate)
_sessionIdManager.invalidateAll(session.getClusterId());
-
+
if (invalidate && !_sessionListeners.isEmpty())
{
HttpSessionEvent event=new HttpSessionEvent(session);
@@ -767,16 +767,16 @@ public class JDBCSessionManager extends AbstractSessionManager
}
}
}
-
-
+
+
/**
* Expire any Sessions we have in memory matching the list of
* expired Session ids.
- *
+ *
* @param sessionIds
*/
protected void expire (List<?> sessionIds)
- {
+ {
//don't attempt to scavenge if we are shutting down
if (isStopping() || isStopped())
return;
@@ -791,9 +791,9 @@ public class JDBCSessionManager extends AbstractSessionManager
while (itor.hasNext())
{
String sessionId = (String)itor.next();
- if (LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled())
LOG.debug("Expiring session id "+sessionId);
-
+
Session session = (Session)_sessions.get(sessionId);
if (session != null)
{
@@ -802,15 +802,11 @@ public class JDBCSessionManager extends AbstractSessionManager
}
else
{
- if (LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled())
LOG.debug("Unrecognized session id="+sessionId);
}
}
}
- catch (ThreadDeath e)
- {
- throw e;
- }
catch (Throwable t)
{
LOG.warn("Problem expiring sessions", t);
@@ -820,12 +816,12 @@ public class JDBCSessionManager extends AbstractSessionManager
thread.setContextClassLoader(old_loader);
}
}
-
-
+
+
protected void prepareTables ()
{
__sessionTableRowId = ((JDBCSessionIdManager)_sessionIdManager)._sessionTableRowId;
-
+
__insertSession = "insert into "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
" ("+__sessionTableRowId+", sessionId, contextPath, virtualHost, lastNode, accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime, expiryTime, map) "+
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
@@ -845,7 +841,7 @@ public class JDBCSessionManager extends AbstractSessionManager
__updateSessionAccessTime = "update "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
" set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ? where "+__sessionTableRowId+" = ?";
}
-
+
/**
* Load a session from the database
* @param id
@@ -866,7 +862,7 @@ public class JDBCSessionManager extends AbstractSessionManager
Connection connection=null;
PreparedStatement statement = null;
try
- {
+ {
connection = getConnection();
statement = connection.prepareStatement(__selectSession);
statement.setString(1, id);
@@ -909,24 +905,24 @@ public class JDBCSessionManager extends AbstractSessionManager
try { connection.close();}
catch(Exception e) { LOG.warn(e); }
}
- }
+ }
}
};
-
+
if (_context==null)
load.run();
else
_context.getContextHandler().handle(load);
-
+
if (_exception.get()!=null)
throw _exception.get();
-
+
return _reference.get();
}
-
+
/**
* Insert a session into the database.
- *
+ *
* @param data
* @throws Exception
*/
@@ -935,14 +931,14 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (data==null)
return;
-
- //put into the database
+
+ //put into the database
Connection connection = getConnection();
PreparedStatement statement = null;
try
- {
+ {
String rowId = calculateRowId(data);
-
+
long now = System.currentTimeMillis();
connection.setAutoCommit(true);
statement = connection.prepareStatement(__insertSession);
@@ -957,34 +953,34 @@ public class JDBCSessionManager extends AbstractSessionManager
statement.setLong(9, data.getCookieSet());//time cookie was set
statement.setLong(10, now); //last saved time
statement.setLong(11, data.getExpiryTime());
-
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(data.getAttributeMap());
byte[] bytes = baos.toByteArray();
-
+
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
-
+
statement.executeUpdate();
data.setRowId(rowId); //set it on the in-memory data as well as in db
data.setLastSaved(now);
-
+
if (LOG.isDebugEnabled())
LOG.debug("Stored session "+data);
- }
+ }
finally
{
if (connection!=null)
connection.close();
}
}
-
-
+
+
/**
* Update data on an existing persisted session.
- *
+ *
* @param data
* @throws Exception
*/
@@ -993,30 +989,30 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (data==null)
return;
-
+
Connection connection = getConnection();
PreparedStatement statement = null;
try
- {
+ {
long now = System.currentTimeMillis();
connection.setAutoCommit(true);
- statement = connection.prepareStatement(__updateSession);
+ statement = connection.prepareStatement(__updateSession);
statement.setString(1, getSessionIdManager().getWorkerName());//my node id
statement.setLong(2, data.getAccessed());//accessTime
statement.setLong(3, data.getLastAccessed()); //lastAccessTime
statement.setLong(4, now); //last saved time
statement.setLong(5, data.getExpiryTime());
-
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(data.getAttributeMap());
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
- statement.setBinaryStream(6, bais, bytes.length);//attribute map as blob
+
+ statement.setBinaryStream(6, bais, bytes.length);//attribute map as blob
statement.setString(7, data.getRowId()); //rowId
statement.executeUpdate();
-
+
data.setLastSaved(now);
if (LOG.isDebugEnabled())
LOG.debug("Updated session "+data);
@@ -1027,11 +1023,11 @@ public class JDBCSessionManager extends AbstractSessionManager
connection.close();
}
}
-
-
+
+
/**
* Update the node on which the session was last seen to be my node.
- *
+ *
* @param data
* @throws Exception
*/
@@ -1042,7 +1038,7 @@ public class JDBCSessionManager extends AbstractSessionManager
Connection connection = getConnection();
PreparedStatement statement = null;
try
- {
+ {
connection.setAutoCommit(true);
statement = connection.prepareStatement(__updateSessionNode);
statement.setString(1, nodeId);
@@ -1058,10 +1054,10 @@ public class JDBCSessionManager extends AbstractSessionManager
connection.close();
}
}
-
+
/**
* Persist the time the session was last accessed.
- *
+ *
* @param data
* @throws Exception
*/
@@ -1071,7 +1067,7 @@ public class JDBCSessionManager extends AbstractSessionManager
Connection connection = getConnection();
PreparedStatement statement = null;
try
- {
+ {
long now = System.currentTimeMillis();
connection.setAutoCommit(true);
statement = connection.prepareStatement(__updateSessionAccessTime);
@@ -1093,14 +1089,14 @@ public class JDBCSessionManager extends AbstractSessionManager
connection.close();
}
}
-
-
-
-
+
+
+
+
/**
* Delete a session from the database. Should only be called
* when the session has been invalidated.
- *
+ *
* @param data
* @throws Exception
*/
@@ -1122,11 +1118,11 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (connection!=null)
connection.close();
- }
+ }
}
-
-
-
+
+
+
/**
* Get a connection from the driver.
* @return
@@ -1134,13 +1130,13 @@ public class JDBCSessionManager extends AbstractSessionManager
*/
private Connection getConnection ()
throws SQLException
- {
+ {
return ((JDBCSessionIdManager)getSessionIdManager()).getConnection();
}
/**
* Calculate a unique id for this session across the cluster.
- *
+ *
* Unique id is composed of: contextpath_virtualhost0_sessionid
* @param data
* @return
@@ -1152,31 +1148,31 @@ public class JDBCSessionManager extends AbstractSessionManager
rowId = rowId+"_"+data.getId();
return rowId;
}
-
+
/**
* Get the first virtual host for the context.
- *
+ *
* Used to help identify the exact session/contextPath.
- *
+ *
* @return 0.0.0.0 if no virtual host is defined
*/
private String getVirtualHost (ContextHandler.Context context)
{
String vhost = "0.0.0.0";
-
+
if (context==null)
return vhost;
-
+
String [] vhosts = context.getContextHandler().getVirtualHosts();
if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
return vhost;
-
+
return vhosts[0];
}
-
+
/**
* Make an acceptable file name from a context path.
- *
+ *
* @param path
* @return
*/
@@ -1184,7 +1180,7 @@ public class JDBCSessionManager extends AbstractSessionManager
{
if (path==null)
return "";
-
+
return path.replace('/', '_').replace('.','_').replace('\\','_');
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
index 5c6ca0d60f..1986e7bc08 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
@@ -15,6 +15,7 @@ package org.eclipse.jetty.server.ssl;
import java.io.IOException;
import java.nio.channels.SocketChannel;
+
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java
index 3e3fe28c0f..e63f875a9e 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java
@@ -22,7 +22,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;
-import java.util.Random;
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
@@ -35,6 +34,7 @@ import org.eclipse.jetty.continuation.ContinuationSupport;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.StringUtil;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -75,12 +75,16 @@ public class AsyncRequestReadTest
Arrays.fill(content, (byte)120);
OutputStream out = socket.getOutputStream();
- out.write("POST / HTTP/1.1\r\n".getBytes());
- out.write("Host: localhost\r\n".getBytes());
- out.write(("Content-Length: "+content.length+"\r\n").getBytes());
- out.write("Content-Type: bytes\r\n".getBytes());
- out.write("Connection: close\r\n".getBytes());
- out.write("\r\n".getBytes());
+ String header=
+ "POST / HTTP/1.1\r\n"+
+ "Host: localhost\r\n"+
+ "Content-Length: "+content.length+"\r\n"+
+ "Content-Type: bytes\r\n"+
+ "Connection: close\r\n"+
+ "\r\n";
+ byte[] h=header.getBytes(StringUtil.__ISO_8859_1);
+
+ out.write(h);
out.flush();
out.write(content,0,4*4096);
@@ -98,7 +102,7 @@ public class AsyncRequestReadTest
long total=__total.exchange(0L,30,TimeUnit.SECONDS);
assertEquals(content.length, total);
}
-
+
@Test
public void tests() throws Exception
{
@@ -114,7 +118,7 @@ public class AsyncRequestReadTest
public void runTest(int contentSize, int chunkSize, int chunks, int delayMS) throws Exception
{
String tst=contentSize+","+chunkSize+","+chunks+","+delayMS;
- System.err.println(tst);
+ //System.err.println(tst);
final Socket socket = new Socket("localhost",connector.getLocalPort());
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
index f49d6ac48c..497e081dd0 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
@@ -30,6 +30,7 @@ import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSessionContext;
@@ -487,6 +488,24 @@ public class ResponseTest
}
}
+ @Test
+ public void testAddCookie() throws Exception
+ {
+ Response response = new Response(new TestHttpConnection(connector,new ByteArrayEndPoint(), connector.getServer()));
+
+ Cookie cookie=new Cookie("name","value");
+ cookie.setDomain("domain");
+ cookie.setPath("/path");
+ cookie.setSecure(true);
+ cookie.setComment("comment__HTTP_ONLY__");
+
+ response.addCookie(cookie);
+
+ String set = response.getHttpFields().getStringField("Set-Cookie");
+
+ assertEquals("name=value;Path=/path;Domain=domain;Secure;HttpOnly",set);
+ }
+
private Response newResponse()
{
ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java
index a7b2c88445..a7424b9949 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java
@@ -19,7 +19,6 @@ import java.io.OutputStream;
import java.net.Socket;
import java.security.KeyStore;
import java.util.Arrays;
-import java.util.Random;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSelectChannelTimeoutTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSelectChannelTimeoutTest.java
index 9e6498be10..502f16ef6f 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSelectChannelTimeoutTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSelectChannelTimeoutTest.java
@@ -23,7 +23,6 @@ import javax.net.ssl.TrustManagerFactory;
import org.eclipse.jetty.server.ConnectorTimeoutTest;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.BeforeClass;
-import org.junit.Test;
public class SslSelectChannelTimeoutTest extends ConnectorTimeoutTest
{
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
index 8279f771dc..b06acc1ea6 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
@@ -38,7 +38,6 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.AfterClass;
-import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
index de3efb6418..1f742af5e6 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
@@ -40,9 +40,9 @@ import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.WriterOutputStream;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Dispatcher;
-import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.server.InclusiveByteRange;
import org.eclipse.jetty.server.ResourceCache;
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
index 6fb32bc69c..ada696e330 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
@@ -25,8 +25,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpMethods;
-import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java
index f6ddbaf0b4..b4c0ca6a44 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java
@@ -26,9 +26,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
index ebad1b26a9..fa3b60cb4e 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
@@ -50,8 +50,10 @@ import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.DispatcherType;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServletRequestHttpWrapper;
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java
index 306b6bff12..8fe840c1b8 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java
@@ -134,7 +134,7 @@ public abstract class Utf8Appendable
protected void appendByte(byte b) throws IOException
{
- if (b > 0 && isUtf8SequenceComplete())
+ if (b > 0 && _state == UTF8_ACCEPT)
{
_appendable.append((char)(b & 0xFF));
}
@@ -142,41 +142,48 @@ public abstract class Utf8Appendable
{
int i = b & 0xFF;
int type = BYTE_TABLE[i];
- _codep = isUtf8SequenceComplete() ? (0xFF >> type) & i : (i & 0x3F) | (_codep << 6);
- _state = TRANS_TABLE[_state + type];
+ _codep = _state == UTF8_ACCEPT ? (0xFF >> type) & i : (i & 0x3F) | (_codep << 6);
+ int next = TRANS_TABLE[_state + type];
- if (isUtf8SequenceComplete())
+ switch(next)
{
- if (_codep < Character.MIN_HIGH_SURROGATE)
- {
- _appendable.append((char)_codep);
- }
- else
- {
- for (char c : Character.toChars(_codep))
- _appendable.append(c);
- }
- }
- else if (_state == UTF8_REJECT)
- {
- _codep=0;
- _state = UTF8_ACCEPT;
- _appendable.append(REPLACEMENT);
- throw new NotUtf8Exception();
+ case UTF8_ACCEPT:
+ _state=next;
+ if (_codep < Character.MIN_HIGH_SURROGATE)
+ {
+ _appendable.append((char)_codep);
+ }
+ else
+ {
+ for (char c : Character.toChars(_codep))
+ _appendable.append(c);
+ }
+ break;
+
+ case UTF8_REJECT:
+ String reason = "byte "+TypeUtil.toHexString(b)+" in state "+(_state/12);
+ _codep=0;
+ _state = UTF8_ACCEPT;
+ _appendable.append(REPLACEMENT);
+ throw new NotUtf8Exception(reason);
+
+ default:
+ _state=next;
+
}
}
}
- protected boolean isUtf8SequenceComplete()
+ public boolean isUtf8SequenceComplete()
{
return _state == UTF8_ACCEPT;
}
public static class NotUtf8Exception extends IllegalArgumentException
{
- public NotUtf8Exception()
+ public NotUtf8Exception(String reason)
{
- super("Not valid UTF8!");
+ super("Not valid UTF8! "+reason);
}
}
}
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java
index e857d48dbb..74f8e5fa66 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java
@@ -142,11 +142,6 @@ public class Log
LOG.debug("Logging to {} via {}", LOG, log_class.getName());
}
}
- catch(ThreadDeath e)
- {
- // Let ThreadDeath pass through
- throw e;
- }
catch(Throwable e)
{
// Unable to load specified Logger implementation, default to standard logging.
@@ -163,7 +158,7 @@ public class Log
{
e.printStackTrace();
}
-
+
if (LOG == null)
{
log_class = StdErrLog.class;
@@ -186,7 +181,7 @@ public class Log
initialized();
return LOG;
}
-
+
/**
* Get the root logger.
* @return the root logger
@@ -397,10 +392,10 @@ public class Log
return;
LOG.warn(EXCEPTION, th);
}
-
+
/**
* Obtain a named Logger based on the fully qualified class name.
- *
+ *
* @param clazz
* the class to base the Logger name off of
* @return the Logger with the given name
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/CapturingJULHandler.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/CapturingJULHandler.java
index adb7b67b3c..1ec646e669 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/CapturingJULHandler.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/log/CapturingJULHandler.java
@@ -1,6 +1,6 @@
package org.eclipse.jetty.util.log;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.containsString;
import java.io.PrintWriter;
import java.io.StringWriter;
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/JavaUtilLogTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/JavaUtilLogTest.java
index d3150ea90c..244b1e1306 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/JavaUtilLogTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/log/JavaUtilLogTest.java
@@ -1,6 +1,6 @@
package org.eclipse.jetty.util.log;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.is;
import java.io.PrintWriter;
import java.io.StringWriter;
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java
index 9e77066bb4..e5322ca63b 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/log/LogTest.java
@@ -13,7 +13,7 @@
package org.eclipse.jetty.util.log;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.is;
import org.junit.AfterClass;
import org.junit.Assert;
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrCapture.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrCapture.java
index 3955c5e2a0..b9b536db80 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrCapture.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrCapture.java
@@ -1,6 +1,7 @@
package org.eclipse.jetty.util.log;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java
index c3bb5518ea..6a0e8e2b62 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/log/StdErrLogTest.java
@@ -13,7 +13,8 @@
package org.eclipse.jetty.util.log;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java
index 075998d85f..4e2c7e1861 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java
@@ -6,7 +6,6 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.StdErrLog;
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java
index 3e44be1460..aa37a0c65b 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java
@@ -30,7 +30,6 @@ import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
-import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
@@ -44,7 +43,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
public final static byte LENGTH_FRAME=(byte)0x80;
public final static byte SENTINEL_FRAME=(byte)0x00;
- final IdleCheck _idle;
final WebSocketParser _parser;
final WebSocketGenerator _generator;
final WebSocket _websocket;
@@ -57,8 +55,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
throws IOException
{
super(endpoint,timestamp);
- if (endpoint instanceof AsyncEndPoint)
- ((AsyncEndPoint)endpoint).cancelIdle();
_endp.setMaxIdleTime(maxIdleTime);
@@ -67,28 +63,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
_generator = new WebSocketGeneratorD00(buffers, _endp);
_parser = new WebSocketParserD00(buffers, endpoint, new FrameHandlerD00(_websocket));
-
- if (_endp instanceof SelectChannelEndPoint)
- {
- final SelectChannelEndPoint scep=(SelectChannelEndPoint)_endp;
- scep.cancelIdle();
- _idle=new IdleCheck()
- {
- public void access(EndPoint endp)
- {
- scep.scheduleIdle();
- }
- };
- scep.scheduleIdle();
- }
- else
- {
- _idle = new IdleCheck()
- {
- public void access(EndPoint endp)
- {}
- };
- }
}
/* ------------------------------------------------------------ */
@@ -190,8 +164,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
{
if (_endp.isOpen())
{
- _idle.access(_endp);
-
if (_endp.isInputShutdown() && _generator.isBufferEmpty())
_endp.close();
else
@@ -253,7 +225,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
_generator.addFrame((byte)0,SENTINEL_FRAME,data,0,data.length);
_generator.flush();
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -262,7 +233,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
_generator.addFrame((byte)0,LENGTH_FRAME,data,offset,length);
_generator.flush();
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -285,7 +255,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
_generator.addFrame((byte)0,opcode,content,offset,length);
_generator.flush();
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -299,7 +268,7 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
{
close();
}
-
+
/* ------------------------------------------------------------ */
public void close()
{
@@ -371,11 +340,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
}
}
- private interface IdleCheck
- {
- void access(EndPoint endp);
- }
-
public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
{
String uri=request.getRequestURI();
@@ -490,10 +454,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
((WebSocket.OnBinaryMessage)_websocket).onMessage(array,buffer.getIndex(),buffer.length());
}
}
- catch(ThreadDeath th)
- {
- throw th;
- }
catch(Throwable th)
{
LOG.warn(th);
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java
index cd324a4409..4ee7947c9b 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java
@@ -28,7 +28,6 @@ import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.util.B64Code;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.Utf8StringBuilder;
@@ -76,7 +75,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
private final static byte[] MAGIC;
- private final IdleCheck _idle;
private final WebSocketParser _parser;
private final WebSocketGenerator _generator;
private final WebSocket _webSocket;
@@ -116,9 +114,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
{
super(endpoint,timestamp);
- if (endpoint instanceof AsyncEndPoint)
- ((AsyncEndPoint)endpoint).cancelIdle();
-
_endp.setMaxIdleTime(maxIdleTime);
_webSocket = websocket;
@@ -130,28 +125,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
_parser = new WebSocketParserD06(buffers, endpoint, _frameHandler,true);
_protocol=protocol;
- if (_endp instanceof SelectChannelEndPoint)
- {
- final SelectChannelEndPoint scep=(SelectChannelEndPoint)_endp;
- scep.cancelIdle();
- _idle=new IdleCheck()
- {
- public void access(EndPoint endp)
- {
- scep.scheduleIdle();
- }
- };
- scep.scheduleIdle();
- }
- else
- {
- _idle = new IdleCheck()
- {
- public void access(EndPoint endp)
- {}
- };
- }
-
_maxTextMessageSize=buffers.getBufferSize();
_maxBinaryMessageSize=-1;
}
@@ -200,7 +173,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
{
if (_endp.isOpen())
{
- _idle.access(_endp);
if (_closedIn && _closedOut && _generator.isBufferEmpty())
_endp.close();
else if (_endp.isInputShutdown() && !_closedIn)
@@ -334,7 +306,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
_generator.addFrame((byte)0x8,WebSocketConnectionD06.OP_TEXT,data,0,data.length);
_generator.flush();
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -345,7 +316,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
_generator.addFrame((byte)0x8,WebSocketConnectionD06.OP_BINARY,content,offset,length);
_generator.flush();
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -356,7 +326,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
_generator.addFrame(flags,opcode,content,offset,length);
_generator.flush();
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -367,7 +336,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
_generator.addFrame((byte)0x8,control,data,offset,length);
_generator.flush();
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -511,7 +479,7 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
{
close();
}
-
+
/* ------------------------------------------------------------ */
public void close()
{
@@ -713,10 +681,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
}
}
}
- catch(ThreadDeath th)
- {
- throw th;
- }
catch(Throwable th)
{
LOG.warn(th);
@@ -736,12 +700,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
}
/* ------------------------------------------------------------ */
- private interface IdleCheck
- {
- void access(EndPoint endp);
- }
-
- /* ------------------------------------------------------------ */
public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
{
String key = request.getHeader("Sec-WebSocket-Key");
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD08.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD08.java
index 782a1a2366..9839a554a3 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD08.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD08.java
@@ -77,7 +77,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
}
private final static byte[] MAGIC;
- private final IdleCheck _idle;
private final List<Extension> _extensions;
private final WebSocketParserD08 _parser;
private final WebSocketParser.FrameHandler _inbound;
@@ -130,9 +129,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
_context=Thread.currentThread().getContextClassLoader();
- if (endpoint instanceof AsyncEndPoint)
- ((AsyncEndPoint)endpoint).cancelIdle();
-
_draft=draft;
_endp.setMaxIdleTime(maxIdleTime);
@@ -164,27 +160,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
_protocol=protocol;
- if (_endp instanceof SelectChannelEndPoint)
- {
- final SelectChannelEndPoint scep=(SelectChannelEndPoint)_endp;
- scep.cancelIdle();
- _idle=new IdleCheck()
- {
- public void access(EndPoint endp)
- {
- scep.scheduleIdle();
- }
- };
- scep.scheduleIdle();
- }
- else
- {
- _idle = new IdleCheck()
- {
- public void access(EndPoint endp)
- {}
- };
- }
}
/* ------------------------------------------------------------ */
@@ -246,7 +221,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
_generator.returnBuffer();
if (_endp.isOpen())
{
- _idle.access(_endp);
if (_closedIn && _closedOut && _outbound.isBufferEmpty())
_endp.close();
else if (_endp.isInputShutdown() && !_closedIn)
@@ -417,7 +391,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
byte[] data = content.getBytes(StringUtil.__UTF8);
_outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD08.OP_TEXT,data,0,data.length);
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -427,7 +400,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
_outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD08.OP_BINARY,content,offset,length);
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -437,7 +409,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
_outbound.addFrame(flags,opcode,content,offset,length);
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -447,7 +418,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
_outbound.addFrame((byte)FLAG_FIN,ctrl,data,offset,length);
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -585,13 +555,13 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
{
return opcode==OP_PONG;
}
-
+
/* ------------------------------------------------------------ */
public void disconnect()
{
close();
}
-
+
/* ------------------------------------------------------------ */
public void close()
{
@@ -786,10 +756,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
}
}
}
- catch(ThreadDeath th)
- {
- throw th;
- }
catch(Throwable th)
{
LOG.warn(th);
@@ -835,12 +801,6 @@ public class WebSocketConnectionD08 extends AbstractConnection implements WebSoc
}
/* ------------------------------------------------------------ */
- private interface IdleCheck
- {
- void access(EndPoint endp);
- }
-
- /* ------------------------------------------------------------ */
public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
{
String key = request.getHeader("Sec-WebSocket-Key");
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD13.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD13.java
index 079b3cfa20..7525ff1446 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD13.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketConnectionD13.java
@@ -67,7 +67,7 @@ import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;
public class WebSocketConnectionD13 extends AbstractConnection implements WebSocketConnection
{
private static final Logger LOG = Log.getLogger(WebSocketConnectionD13.class);
-
+
final static byte OP_CONTINUATION = 0x00;
final static byte OP_TEXT = 0x01;
final static byte OP_BINARY = 0x02;
@@ -106,7 +106,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
}
private final static byte[] MAGIC;
- private final IdleCheck _idle;
private final List<Extension> _extensions;
private final WebSocketParserD13 _parser;
private final WebSocketGeneratorD13 _generator;
@@ -156,9 +155,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
_context=Thread.currentThread().getContextClassLoader();
- if (endpoint instanceof AsyncEndPoint)
- ((AsyncEndPoint)endpoint).cancelIdle();
-
_draft=draft;
_endp.setMaxIdleTime(maxIdleTime);
@@ -191,28 +187,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
_protocol=protocol;
- // TODO should these be AsyncEndPoint checks/calls?
- if (_endp instanceof SelectChannelEndPoint)
- {
- final SelectChannelEndPoint scep=(SelectChannelEndPoint)_endp;
- scep.cancelIdle();
- _idle=new IdleCheck()
- {
- public void access(EndPoint endp)
- {
- scep.scheduleIdle();
- }
- };
- scep.scheduleIdle();
- }
- else
- {
- _idle = new IdleCheck()
- {
- public void access(EndPoint endp)
- {}
- };
- }
}
/* ------------------------------------------------------------ */
@@ -247,7 +221,9 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
int filled=_parser.parseNext();
progress = flushed>0 || filled>0;
-
+
+ _endp.flush();
+
if (_endp instanceof AsyncEndPoint && ((AsyncEndPoint)_endp).hasProgressed())
progress=true;
}
@@ -272,7 +248,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
_generator.returnBuffer();
if (_endp.isOpen())
{
- _idle.access(_endp);
if (_closedIn && _closedOut && _outbound.isBufferEmpty())
_endp.close();
else if (_endp.isInputShutdown() && !_closedIn)
@@ -290,7 +265,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
if (!_closedIn)
_endp.close();
}
-
+
/* ------------------------------------------------------------ */
public boolean isIdle()
{
@@ -388,12 +363,12 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
{
// Close code 1005/1006 are never to be sent as a status over
// a Close control frame. Code<-1 also means no node.
-
+
if (code<0 || (code == WebSocketConnectionD13.CLOSE_NO_CODE) || code==WebSocketConnectionD13.CLOSE_NO_CLOSE)
code=-1;
else if (code==0)
code=WebSocketConnectionD13.CLOSE_NORMAL;
-
+
byte[] bytes = ("xx"+(message==null?"":message)).getBytes(StringUtil.__ISO_8859_1);
bytes[0]=(byte)(code/0x100);
bytes[1]=(byte)(code%0x100);
@@ -438,7 +413,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
byte[] data = content.getBytes(StringUtil.__UTF8);
_outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD13.OP_TEXT,data,0,data.length);
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -448,7 +422,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
_outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD13.OP_BINARY,content,offset,length);
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -458,18 +431,16 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
_outbound.addFrame(flags,opcode,content,offset,length);
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
public void sendControl(byte ctrl, byte[] data, int offset, int length) throws IOException
{
- // TODO: section 5.5 states that control frames MUST never be length > 125 bytes and MUST NOT be fragmented
+ // TODO: section 5.5 states that control frames MUST never be length > 125 bytes and MUST NOT be fragmented
if (_closedOut)
throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
_outbound.addFrame((byte)FLAG_FIN,ctrl,data,offset,length);
checkWriteable();
- _idle.access(_endp);
}
/* ------------------------------------------------------------ */
@@ -613,7 +584,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
{
close(CLOSE_NORMAL,null);
}
-
+
/* ------------------------------------------------------------ */
public void close()
{
@@ -653,7 +624,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
public void onFrame(final byte flags, final byte opcode, final Buffer buffer)
{
boolean lastFrame = isLastFrame(flags);
-
+
synchronized(WebSocketConnectionD13.this)
{
// Ignore incoming after a close
@@ -682,7 +653,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
{
return;
}
-
+
// Deliver frame if websocket is a FrameWebSocket
if (_onFrame!=null)
{
@@ -695,7 +666,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
if (_onControl.onControl(opcode,array,buffer.getIndex(),buffer.length()))
return;
}
-
+
switch(opcode)
{
case WebSocketConnectionD13.OP_CONTINUATION:
@@ -705,7 +676,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
errorClose(WebSocketConnectionD13.CLOSE_PROTOCOL,"Bad Continuation");
return;
}
-
+
// If text, append to the message buffer
if (_onTextMessage!=null && _opcode==WebSocketConnectionD13.OP_TEXT)
{
@@ -750,7 +721,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
case WebSocketConnectionD13.OP_PING:
{
LOG.debug("PING {}",this);
- if (!_closedOut)
+ if (!_closedOut)
{
_connection.sendControl(WebSocketConnectionD13.OP_PONG,buffer.array(),buffer.getIndex(),buffer.length());
}
@@ -770,10 +741,10 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
if (buffer.length()>=2)
{
code=(0xff&buffer.array()[buffer.getIndex()])*0x100+(0xff&buffer.array()[buffer.getIndex()+1]);
-
+
// Validate close status codes.
if (code < WebSocketConnectionD13.CLOSE_NORMAL ||
- code == WebSocketConnectionD13.CLOSE_UNDEFINED ||
+ code == WebSocketConnectionD13.CLOSE_UNDEFINED ||
code == WebSocketConnectionD13.CLOSE_NO_CLOSE ||
code == WebSocketConnectionD13.CLOSE_NO_CODE ||
( code > 1010 && code <= 2999 ) ||
@@ -782,8 +753,8 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
errorClose(WebSocketConnectionD13.CLOSE_PROTOCOL,"Invalid close code " + code);
return;
}
-
- if (buffer.length()>2)
+
+ if (buffer.length()>2)
{
if(_utf8.append(buffer.array(),buffer.getIndex()+2,buffer.length()-2,_connection.getMaxTextMessageSize()))
{
@@ -791,10 +762,10 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
_utf8.reset();
}
}
- }
+ }
else if(buffer.length() == 1)
{
- // Invalid length. use status code 1002 (Protocol error)
+ // Invalid length. use status code 1002 (Protocol error)
errorClose(WebSocketConnectionD13.CLOSE_PROTOCOL,"Invalid payload length of 1");
return;
}
@@ -809,7 +780,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
errorClose(WebSocketConnectionD13.CLOSE_PROTOCOL,"Expected Continuation"+Integer.toHexString(opcode));
return;
}
-
+
if(_onTextMessage!=null)
{
if (_connection.getMaxTextMessageSize()<=0)
@@ -842,7 +813,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
}
break;
}
-
+
case WebSocketConnectionD13.OP_BINARY:
{
if (_opcode!=-1)
@@ -850,7 +821,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
errorClose(WebSocketConnectionD13.CLOSE_PROTOCOL,"Expected Continuation"+Integer.toHexString(opcode));
return;
}
-
+
if (_onBinaryMessage!=null && checkBinaryMessageSize(0,buffer.length()))
{
if (lastFrame)
@@ -876,13 +847,9 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
default:
errorClose(WebSocketConnectionD13.CLOSE_PROTOCOL,"Bad opcode 0x"+Integer.toHexString(opcode));
- return;
+ break;
}
}
- catch(ThreadDeath th)
- {
- throw th;
- }
catch(Utf8Appendable.NotUtf8Exception notUtf8)
{
LOG.warn("{} for {}",notUtf8,_endp);
@@ -900,7 +867,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
private void errorClose(int code, String message)
{
_connection.close(code,message);
-
+
// Brutally drop the connection
try
{
@@ -912,7 +879,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
LOG.debug(e);
}
}
-
+
private boolean checkBinaryMessageSize(int bufferLen, int length)
{
int max = _connection.getMaxBinaryMessageSize();
@@ -950,13 +917,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
return WebSocketConnectionD13.this.toString()+"FH";
}
}
-
- /* ------------------------------------------------------------ */
- private interface IdleCheck
- {
- void access(EndPoint endp);
- }
-
+
/* ------------------------------------------------------------ */
public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
{
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java
index e339d082b8..ed663826e3 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketFactory.java
@@ -28,6 +28,7 @@ import org.eclipse.jetty.http.HttpException;
import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.io.ConnectedEndPoint;
import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.BlockingHttpConnection;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -195,6 +196,8 @@ public class WebSocketFactory
if (draft < 0)
draft = request.getIntHeader("Sec-WebSocket-Draft");
AbstractHttpConnection http = AbstractHttpConnection.getCurrentConnection();
+ if (http instanceof BlockingHttpConnection)
+ throw new IllegalStateException("Websockets not supported on blocking connectors");
ConnectedEndPoint endp = (ConnectedEndPoint)http.getEndPoint();
List<String> extensions_requested = new ArrayList<String>();
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD13.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD13.java
index 6e9bfd599b..0ed3e7c02a 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD13.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketGeneratorD13.java
@@ -18,7 +18,6 @@ import java.io.IOException;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
-import org.eclipse.jetty.util.TypeUtil;
/* ------------------------------------------------------------ */
diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD13.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD13.java
index 710ace6738..f57c4976f5 100644
--- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD13.java
+++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketParserD13.java
@@ -18,7 +18,6 @@ import java.io.IOException;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketClientTest.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketClientTest.java
index f8029ffb11..80042a9763 100644
--- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketClientTest.java
+++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketClientTest.java
@@ -1,6 +1,6 @@
package org.eclipse.jetty.websocket;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.greaterThan;
import java.io.BufferedReader;
import java.io.IOException;
diff --git a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD13Test.java b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD13Test.java
index 9c2ad777e4..4fb5fe2096 100644
--- a/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD13Test.java
+++ b/jetty-websocket/src/test/java/org/eclipse/jetty/websocket/WebSocketMessageD13Test.java
@@ -1,6 +1,8 @@
package org.eclipse.jetty.websocket;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.io.EOFException;
import java.io.IOException;
@@ -19,7 +21,6 @@ import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
-import org.eclipse.jetty.io.nio.ChannelEndPoint;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
index c14e804696..6da0355acf 100644
--- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
+++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
@@ -4,11 +4,11 @@
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
-// The Eclipse Public License is available at
+// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
-// You may elect to redistribute this code under either of these licenses.
+// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.xml;
@@ -53,11 +53,11 @@ import org.xml.sax.SAXException;
/**
* Configure Objects from XML. This class reads an XML file conforming to the configure.dtd DTD and uses it to configure and object by calling set, put or other
* methods on the object.
- *
+ *
* <p>
* The actual XML file format may be changed (eg to spring XML) by implementing the {@link ConfigurationProcessorFactory} interfaces to be found by the
* <code>ServiceLoader</code> by using the DTD and first tag element in the file. Note that DTD will be null if validation is off.
- *
+ *
*/
public class XmlConfiguration
{
@@ -69,7 +69,7 @@ public class XmlConfiguration
private static final Class<?>[] __primitiveHolders =
{ Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class };
private static final Integer ZERO = new Integer(0);
-
+
private static final Iterable<?> __factoryLoader;
static
{
@@ -77,7 +77,7 @@ public class XmlConfiguration
try
{
// Use reflection to look up 1.6 service loader
- // loader=ServiceLoader.load(ConfigurationProcessorFactory.class);
+ // loader=ServiceLoader.load(ConfigurationProcessorFactory.class);
Class<?> slc = ClassLoader.getSystemClassLoader().loadClass("java.util.ServiceLoader");
Method load = slc.getMethod("load",Class.class);
loader=(Iterable<?>)load.invoke(null,ConfigurationProcessorFactory.class);
@@ -90,7 +90,7 @@ public class XmlConfiguration
{
__factoryLoader=loader;
}
- }
+ }
/* ------------------------------------------------------------ */
private static XmlParser __parser;
@@ -135,7 +135,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */
/**
* Constructor. Reads the XML configuration file.
- *
+ *
* @param configuration
*/
public XmlConfiguration(URL configuration) throws SAXException, IOException
@@ -152,7 +152,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */
/**
* Constructor.
- *
+ *
* @param configuration
* String of XML configuration commands excluding the normal XML preamble. The String should start with a " <Configure ...." element.
* @exception SAXException
@@ -170,11 +170,11 @@ public class XmlConfiguration
_dtd=__parser.getDTD();
}
}
-
+
/* ------------------------------------------------------------ */
/**
* Constructor.
- *
+ *
* @param configuration
* An input stream containing a complete e.g. configuration file
* @exception SAXException
@@ -217,7 +217,7 @@ public class XmlConfiguration
if (_processor!=null)
break;
}
-
+
if (_processor==null)
throw new IllegalStateException("Unknown configuration type: "+config.getTag()+" in "+this);
}
@@ -227,7 +227,7 @@ public class XmlConfiguration
}
_processor.init(_url,_config,_idMap, _propertyMap);
}
-
+
/* ------------------------------------------------------------ */
public Map<String, Object> getIdMap()
@@ -263,13 +263,13 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */
/**
- * Configure an object.
+ * Configure an object.
*
* <p>Apply the XML configuration script to the passed object.</p>
- *
+ *
* @param obj
* The object to be configured, which must be of a type or super type of the class attribute of the Configure element.
- * @exception Exception
+ * @exception Exception
*/
public Object configure(Object obj) throws Exception
{
@@ -279,7 +279,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */
/**
* Configure an object. If the configuration has an ID, an object is looked up by ID and it's type check. Otherwise a new object is created.
- *
+ *
* @return The newly created configured object.
* @exception Exception
*/
@@ -335,7 +335,7 @@ public class XmlConfiguration
configure(obj,_config,0);
return obj;
}
-
+
/* ------------------------------------------------------------ */
private Class<?> nodeClass(XmlParser.Node node) throws ClassNotFoundException
{
@@ -345,11 +345,11 @@ public class XmlConfiguration
return Loader.loadClass(XmlConfiguration.class,className,true);
}
-
+
/* ------------------------------------------------------------ */
/**
* Recursive configuration step. This method applies the remaining Set, Put and Call elements to the current object.
- *
+ *
* @param obj
* @param cfg
* @param i
@@ -403,7 +403,7 @@ public class XmlConfiguration
* Call a set method. This method makes a best effort to find a matching set method. The type of the value is used to find a suitable set method by 1.
* Trying for a trivial type match. 2. Looking for a native type match. 3. Trying all correctly named methods for an auto conversion. 4. Attempting to
* construct a suitable value from original value. @param obj
- *
+ *
* @param node
*/
private void set(Object obj, XmlParser.Node node) throws Exception
@@ -583,7 +583,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */
/*
* Call a put method.
- *
+ *
* @param obj @param node
*/
private void put(Object obj, XmlParser.Node node) throws Exception
@@ -602,7 +602,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */
/*
* Call a get method. Any object returned from the call is passed to the configure method to consume the remaining elements. @param obj @param node
- *
+ *
* @return @exception Exception
*/
private Object get(Object obj, XmlParser.Node node) throws Exception
@@ -648,7 +648,7 @@ public class XmlConfiguration
* Call a method. A method is selected by trying all methods with matching names and number of arguments. Any object returned from the call is passed to
* the configure method to consume the remaining elements. Note that if this is a static call we consider only methods declared directly in the given
* class. i.e. we ignore any static methods in superclasses. @param obj
- *
+ *
* @param node @return @exception Exception
*/
private Object call(Object obj, XmlParser.Node node) throws Exception
@@ -710,7 +710,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */
/*
* Create a new value object.
- *
+ *
* @param obj @param node @return @exception Exception
*/
private Object newObj(Object obj, XmlParser.Node node) throws Exception
@@ -785,7 +785,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */
/*
* Reference an id value object.
- *
+ *
* @param obj @param node @return @exception NoSuchMethodException @exception ClassNotFoundException @exception InvocationTargetException
*/
private Object refObj(Object obj, XmlParser.Node node) throws Exception
@@ -903,7 +903,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */
/*
* Create a new value object.
- *
+ *
* @param obj @param node @return @exception Exception
*/
private Object propertyObj(Object obj, XmlParser.Node node) throws Exception
@@ -1113,7 +1113,7 @@ public class XmlConfiguration
* <p>
* Any IDs created in a configuration are passed to the next configuration file on the command line using {@link #getIdMap()} and {@link #setIdMap(Map)} .
* This allows objects with IDs created in one config file to be referenced in subsequent config files on the command line.
- *
+ *
* @param args
* array of property and xml configuration filenames or {@link Resource}s.
*/
@@ -1221,16 +1221,13 @@ public class XmlConfiguration
Throwable th = exception.get();
if (th != null)
{
- if (th instanceof Exception)
+ if (th instanceof RuntimeException)
+ throw (RuntimeException)th;
+ else if (th instanceof Exception)
throw (Exception)th;
else if (th instanceof Error)
throw (Error)th;
- else if (th instanceof RuntimeException)
- throw (RuntimeException)th;
- else if (th instanceof ThreadDeath)
- throw (ThreadDeath)th;
throw new Error(th);
}
}
-
}
diff --git a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java
index c7b63308be..ea894ef4fe 100644
--- a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java
+++ b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/HttpTester.java
@@ -26,6 +26,7 @@ import org.eclipse.jetty.http.HttpVersions;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.io.View;
import org.eclipse.jetty.io.bio.StringEndPoint;
@@ -130,15 +131,32 @@ public class HttpTester
* @return Any unparsed data in the rawHTTP (eg pipelined requests)
* @throws IOException
*/
- public String parse(String rawHTTP) throws IOException
+ public String parse(String rawHTTP, boolean isHeadResponse) throws IOException
{
_charset = _defaultCharset;
ByteArrayBuffer buf = new ByteArrayBuffer(getByteArray(rawHTTP));
View view = new View(buf);
- HttpParser parser = new HttpParser(view,new PH());
+ PH ph = new PH();
+ HttpParser parser = new HttpParser(view,ph);
+ parser.setHeadResponse(isHeadResponse);
parser.parse();
+ if (ph.isEarlyEOF())
+ throw new EofException();
return getString(view.asArray());
}
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Parse one HTTP request or response
+ * @param rawHTTP Raw HTTP to parse
+ * @return Any unparsed data in the rawHTTP (eg pipelined requests)
+ * @throws IOException
+ */
+ public String parse(String rawHTTP) throws IOException
+ {
+ return parse(rawHTTP, false);
+ }
/* ------------------------------------------------------------ */
/**
@@ -147,17 +165,33 @@ public class HttpTester
* @return Any unparsed data in the rawHTTP (eg pipelined requests)
* @throws IOException
*/
- public byte[] parse(byte[] rawHTTP) throws IOException
+ public byte[] parse(byte[] rawHTTP, boolean isHeadResponse) throws IOException
{
_charset = _defaultCharset;
ByteArrayBuffer buf = new ByteArrayBuffer(rawHTTP);
View view = new View(buf);
- HttpParser parser = new HttpParser(view,new PH());
+ PH ph = new PH();
+ HttpParser parser = new HttpParser(view,ph);
+ parser.setHeadResponse(isHeadResponse);
parser.parse();
+ if (ph.isEarlyEOF())
+ throw new EofException();
return view.asArray();
}
/* ------------------------------------------------------------ */
+ /**
+ * Parse one HTTP request or response
+ * @param rawHTTP Raw HTTP to parse
+ * @return Any unparsed data in the rawHTTP (eg pipelined requests)
+ * @throws IOException
+ */
+ public byte[] parse(byte[] rawHTTP) throws IOException
+ {
+ return parse(rawHTTP, false);
+ }
+
+ /* ------------------------------------------------------------ */
public String generate() throws IOException
{
_charset = _defaultCharset;
@@ -484,6 +518,8 @@ public class HttpTester
/* ------------------------------------------------------------ */
private class PH extends HttpParser.EventHandler
{
+ private volatile boolean _earlyEOF;
+
@Override
public void startRequest(Buffer method, Buffer url, Buffer version) throws IOException
{
@@ -532,6 +568,18 @@ public class HttpTester
_parsedContent=new ByteArrayOutputStream2();
_parsedContent.write(ref.asArray());
}
+
+ @Override
+ public void earlyEOF()
+ {
+ _earlyEOF = true;
+ }
+
+ public boolean isEarlyEOF()
+ {
+ return _earlyEOF;
+ }
+
}
}
diff --git a/test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/HttpTesterTest.java b/test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/HttpTesterTest.java
index b019d34da7..b12ea713cc 100644
--- a/test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/HttpTesterTest.java
+++ b/test-jetty-servlet/src/test/java/org/eclipse/jetty/testing/HttpTesterTest.java
@@ -36,5 +36,21 @@ public class HttpTesterTest extends TestCase
assertEquals("utf-8",tester.getCharacterEncoding());
assertEquals("123456789\uA74A",tester.getContent());
}
+
+
+ public void testHead() throws Exception
+ {
+ String headResponse = "HTTP/1.1 200 OK\r\n"+
+ "Content-Type: text/html\r\n"+
+ "Content-Length: 22\r\n"+
+ "\r\n";
+
+ HttpTester tester = new HttpTester();
+ tester.parse(headResponse, true);
+ assertEquals(200, tester.getStatus());
+ assertEquals("22", tester.getHeader("Content-Length"));
+ assertEquals("text/html",tester.getContentType());
+ System.err.println(tester.getContent());
+ }
}
diff --git a/test-jetty-webapp/src/main/java/com/acme/Dump.java b/test-jetty-webapp/src/main/java/com/acme/Dump.java
index 637d51b268..fbb3c13be9 100644
--- a/test-jetty-webapp/src/main/java/com/acme/Dump.java
+++ b/test-jetty-webapp/src/main/java/com/acme/Dump.java
@@ -28,6 +28,8 @@ import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
+import java.util.Timer;
+import java.util.TimerTask;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
@@ -64,6 +66,7 @@ public class Dump extends HttpServlet
private static final Logger LOG = Log.getLogger(Dump.class);
boolean fixed;
+ Timer _timer;
/* ------------------------------------------------------------ */
@Override
@@ -77,6 +80,8 @@ public class Dump extends HttpServlet
fixed=true;
throw new UnavailableException("Unavailable test",Integer.parseInt(config.getInitParameter("unavailable")));
}
+
+ _timer=new Timer(true);
}
/* ------------------------------------------------------------ */
@@ -180,54 +185,39 @@ public class Dump extends HttpServlet
request.setAttribute("RESUME",Boolean.TRUE);
final long resume=Long.parseLong(request.getParameter("resume"));
- new Thread(new Runnable()
+ final Continuation continuation = ContinuationSupport.getContinuation(request);
+ _timer.schedule(new TimerTask()
{
+ @Override
public void run()
{
- try
- {
- Thread.sleep(resume);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- Continuation continuation = ContinuationSupport.getContinuation(request);
continuation.resume();
}
-
- }).start();
+ },resume);
+
}
if (request.getParameter("complete")!=null)
{
final long complete=Long.parseLong(request.getParameter("complete"));
- new Thread(new Runnable()
+ _timer.schedule(new TimerTask()
{
+ @Override
public void run()
{
try
{
- Thread.sleep(complete);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- try
- {
response.setContentType("text/html");
response.getOutputStream().println("<h1>COMPLETED</h1>");
Continuation continuation = ContinuationSupport.getContinuation(request);
continuation.complete();
}
- catch (IOException e)
+ catch(Exception e)
{
e.printStackTrace();
}
}
-
- }).start();
+ },complete);
}
if (request.getParameter("suspend")!=null && request.getAttribute("SUSPEND")!=Boolean.TRUE)
@@ -808,7 +798,7 @@ public class Dump extends HttpServlet
}
catch (Exception e)
{
- getServletContext().log("dump", e);
+ getServletContext().log("dump "+e);
}
String lines= request.getParameter("lines");
@@ -851,6 +841,7 @@ public class Dump extends HttpServlet
@Override
public synchronized void destroy()
{
+ _timer.cancel();
}
/* ------------------------------------------------------------ */

Back to the top