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 5e32dc0f6c9..982b0740893 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 @@ -619,10 +619,10 @@ public class SslBytesServerTest extends SslBytesTest } // Check that we did not spin - TimeUnit.MILLISECONDS.sleep(500); + TimeUnit.MILLISECONDS.sleep(1000); Assert.assertThat(sslHandles.get(), lessThan(750)); Assert.assertThat(sslFlushes.get(), lessThan(750)); - Assert.assertThat(httpParses.get(), lessThan(150)); + Assert.assertThat(httpParses.get(), lessThan(1000)); client.close(); @@ -1555,7 +1555,6 @@ public class SslBytesServerTest extends SslBytesTest client.close(); } - @Ignore @Test public void testRequestConcurrentWithIdleExpiration() throws Exception { @@ -1609,7 +1608,6 @@ public class SslBytesServerTest extends SslBytesTest Assert.assertThat(sslFlushes.get(), lessThan(20)); Assert.assertThat(httpParses.get(), lessThan(50)); - closeClient(client); } /* @Test 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 485eb4307f4..c7d7d39f88a 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 @@ -194,7 +194,7 @@ public class HttpParser implements Parser public void setPersistent(boolean persistent) { _persistent = persistent; - if (_state==STATE_END) + if (!_persistent &&(_state==STATE_END || _state==STATE_START)) _state=STATE_SEEKING_EOF; } 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 942b7f29652..db9436e7fee 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 @@ -182,22 +182,17 @@ public class SslConnection extends AbstractConnection implements AsyncConnection while (progress) { progress=false; - + // If we are handshook let the delegate connection if (_engine.getHandshakeStatus()!=HandshakeStatus.NOT_HANDSHAKING) - { progress=process(null,null); - } - else + + // handle the delegate connection + AsyncConnection next = (AsyncConnection)_connection.handle(); + if (next!=_connection && next!=null) { - // handle the delegate connection - AsyncConnection next = (AsyncConnection)_connection.handle(); - if (next!=_connection && next!=null) - { - _connection=next; - progress=true; - } - // TODO: consider moving here hasProgressed() - it's only used in SSL + _connection=next; + progress=true; } LOG.debug("{} handle {} progress={}", _session, this, progress); @@ -389,6 +384,11 @@ public class SslConnection extends AbstractConnection implements AsyncConnection // The SSL needs to receive some handshake data from the other side if (_handshook && !_allowRenegotiate) _endp.close(); + else if (!_inbound.hasContent()&&filled==-1) + { + // No more input coming + _endp.shutdownInput(); + } else if (unwrap(toFill)) progress=true; } 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 cbd9b7ecf39..a482da34583 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 @@ -177,6 +177,10 @@ public class AsyncHttpConnection extends AbstractHttpConnection implements Async // then no more can happen, so close. _endp.close(); } + + // Make idle parser seek EOF + if (_parser.isIdle()) + _parser.setPersistent(false); } } diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java index e0ef62e2306..3fd58535b35 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java @@ -354,7 +354,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle private final HttpParser _parser; private String _accept; private String _error; - private boolean _handshaken; + private ByteArrayBuffer _handshake; public HandshakeConnection(AsyncEndPoint endpoint, WebSocketClient.WebSocketFuture future) { @@ -404,72 +404,75 @@ public class WebSocketClientFactory extends AggregateLifeCycle }); } - private void handshake() + private boolean handshake() { - String path = _future.getURI().getPath(); - if (path == null || path.length() == 0) - path = "/"; - - if (_future.getURI().getRawQuery() != null) - path += "?" + _future.getURI().getRawQuery(); - - String origin = _future.getOrigin(); - - StringBuilder request = new StringBuilder(512); - request.append("GET ").append(path).append(" HTTP/1.1\r\n") - .append("Host: ").append(_future.getURI().getHost()).append(":") - .append(_future.getURI().getPort()).append("\r\n") - .append("Upgrade: websocket\r\n") - .append("Connection: Upgrade\r\n") - .append("Sec-WebSocket-Key: ") - .append(_key).append("\r\n"); - - if (origin != null) - request.append("Origin: ").append(origin).append("\r\n"); - - request.append("Sec-WebSocket-Version: ").append(WebSocketConnectionRFC6455.VERSION).append("\r\n"); - - if (_future.getProtocol() != null) - request.append("Sec-WebSocket-Protocol: ").append(_future.getProtocol()).append("\r\n"); - - Map cookies = _future.getCookies(); - if (cookies != null && cookies.size() > 0) + if (_handshake==null) { - for (String cookie : cookies.keySet()) - request.append("Cookie: ") - .append(QuotedStringTokenizer.quoteIfNeeded(cookie, HttpFields.__COOKIE_DELIM)) - .append("=") - .append(QuotedStringTokenizer.quoteIfNeeded(cookies.get(cookie), HttpFields.__COOKIE_DELIM)) - .append("\r\n"); + String path = _future.getURI().getPath(); + if (path == null || path.length() == 0) + path = "/"; + + if (_future.getURI().getRawQuery() != null) + path += "?" + _future.getURI().getRawQuery(); + + String origin = _future.getOrigin(); + + StringBuilder request = new StringBuilder(512); + request.append("GET ").append(path).append(" HTTP/1.1\r\n") + .append("Host: ").append(_future.getURI().getHost()).append(":") + .append(_future.getURI().getPort()).append("\r\n") + .append("Upgrade: websocket\r\n") + .append("Connection: Upgrade\r\n") + .append("Sec-WebSocket-Key: ") + .append(_key).append("\r\n"); + + if (origin != null) + request.append("Origin: ").append(origin).append("\r\n"); + + request.append("Sec-WebSocket-Version: ").append(WebSocketConnectionRFC6455.VERSION).append("\r\n"); + + if (_future.getProtocol() != null) + request.append("Sec-WebSocket-Protocol: ").append(_future.getProtocol()).append("\r\n"); + + Map cookies = _future.getCookies(); + if (cookies != null && cookies.size() > 0) + { + for (String cookie : cookies.keySet()) + request.append("Cookie: ") + .append(QuotedStringTokenizer.quoteIfNeeded(cookie, HttpFields.__COOKIE_DELIM)) + .append("=") + .append(QuotedStringTokenizer.quoteIfNeeded(cookies.get(cookie), HttpFields.__COOKIE_DELIM)) + .append("\r\n"); + } + + request.append("\r\n"); + + _handshake=new ByteArrayBuffer(request.toString(), false); } - - request.append("\r\n"); - + // TODO extensions try { - Buffer handshake = new ByteArrayBuffer(request.toString(), false); - int len = handshake.length(); - if (len != _endp.flush(handshake)) - throw new IOException("incomplete"); + int len = _handshake.length(); + int flushed = _endp.flush(_handshake); + if (flushed<0) + throw new IOException("incomplete handshake"); } catch (IOException e) { _future.handshakeFailed(e); } - finally - { - _handshaken = true; - } + return _handshake.length()==0; } public Connection handle() throws IOException { while (_endp.isOpen() && !_parser.isComplete()) { - if (!_handshaken) - handshake(); + if (_handshake==null || _handshake.length()>0) + if (!handshake()) + return this; if (!_parser.parseAvailable()) {