From 01af85db42f0adfd54d0b398af3c681ad7b7a64d Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 14 Aug 2019 14:57:21 +0200 Subject: [PATCH 01/77] Issue #3537 - Bootstrapping WebSockets with HTTP/2. Implemented upgrade logic for WebSocket over HTTP/2. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/client/HttpRequest.java | 12 + .../eclipse/jetty/client/HttpUpgrader.java | 34 +++ .../client/http/HttpChannelOverHTTP.java | 34 ++- .../client/http/HttpConnectionOverHTTP.java | 9 + .../client/http/HttpReceiverOverHTTP.java | 3 +- .../java/org/eclipse/jetty/http/MetaData.java | 5 + .../jetty/http2/hpack/MetaDataBuilder.java | 12 +- .../client/http/HttpConnectionOverHTTP2.java | 14 + .../client/http/HttpReceiverOverHTTP2.java | 8 +- .../client/http/HttpSenderOverHTTP2.java | 11 +- .../http2/server/HttpTransportOverHTTP2.java | 2 + .../jetty/server/HttpChannelOverHttp.java | 6 + .../client/JavaxClientUpgradeRequest.java | 6 +- .../websocket/javax/tests/LocalFuzzer.java | 3 +- .../websocket/javax/tests/NetworkFuzzer.java | 4 +- .../websocket/javax/tests/UpgradeUtils.java | 28 +- .../server/AnnotatedServerEndpointTest.java | 8 +- .../test/resources/jetty-logging.properties | 2 +- .../jetty/websocket/api/UpgradeRequest.java | 28 -- .../client/ClientUpgradeRequest.java | 35 +-- .../DelegatedJettyClientUpgradeRequest.java | 18 -- .../impl/JettyClientUpgradeRequest.java | 11 +- .../common/handshake/DummyUpgradeRequest.java | 18 -- .../internal/UpgradeRequestAdapter.java | 18 -- jetty-websocket/jetty-websocket-tests/pom.xml | 17 +- .../jetty/websocket/tests/EventSocket.java | 10 +- .../tests/WebSocketOverHTTP2Test.java | 131 +++++++++ .../test/resources/jetty-logging.properties | 64 ++--- .../core/client/ClientUpgradeRequest.java | 183 +++++-------- .../core/client/HttpUpgraderOverHTTP.java | 86 ++++++ .../core/client/HttpUpgraderOverHTTP2.java | 51 ++++ .../websocket/core/server/Handshaker.java | 11 +- .../server/internal/HandshakerSelector.java | 58 ++++ .../server/internal/RFC8441Handshaker.java | 249 ++++++++++++++++++ .../server/internal/RFC8441Negotiation.java | 44 ++++ 35 files changed, 870 insertions(+), 363 deletions(-) create mode 100644 jetty-client/src/main/java/org/eclipse/jetty/client/HttpUpgrader.java create mode 100644 jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java create mode 100644 jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java create mode 100644 jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java create mode 100644 jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java create mode 100644 jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java create mode 100644 jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java index 9230088e738..9a0282f644c 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java @@ -87,6 +87,7 @@ public class HttpRequest implements Request private List requestListeners; private BiFunction pushListener; private Supplier trailers; + private String upgradeProtocol; protected HttpRequest(HttpClient client, HttpConversation conversation, URI uri) { @@ -609,6 +610,12 @@ public class HttpRequest implements Request return this; } + public HttpRequest upgradeProtocol(String upgradeProtocol) + { + this.upgradeProtocol = upgradeProtocol; + return this; + } + @Override public ContentProvider getContent() { @@ -765,6 +772,11 @@ public class HttpRequest implements Request return trailers; } + public String getUpgradeProtocol() + { + return upgradeProtocol; + } + @Override public boolean abort(Throwable cause) { diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpUpgrader.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpUpgrader.java new file mode 100644 index 00000000000..cfc75d66899 --- /dev/null +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpUpgrader.java @@ -0,0 +1,34 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.client; + +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.io.EndPoint; + +public interface HttpUpgrader +{ + public void prepare(HttpRequest request); + + public void upgrade(HttpResponse response, EndPoint endPoint); + + public interface Factory + { + public HttpUpgrader newHttpUpgrader(HttpVersion version); + } +} diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java index 6bd8cd84d9d..b73ba238f98 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java @@ -26,6 +26,7 @@ import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpRequest; import org.eclipse.jetty.client.HttpResponse; import org.eclipse.jetty.client.HttpResponseException; +import org.eclipse.jetty.client.HttpUpgrader; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.http.HttpFields; @@ -98,29 +99,24 @@ public class HttpChannelOverHTTP extends HttpChannel return result; HttpResponse response = exchange.getResponse(); - - if ((response.getVersion() == HttpVersion.HTTP_1_1) && - (response.getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101)) + if (response.getVersion() == HttpVersion.HTTP_1_1 && response.getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101) { - String nextConnection = response.getHeaders().get(HttpHeader.CONNECTION); - if ((nextConnection == null) || !nextConnection.toLowerCase(Locale.US).contains("upgrade")) - { - return new Result(result, new HttpResponseException("101 Switching Protocols without Connection: Upgrade not supported", response)); - } + String header = response.getHeaders().get(HttpHeader.CONNECTION); + if (header == null || !header.toLowerCase(Locale.US).contains("upgrade")) + return new Result(result, new HttpResponseException("101 response without 'Connection: Upgrade'", response)); - // Upgrade Response HttpRequest request = exchange.getRequest(); - HttpConnectionUpgrader upgrader = (HttpConnectionUpgrader)request.getConversation().getAttribute(HttpConnectionUpgrader.class.getName()); - if (upgrader != null) + HttpUpgrader upgrader = (HttpUpgrader)request.getConversation().getAttribute(HttpUpgrader.class.getName()); + if (upgrader == null) + return new Result(result, new HttpResponseException("101 response without " + HttpUpgrader.class.getSimpleName(), response)); + + try { - try - { - upgrader.upgrade(response, getHttpConnection()); - } - catch (Throwable x) - { - return new Result(result, x); - } + upgrader.upgrade(response, getHttpConnection().getEndPoint()); + } + catch (Throwable x) + { + return new Result(result, new HttpResponseException("Could not upgrade to WebSocket", response, x)); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java index 12e98ade896..b70e0a2a1bc 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java @@ -30,11 +30,14 @@ import org.eclipse.jetty.client.HttpConnection; import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpProxy; +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpUpgrader; import org.eclipse.jetty.client.IConnection; import org.eclipse.jetty.client.SendFailure; import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.util.Promise; @@ -268,6 +271,12 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne request.timeout(connectTimeout, TimeUnit.MILLISECONDS) .idleTimeout(2 * connectTimeout, TimeUnit.MILLISECONDS); } + if (request instanceof HttpUpgrader.Factory) + { + HttpUpgrader upgrader = ((HttpUpgrader.Factory)request).newHttpUpgrader(HttpVersion.HTTP_1_1); + ((HttpRequest)request).getConversation().setAttribute(HttpUpgrader.class.getName(), upgrader); + upgrader.prepare((HttpRequest)request); + } } @Override diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java index 9febba733de..d32fc6deddb 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java @@ -333,8 +333,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res if (status == HttpStatus.SWITCHING_PROTOCOLS_101) return true; - if (HttpMethod.CONNECT.is(exchange.getRequest().getMethod()) && - status == HttpStatus.OK_200) + if (HttpMethod.CONNECT.is(exchange.getRequest().getMethod()) && status == HttpStatus.OK_200) return true; return false; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java index ec188fc2336..84a84f5be90 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java @@ -250,6 +250,11 @@ public class MetaData implements Iterable private String _protocol; public ConnectRequest(HttpScheme scheme, HostPortHttpField authority, String path, HttpFields fields, String protocol) + { + this(scheme == null ? null : scheme.asString(), authority, path, fields, protocol); + } + + public ConnectRequest(String scheme, HostPortHttpField authority, String path, HttpFields fields, String protocol) { super(HttpMethod.CONNECT.asString(), scheme, authority, path, HttpVersion.HTTP_2, fields, Long.MIN_VALUE); _protocol = protocol; diff --git a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java index cad98d49c59..0d788e302af 100644 --- a/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java +++ b/jetty-http2/http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/MetaDataBuilder.java @@ -175,22 +175,22 @@ public class MetaDataBuilder _contentLength = field.getLongValue(); _fields.add(field); break; - + case TE: if ("trailers".equalsIgnoreCase(value)) _fields.add(field); else streamException("Unsupported TE value '%s'", value); break; - + case CONNECTION: if ("TE".equalsIgnoreCase(value)) _fields.add(field); else streamException("Connection specific field '%s'", header); - break; + break; - default: + default: if (name.charAt(0) == ':') streamException("Unknown pseudo header '%s'", name); else @@ -236,7 +236,7 @@ public class MetaDataBuilder _streamException.addSuppressed(new Throwable()); throw _streamException; } - + if (_request && _response) throw new HpackException.StreamException("Request and Response headers"); @@ -266,7 +266,7 @@ public class MetaDataBuilder throw new HpackException.StreamException("No Status"); return new MetaData.Response(HttpVersion.HTTP_2, _status, fields, _contentLength); } - + return new MetaData(HttpVersion.HTTP_2, fields, _contentLength); } finally diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java index 34da1e8feae..20223e2aea7 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpConnectionOverHTTP2.java @@ -32,7 +32,9 @@ import org.eclipse.jetty.client.HttpConnection; import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpUpgrader; import org.eclipse.jetty.client.SendFailure; +import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http2.ErrorCode; import org.eclipse.jetty.http2.IStream; @@ -88,6 +90,18 @@ public class HttpConnectionOverHTTP2 extends HttpConnection implements Sweeper.S return send(channel, exchange); } + @Override + protected void normalizeRequest(Request request) + { + super.normalizeRequest(request); + if (request instanceof HttpUpgrader.Factory) + { + HttpUpgrader upgrader = ((HttpUpgrader.Factory)request).newHttpUpgrader(HttpVersion.HTTP_2); + ((HttpRequest)request).getConversation().setAttribute(HttpUpgrader.class.getName(), upgrader); + upgrader.prepare((HttpRequest)request); + } + } + protected HttpChannelOverHTTP2 acquireHttpChannel() { HttpChannelOverHTTP2 channel = idleChannels.poll(); diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java index afcc8ed7d63..0b2a5b7e78f 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java @@ -27,10 +27,12 @@ import java.util.Queue; import java.util.function.BiFunction; import org.eclipse.jetty.client.HttpChannel; +import org.eclipse.jetty.client.HttpConversation; import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpReceiver; import org.eclipse.jetty.client.HttpRequest; import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpUpgrader; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.http.HttpField; @@ -106,7 +108,11 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements HTTP2Channel. if (LOG.isDebugEnabled()) LOG.debug("Successful HTTP2 tunnel on {} via {}", stream, endPoint); ((IStream)stream).setAttachment(endPoint); - httpRequest.getConversation().setAttribute(EndPoint.class.getName(), endPoint); + HttpConversation conversation = httpRequest.getConversation(); + conversation.setAttribute(EndPoint.class.getName(), endPoint); + HttpUpgrader upgrader = (HttpUpgrader)conversation.getAttribute(HttpUpgrader.class.getName()); + if (upgrader != null) + upgrader.upgrade(httpResponse, endPoint); } if (responseHeaders(exchange)) diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java index ff2d71aca66..f4954db2641 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java @@ -59,7 +59,16 @@ public class HttpSenderOverHTTP2 extends HttpSender MetaData.Request metaData; if (isTunnel) { - metaData = new MetaData.Request(request.getMethod(), null, new HostPortHttpField(request.getPath()), null, HttpVersion.HTTP_2, request.getHeaders()); + String upgradeProtocol = request.getUpgradeProtocol(); + if (upgradeProtocol == null) + { + metaData = new MetaData.ConnectRequest((String)null, new HostPortHttpField(request.getPath()), null, request.getHeaders(), null); + } + else + { + HostPortHttpField authority = new HostPortHttpField(request.getHost(), request.getPort()); + metaData = new MetaData.ConnectRequest(request.getScheme(), authority, request.getPath(), request.getHeaders(), upgradeProtocol); + } } else { diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java index 1f53feba058..4f5f12852f4 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java @@ -340,6 +340,8 @@ public class HttpTransportOverHTTP2 implements HttpTransport Object attachment = stream.getAttachment(); if (attachment instanceof HttpChannelOverHTTP2) { + // TODO: we used to "fake" a 101 response to upgrade the endpoint + // but we don't anymore, so this code should be deleted. HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)attachment; if (channel.getResponse().getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java index 55243378512..d5935e5caac 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java @@ -407,6 +407,12 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque return true; } + @Override + protected void checkAndPrepareUpgrade() + { + // TODO: move the code from HttpConnection.upgrade() here? + } + /** *

Attempts to perform a HTTP/1.1 upgrade.

*

The upgrade looks up a {@link ConnectionFactory.Upgrading} from the connector diff --git a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxClientUpgradeRequest.java b/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxClientUpgradeRequest.java index d726e26cb8e..40d1a386c13 100644 --- a/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxClientUpgradeRequest.java +++ b/jetty-websocket/javax-websocket-client/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxClientUpgradeRequest.java @@ -21,7 +21,7 @@ package org.eclipse.jetty.websocket.javax.client; import java.net.URI; import org.eclipse.jetty.client.HttpResponse; -import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; +import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; @@ -43,11 +43,11 @@ public class JavaxClientUpgradeRequest extends ClientUpgradeRequest } @Override - public void upgrade(HttpResponse response, HttpConnectionOverHTTP httpConnection) + public void upgrade(HttpResponse response, EndPoint endPoint) { frameHandler.setUpgradeRequest(new DelegatedJavaxClientUpgradeRequest(this)); frameHandler.setUpgradeResponse(new DelegatedJavaxClientUpgradeResponse(response)); - super.upgrade(response, httpConnection); + super.upgrade(response, endPoint); } @Override diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java index c9c76778bf7..ede01bab693 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java +++ b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalFuzzer.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.javax.tests; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; @@ -53,7 +54,7 @@ public class LocalFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseable public LocalFuzzer(Provider provider, CharSequence requestPath) throws Exception { - this(provider, requestPath, UpgradeUtils.newDefaultUpgradeRequestHeaders()); + this(provider, requestPath, new HashMap<>()); } public LocalFuzzer(Provider provider, CharSequence requestPath, Map headers) throws Exception diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java index e57c86d9bd5..346a46503c2 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java +++ b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java @@ -208,9 +208,9 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab } @Override - protected void customize(EndPoint endp) + protected void customize(EndPoint endPoint) { - frameCapture.setEndPoint(endp); + frameCapture.setEndPoint(endPoint); futureCapture.complete(frameCapture); } diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java index 9e3995ed2b0..e8c177a1f39 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java +++ b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UpgradeUtils.java @@ -19,9 +19,6 @@ package org.eclipse.jetty.websocket.javax.tests; import java.util.Map; -import java.util.TreeMap; - -import org.eclipse.jetty.http.HttpHeader; public class UpgradeUtils { @@ -31,32 +28,9 @@ public class UpgradeUtils upgradeRequest.append("GET "); upgradeRequest.append(requestPath == null ? "/" : requestPath); upgradeRequest.append(" HTTP/1.1\r\n"); - headers.entrySet().stream().forEach(e -> + headers.entrySet().forEach(e -> upgradeRequest.append(e.getKey()).append(": ").append(e.getValue()).append("\r\n")); upgradeRequest.append("\r\n"); return upgradeRequest.toString(); } - - public static String generateUpgradeRequest() - { - return generateUpgradeRequest("/", newDefaultUpgradeRequestHeaders()); - } - - public static String generateUpgradeRequest(CharSequence requestPath) - { - return generateUpgradeRequest(requestPath, newDefaultUpgradeRequestHeaders()); - } - - public static Map newDefaultUpgradeRequestHeaders() - { - Map headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - headers.put("Host", "local"); - headers.put("Connection", "Upgrade"); - headers.put("Upgrade", "WebSocket"); - headers.put(HttpHeader.SEC_WEBSOCKET_KEY.asString(), "dGhlIHNhbXBsZSBub25jZQ=="); - headers.put(HttpHeader.ORIGIN.asString(), "ws://local/"); - // headers.put(WSConstants.SEC_WEBSOCKET_PROTOCOL, "echo"); - headers.put(HttpHeader.SEC_WEBSOCKET_VERSION.asString(), "13"); - return headers; - } } diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java index 954c53e7f43..9470dbdaa9b 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java +++ b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/AnnotatedServerEndpointTest.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.javax.tests.server; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -30,7 +31,6 @@ import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.javax.tests.Fuzzer; -import org.eclipse.jetty.websocket.javax.tests.UpgradeUtils; import org.eclipse.jetty.websocket.javax.tests.WSServer; import org.eclipse.jetty.websocket.javax.tests.coders.DateDecoder; import org.eclipse.jetty.websocket.javax.tests.coders.TimeEncoder; @@ -72,8 +72,8 @@ public class AnnotatedServerEndpointTest private void assertResponse(String message, String expectedText) throws Exception { - Map upgradeRequest = UpgradeUtils.newDefaultUpgradeRequestHeaders(); - upgradeRequest.put(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL.asString(), "echo"); + Map headers = new HashMap<>(); + headers.put(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL.asString(), "echo"); List send = new ArrayList<>(); send.add(new Frame(OpCode.TEXT).setPayload(message)); @@ -83,7 +83,7 @@ public class AnnotatedServerEndpointTest expect.add(new Frame(OpCode.TEXT).setPayload(expectedText)); expect.add(CloseStatus.toFrame(CloseStatus.NORMAL)); - try (Fuzzer session = server.newNetworkFuzzer("/app/echo", upgradeRequest)) + try (Fuzzer session = server.newNetworkFuzzer("/app/echo", headers)) { session.sendFrames(send); session.expect(expect); diff --git a/jetty-websocket/javax-websocket-tests/src/test/resources/jetty-logging.properties b/jetty-websocket/javax-websocket-tests/src/test/resources/jetty-logging.properties index d078063b659..3d2cd907dc6 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/javax-websocket-tests/src/test/resources/jetty-logging.properties @@ -19,7 +19,7 @@ # # org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.LEVEL=WARN +org.eclipse.jetty.LEVEL=INFO # org.eclipse.jetty.util.log.stderr.LONG=true # org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG # org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java index 1767a751d4f..c0a123f59d1 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java +++ b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/UpgradeRequest.java @@ -255,34 +255,6 @@ public interface UpgradeRequest */ void setHeaders(Map> headers); - /** - * Set the HTTP Version to use. - *

- * As of RFC6455 (December 2011) this should always be - * {@code HTTP/1.1} - * - * @param httpVersion the HTTP version to use. - */ - void setHttpVersion(String httpVersion); - - /** - * Set the HTTP method to use. - *

- * As of RFC6455 (December 2011) this is always {@code GET} - * - * @param method the HTTP method to use. - */ - void setMethod(String method); - - /** - * Set the Request URI to use for this request. - *

- * Must be an absolute URI with scheme {@code 'ws'} or {@code 'wss'} - * - * @param uri the Request URI - */ - void setRequestURI(URI uri); - /** * Set the Session associated with this request. *

diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java b/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java index 14cb4a8e9b0..3e9727a9a4f 100644 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java +++ b/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java @@ -26,9 +26,11 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.TreeMap; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; @@ -46,7 +48,6 @@ public final class ClientUpgradeRequest implements UpgradeRequest private String httpVersion; private String method; private String host; - private boolean secure; public ClientUpgradeRequest() { @@ -57,12 +58,9 @@ public final class ClientUpgradeRequest implements UpgradeRequest { this.requestURI = uri; String scheme = uri.getScheme(); - if (!"ws".equalsIgnoreCase(scheme) && !"wss".equalsIgnoreCase(scheme)) - { + if (!HttpScheme.WS.is(scheme) || !HttpScheme.WSS.is(scheme)) throw new IllegalArgumentException("URI scheme must be 'ws' or 'wss'"); - } this.host = this.requestURI.getHost(); - this.parameters.clear(); } @Override @@ -193,11 +191,7 @@ public final class ClientUpgradeRequest implements UpgradeRequest public String getProtocolVersion() { String version = getHeader("Sec-WebSocket-Version"); - if (version == null) - { - return "13"; // Default - } - return version; + return Objects.requireNonNullElse(version, "13"); } @Override @@ -288,8 +282,7 @@ public final class ClientUpgradeRequest implements UpgradeRequest @Override public void setHeaders(Map> headers) { - headers.clear(); - + this.headers.clear(); for (Map.Entry> entry : headers.entrySet()) { String name = entry.getKey(); @@ -298,24 +291,6 @@ public final class ClientUpgradeRequest implements UpgradeRequest } } - @Override - public void setHttpVersion(String httpVersion) - { - this.httpVersion = httpVersion; - } - - @Override - public void setMethod(String method) - { - this.method = method; - } - - @Override - public void setRequestURI(URI uri) - { - this.requestURI = uri; - } - @Override public void setSession(Object session) { diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java b/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java index 88516af8589..5ce030ce2ad 100644 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java +++ b/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java @@ -231,24 +231,6 @@ public class DelegatedJettyClientUpgradeRequest implements UpgradeRequest // TODO } - @Override - public void setHttpVersion(String httpVersion) - { - // TODO - } - - @Override - public void setMethod(String method) - { - - } - - @Override - public void setRequestURI(URI uri) - { - // TODO - } - @Override public void setSession(Object session) { diff --git a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java b/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java index 3083d5c789a..89bc6cb7792 100644 --- a/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java +++ b/jetty-websocket/jetty-websocket-client/src/main/java/org/eclipse/jetty/websocket/client/impl/JettyClientUpgradeRequest.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.stream.Collectors; import org.eclipse.jetty.client.HttpResponse; -import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpVersion; @@ -89,18 +88,18 @@ public class JettyClientUpgradeRequest extends ClientUpgradeRequest } @Override - protected void customize(EndPoint endp) + protected void customize(EndPoint endPoint) { - super.customize(endp); - handshakeRequest.configure(endp); + super.customize(endPoint); + handshakeRequest.configure(endPoint); } @Override - public void upgrade(HttpResponse response, HttpConnectionOverHTTP httpConnection) + public void upgrade(HttpResponse response, EndPoint endPoint) { frameHandler.setUpgradeRequest(new DelegatedJettyClientUpgradeRequest(this)); frameHandler.setUpgradeResponse(new DelegatedJettyClientUpgradeResponse(response)); - super.upgrade(response, httpConnection); + super.upgrade(response, endPoint); } @Override diff --git a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeRequest.java b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeRequest.java index ff776d71200..47cf0aacbb2 100644 --- a/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeRequest.java +++ b/jetty-websocket/jetty-websocket-common/src/test/java/org/eclipse/jetty/websocket/common/handshake/DummyUpgradeRequest.java @@ -185,24 +185,6 @@ public class DummyUpgradeRequest implements UpgradeRequest } - @Override - public void setHttpVersion(String httpVersion) - { - - } - - @Override - public void setMethod(String method) - { - - } - - @Override - public void setRequestURI(URI uri) - { - - } - @Override public void setSession(Object session) { diff --git a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java b/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java index 57a69c63b62..f583acb0076 100644 --- a/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java +++ b/jetty-websocket/jetty-websocket-server/src/main/java/org/eclipse/jetty/websocket/server/internal/UpgradeRequestAdapter.java @@ -197,24 +197,6 @@ public class UpgradeRequestAdapter implements UpgradeRequest throw new UnsupportedOperationException("Not supported from Servlet API"); } - @Override - public void setHttpVersion(String httpVersion) - { - throw new UnsupportedOperationException("Not supported from Servlet API"); - } - - @Override - public void setMethod(String method) - { - throw new UnsupportedOperationException("Not supported from Servlet API"); - } - - @Override - public void setRequestURI(URI uri) - { - throw new UnsupportedOperationException("Not supported from Servlet API"); - } - @Override public void setSession(Object session) { diff --git a/jetty-websocket/jetty-websocket-tests/pom.xml b/jetty-websocket/jetty-websocket-tests/pom.xml index bfd1689a5d7..371005bd234 100644 --- a/jetty-websocket/jetty-websocket-tests/pom.xml +++ b/jetty-websocket/jetty-websocket-tests/pom.xml @@ -19,26 +19,37 @@ org.eclipse.jetty.websocket jetty-websocket-api ${project.version} + test org.eclipse.jetty.websocket jetty-websocket-client ${project.version} + test org.eclipse.jetty.websocket jetty-websocket-server ${project.version} + test org.eclipse.jetty.tests jetty-http-tools ${project.version} + test - org.eclipse.jetty.toolchain - jetty-test-helper - compile + org.eclipse.jetty.http2 + http2-server + ${project.version} + test + + + org.eclipse.jetty.http2 + http2-http-client-transport + ${project.version} + test diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java index ae660da1c09..cce0450d18d 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/EventSocket.java @@ -57,14 +57,14 @@ public class EventSocket { this.session = session; behavior = session.getPolicy().getBehavior().name(); - LOG.info("{} onOpen(): {}", toString(), session); + LOG.debug("{} onOpen(): {}", toString(), session); openLatch.countDown(); } @OnWebSocketMessage public void onMessage(String message) throws IOException { - LOG.info("{} onMessage(): {}", toString(), message); + LOG.debug("{} onMessage(): {}", toString(), message); messageQueue.offer(message); } @@ -72,14 +72,14 @@ public class EventSocket public void onMessage(byte buf[], int offset, int len) { ByteBuffer message = ByteBuffer.wrap(buf, offset, len); - LOG.info("{} onMessage(): {}", toString(), message); + LOG.debug("{} onMessage(): {}", toString(), message); binaryMessageQueue.offer(message); } @OnWebSocketClose public void onClose(int statusCode, String reason) { - LOG.info("{} onClose(): {}:{}", toString(), statusCode, reason); + LOG.debug("{} onClose(): {}:{}", toString(), statusCode, reason); this.statusCode = statusCode; this.reason = reason; closeLatch.countDown(); @@ -88,7 +88,7 @@ public class EventSocket @OnWebSocketError public void onError(Throwable cause) { - LOG.info("{} onError(): {}", toString(), cause); + LOG.debug("{} onError(): {}", toString(), cause); error = cause; errorLatch.countDown(); } diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java new file mode 100644 index 00000000000..492b7c3afcc --- /dev/null +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java @@ -0,0 +1,131 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.tests; + +import java.net.URI; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; +import org.eclipse.jetty.client.http.HttpClientConnectionFactory; +import org.eclipse.jetty.http2.client.HTTP2Client; +import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2; +import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; +import org.eclipse.jetty.io.ClientConnectionFactory; +import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; +import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class WebSocketOverHTTP2Test +{ + private Server server; + private ServerConnector connector; + + @BeforeEach + public void startServer() throws Exception + { + QueuedThreadPool serverThreads = new QueuedThreadPool(); + serverThreads.setName("server"); + server = new Server(serverThreads); + HttpConfiguration httpConfiguration = new HttpConfiguration(); + HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration); + HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(httpConfiguration); + connector = new ServerConnector(server, 1, 1, h1, h2c); + server.addConnector(connector); + + ServletContextHandler context = new ServletContextHandler(server, "/"); + context.addServlet(new ServletHolder(new JettyWebSocketServlet() + { + @Override + protected void configure(JettyWebSocketServletFactory factory) + { + factory.addMapping("/ws/echo", (req, resp) -> new EchoSocket()); + } + }), "/ws/*"); + JettyWebSocketServletContainerInitializer.initialize(context); + + server.start(); + } + + @AfterEach + public void stopServer() throws Exception + { + server.stop(); + } + + @Test + public void testWebSocketOverDynamicHTTP1() throws Exception + { + testWebSocketOverDynamicTransport(clientConnector -> HttpClientConnectionFactory.HTTP11); + } + + @Test + public void testWebSocketOverDynamicHTTP2() throws Exception + { + testWebSocketOverDynamicTransport(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2C(new HTTP2Client(clientConnector))); + } + + private void testWebSocketOverDynamicTransport(Function protocolFn) throws Exception + { + ClientConnector clientConnector = new ClientConnector(); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + clientConnector.setExecutor(clientThreads); + HttpClient httpClient = new HttpClient(new HttpClientTransportDynamic(clientConnector, protocolFn.apply(clientConnector))); + + WebSocketClient wsClient = new WebSocketClient(httpClient); + wsClient.start(); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/echo"); + Session session = wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS); + + String text = "websocket"; + session.getRemote().sendString(text); + + String message = wsEndPoint.messageQueue.poll(5, TimeUnit.SECONDS); + assertNotNull(message); + assertEquals(text, message); + + session.close(StatusCode.NORMAL, null); + assertTrue(wsEndPoint.closeLatch.await(5, TimeUnit.SECONDS)); + assertEquals(StatusCode.NORMAL, wsEndPoint.statusCode); + assertNull(wsEndPoint.error); + } +} diff --git a/jetty-websocket/jetty-websocket-tests/src/test/resources/jetty-logging.properties b/jetty-websocket/jetty-websocket-tests/src/test/resources/jetty-logging.properties index 8806e105177..249aa45a834 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/jetty-websocket-tests/src/test/resources/jetty-logging.properties @@ -1,44 +1,24 @@ -# -# -# ======================================================================== -# Copyright (c) 1995-2017 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. -# ======================================================================== -# -# -# org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.LEVEL=WARN -# org.eclipse.jetty.websocket.tests.LEVEL=DEBUG -# org.eclipse.jetty.util.log.stderr.LONG=true -# org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG -# org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG -# org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG -# org.eclipse.jetty.client.LEVEL=DEBUG -# org.eclipse.jetty.io.LEVEL=DEBUG -# org.eclipse.jetty.io.ManagedSelector.LEVEL=INFO -# org.eclipse.jetty.websocket.LEVEL=DEBUG -# org.eclipse.jetty.websocket.core.internal.WebSocketCoreSessionsion.LEVEL=DEBUG -# org.eclipse.jetty.websocket.jsr356.tests.LEVEL=DEBUG -# org.eclipse.jetty.websocket.LEVEL=INFO -# org.eclipse.jetty.websocket.jsr356.messages.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.client.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.client.jsr356.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.server.LEVEL=DEBUG -# org.eclipse.jetty.websocket.tests.server.jsr356.LEVEL=DEBUG -### Showing any unintended (ignored) errors from CompletionCallback -# org.eclipse.jetty.websocket.common.CompletionCallback.LEVEL=ALL -### Disabling intentional error out of RFCSocket +#org.eclipse.jetty.LEVEL=DEBUG +#org.eclipse.jetty.websocket.tests.LEVEL=DEBUG +#org.eclipse.jetty.util.log.stderr.LONG=true +#org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG +#org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG +#org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG +#org.eclipse.jetty.client.LEVEL=DEBUG +#org.eclipse.jetty.io.LEVEL=DEBUG +#org.eclipse.jetty.io.ManagedSelector.LEVEL=INFO +#org.eclipse.jetty.websocket.LEVEL=DEBUG +#org.eclipse.jetty.websocket.core.internal.WebSocketCoreSessionsion.LEVEL=DEBUG +#org.eclipse.jetty.websocket.jsr356.tests.LEVEL=DEBUG +#org.eclipse.jetty.websocket.LEVEL=INFO +#org.eclipse.jetty.websocket.jsr356.messages.LEVEL=DEBUG +#org.eclipse.jetty.websocket.tests.LEVEL=DEBUG +#org.eclipse.jetty.websocket.tests.client.LEVEL=DEBUG +#org.eclipse.jetty.websocket.tests.client.jsr356.LEVEL=DEBUG +#org.eclipse.jetty.websocket.tests.server.LEVEL=DEBUG +#org.eclipse.jetty.websocket.tests.server.jsr356.LEVEL=DEBUG +## Showing any unintended (ignored) errors from CompletionCallback +#org.eclipse.jetty.websocket.common.CompletionCallback.LEVEL=ALL +## Disabling intentional error out of RFCSocket org.eclipse.jetty.websocket.tests.server.RFCSocket.LEVEL=OFF diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java index 139e355df63..bb536d624bd 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java @@ -20,12 +20,10 @@ package org.eclipse.jetty.websocket.core.client; import java.net.URI; import java.util.ArrayList; -import java.util.Base64; +import java.util.Arrays; import java.util.List; -import java.util.Locale; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -import java.util.concurrent.ThreadLocalRandom; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -33,16 +31,13 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpConversation; import org.eclipse.jetty.client.HttpRequest; import org.eclipse.jetty.client.HttpResponse; -import org.eclipse.jetty.client.HttpResponseException; +import org.eclipse.jetty.client.HttpUpgrader; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; -import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; -import org.eclipse.jetty.client.http.HttpConnectionUpgrader; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; @@ -64,10 +59,9 @@ import org.eclipse.jetty.websocket.core.WebSocketException; import org.eclipse.jetty.websocket.core.internal.ExtensionStack; import org.eclipse.jetty.websocket.core.internal.Negotiated; import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; -import org.eclipse.jetty.websocket.core.internal.WebSocketCore; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; -public abstract class ClientUpgradeRequest extends HttpRequest implements Response.CompleteListener, HttpConnectionUpgrader +public abstract class ClientUpgradeRequest extends HttpRequest implements Response.CompleteListener, HttpUpgrader.Factory { public static ClientUpgradeRequest from(WebSocketCoreClient webSocketClient, URI requestURI, FrameHandler frameHandler) { @@ -103,8 +97,8 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon throw new IllegalArgumentException("WebSocket URI must include a scheme"); } - String scheme = requestURI.getScheme().toLowerCase(Locale.ENGLISH); - if (("ws".equals(scheme) == false) && ("wss".equals(scheme) == false)) + String scheme = requestURI.getScheme(); + if (!HttpScheme.WS.is(scheme) && !HttpScheme.WSS.is(scheme)) { throw new IllegalArgumentException("WebSocket URI scheme only supports [ws] and [wss], not [" + scheme + "]"); } @@ -116,10 +110,6 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon this.wsClient = webSocketClient; this.futureCoreSession = new CompletableFuture<>(); - method(HttpMethod.GET); - version(HttpVersion.HTTP_1_1); - - getConversation().setAttribute(HttpConnectionUpgrader.class.getName(), this); } public void setConfiguration(FrameHandler.ConfigurationCustomizer config) @@ -152,12 +142,10 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon public List getExtensions() { - List extensions = getHeaders().getCSV(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, true) + return getHeaders().getCSV(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, true) .stream() .map(ExtensionConfig::parse) .collect(Collectors.toList()); - - return extensions; } public void setExtensions(List configs) @@ -172,8 +160,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon public List getSubProtocols() { - List subProtocols = getHeaders().getCSV(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, true); - return subProtocols; + return getHeaders().getCSV(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, true); } public void setSubProtocols(String... protocols) @@ -199,17 +186,9 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon @Override public void send(final Response.CompleteListener listener) { - try - { - frameHandler = getFrameHandler(); - if (frameHandler == null) - throw new IllegalArgumentException("FrameHandler could not be created"); - } - catch (Throwable t) - { - throw new IllegalArgumentException("FrameHandler could not be created", t); - } - + frameHandler = getFrameHandler(); + if (frameHandler == null) + throw new IllegalArgumentException("FrameHandler could not be created"); initWebSocketHeaders(); super.send(listener); } @@ -279,20 +258,58 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon } } - @SuppressWarnings("Duplicates") @Override - public void upgrade(HttpResponse response, HttpConnectionOverHTTP httpConnection) + public HttpUpgrader newHttpUpgrader(HttpVersion version) { - if (!this.getHeaders().get(HttpHeader.UPGRADE).equalsIgnoreCase("websocket")) - throw new HttpResponseException("Not a WebSocket Upgrade", response); + if (version == HttpVersion.HTTP_1_1) + return new HttpUpgraderOverHTTP(this); + else if (version == HttpVersion.HTTP_2) + return new HttpUpgraderOverHTTP2(this); + else + throw new UnsupportedOperationException("Unsupported HTTP version for upgrade: " + version); + } - // Check the Accept hash - String reqKey = this.getHeaders().get(HttpHeader.SEC_WEBSOCKET_KEY); - String expectedHash = WebSocketCore.hashKey(reqKey); - String respHash = response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_ACCEPT); - if (expectedHash.equalsIgnoreCase(respHash) == false) - throw new HttpResponseException("Invalid Sec-WebSocket-Accept hash (was:" + respHash + ", expected:" + expectedHash + ")", response); + /** + * Allow for overridden customization of endpoint (such as special transport level properties: e.g. TCP keepAlive) + */ + protected void customize(EndPoint endPoint) + { + } + protected WebSocketConnection newWebSocketConnection(EndPoint endPoint, Executor executor, Scheduler scheduler, ByteBufferPool byteBufferPool, WebSocketCoreSession coreSession) + { + return new WebSocketConnection(endPoint, executor, scheduler, byteBufferPool, coreSession); + } + + protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated) + { + return new WebSocketCoreSession(handler, Behavior.CLIENT, negotiated); + } + + public abstract FrameHandler getFrameHandler(); + + private void initWebSocketHeaders() + { + notifyUpgradeListeners((listener) -> listener.onHandshakeRequest(this)); + } + + private void notifyUpgradeListeners(Consumer action) + { + for (UpgradeListener listener : upgradeListeners) + { + try + { + action.accept(listener); + } + catch (Throwable t) + { + LOG.info("Exception while invoking listener " + listener, t); + } + } + } + + public void upgrade(HttpResponse response, EndPoint endPoint) + { // Parse the Negotiated Extensions List negotiatedExtensions = new ArrayList<>(); HttpField extField = response.getHeaders().getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); @@ -341,7 +358,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon if (values != null) { if (values.length > 1) - throw new WebSocketException("Upgrade failed: Too many WebSocket subprotocol's in response: " + values); + throw new WebSocketException("Upgrade failed: Too many WebSocket subprotocol's in response: " + Arrays.toString(values)); else if (values.length == 1) negotiatedSubProtocol = values[0]; } @@ -355,8 +372,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon throw new WebSocketException("Upgrade failed: subprotocol [" + negotiatedSubProtocol + "] not found in offered subprotocols " + offeredSubProtocols); // We can upgrade - EndPoint endp = httpConnection.getEndPoint(); - customize(endp); + customize(endPoint); Request request = response.getRequest(); Negotiated negotiated = new Negotiated( @@ -370,7 +386,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon customizer.customize(coreSession); HttpClient httpClient = wsClient.getHttpClient(); - WebSocketConnection wsConnection = newWebSocketConnection(endp, httpClient.getExecutor(), httpClient.getScheduler(), httpClient.getByteBufferPool(), coreSession); + WebSocketConnection wsConnection = newWebSocketConnection(endPoint, httpClient.getExecutor(), httpClient.getScheduler(), httpClient.getByteBufferPool(), coreSession); for (Connection.Listener listener : wsClient.getBeans(Connection.Listener.class)) { @@ -384,7 +400,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon // Now swap out the connection try { - endp.upgrade(wsConnection); + endPoint.upgrade(wsConnection); futureCoreSession.complete(coreSession); } catch (Throwable t) @@ -392,79 +408,4 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon futureCoreSession.completeExceptionally(t); } } - - /** - * Allow for overridden customization of endpoint (such as special transport level properties: e.g. TCP keepAlive) - * - * @see Issue #1811 - Customization of WebSocket Connections via WebSocketPolicy - */ - protected void customize(EndPoint endp) - { - } - - protected WebSocketConnection newWebSocketConnection(EndPoint endp, Executor executor, Scheduler scheduler, ByteBufferPool byteBufferPool, WebSocketCoreSession coreSession) - { - return new WebSocketConnection(endp, executor, scheduler, byteBufferPool, coreSession); - } - - protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated) - { - return new WebSocketCoreSession(handler, Behavior.CLIENT, negotiated); - } - - public abstract FrameHandler getFrameHandler(); - - private final String genRandomKey() - { - byte[] bytes = new byte[16]; - ThreadLocalRandom.current().nextBytes(bytes); - return Base64.getEncoder().encodeToString(bytes); - } - - private void initWebSocketHeaders() - { - method(HttpMethod.GET); - version(HttpVersion.HTTP_1_1); - - // The Upgrade Headers - setHeaderIfNotPresent(HttpHeader.UPGRADE, "websocket"); - setHeaderIfNotPresent(HttpHeader.CONNECTION, "Upgrade"); - - // The WebSocket Headers - setHeaderIfNotPresent(HttpHeader.SEC_WEBSOCKET_KEY, genRandomKey()); - setHeaderIfNotPresent(HttpHeader.SEC_WEBSOCKET_VERSION, WebSocketConstants.SPEC_VERSION_STRING); - - // (Per the hybi list): Add no-cache headers to avoid compatibility issue. - // There are some proxies that rewrite "Connection: upgrade" - // to "Connection: close" in the response if a request doesn't contain - // these headers. - setHeaderIfNotPresent(HttpHeader.PRAGMA, "no-cache"); - setHeaderIfNotPresent(HttpHeader.CACHE_CONTROL, "no-cache"); - - // Notify upgrade hooks - notifyUpgradeListeners((listener) -> listener.onHandshakeRequest(this)); - } - - private void setHeaderIfNotPresent(HttpHeader header, String value) - { - if (!getHeaders().contains(header)) - { - getHeaders().put(header, value); - } - } - - private void notifyUpgradeListeners(Consumer action) - { - for (UpgradeListener listener : upgradeListeners) - { - try - { - action.accept(listener); - } - catch (Throwable t) - { - LOG.warn("Unhandled error: " + t.getMessage(), t); - } - } - } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java new file mode 100644 index 00000000000..19775d420bb --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java @@ -0,0 +1,86 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.core.client; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.concurrent.ThreadLocalRandom; + +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpResponseException; +import org.eclipse.jetty.client.HttpUpgrader; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.websocket.core.WebSocketConstants; +import org.eclipse.jetty.websocket.core.internal.WebSocketCore; + +public class HttpUpgraderOverHTTP implements HttpUpgrader +{ + private final ClientUpgradeRequest clientUpgradeRequest; + + public HttpUpgraderOverHTTP(ClientUpgradeRequest clientUpgradeRequest) + { + this.clientUpgradeRequest = clientUpgradeRequest; + } + + @Override + public void prepare(HttpRequest request) + { + request.method(HttpMethod.GET).version(HttpVersion.HTTP_1_1); + request.header(HttpHeader.SEC_WEBSOCKET_VERSION, WebSocketConstants.SPEC_VERSION_STRING); + request.header(HttpHeader.UPGRADE, "websocket"); + request.header(HttpHeader.CONNECTION, "Upgrade"); + request.header(HttpHeader.SEC_WEBSOCKET_KEY, generateRandomKey()); + // Per the hybi list: Add no-cache headers to avoid compatibility issue. + // There are some proxies that rewrite "Connection: upgrade" to + // "Connection: close" in the response if a request doesn't contain + // these headers. + request.header(HttpHeader.PRAGMA, "no-cache"); + request.header(HttpHeader.CACHE_CONTROL, "no-cache"); + } + + private String generateRandomKey() + { + byte[] bytes = new byte[16]; + ThreadLocalRandom.current().nextBytes(bytes); + return new String(Base64.getEncoder().encode(bytes), StandardCharsets.US_ASCII); + } + + @Override + public void upgrade(HttpResponse response, EndPoint endPoint) + { + HttpRequest request = (HttpRequest)response.getRequest(); + HttpFields requestHeaders = request.getHeaders(); + if (!requestHeaders.get(HttpHeader.UPGRADE).equalsIgnoreCase("websocket")) + throw new HttpResponseException("Not a WebSocket Upgrade", response); + + // Check the Accept hash + String reqKey = requestHeaders.get(HttpHeader.SEC_WEBSOCKET_KEY); + String expectedHash = WebSocketCore.hashKey(reqKey); + String respHash = response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_ACCEPT); + if (!expectedHash.equalsIgnoreCase(respHash)) + throw new HttpResponseException("Invalid Sec-WebSocket-Accept hash (was:" + respHash + ", expected:" + expectedHash + ")", response); + + clientUpgradeRequest.upgrade(response, endPoint); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java new file mode 100644 index 00000000000..6d7ae2c4015 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java @@ -0,0 +1,51 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.core.client; + +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpUpgrader; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.websocket.core.WebSocketConstants; + +public class HttpUpgraderOverHTTP2 implements HttpUpgrader +{ + private final ClientUpgradeRequest clientUpgradeRequest; + + public HttpUpgraderOverHTTP2(ClientUpgradeRequest clientUpgradeRequest) + { + this.clientUpgradeRequest = clientUpgradeRequest; + } + + @Override + public void prepare(HttpRequest request) + { + request.method(HttpMethod.CONNECT); + request.upgradeProtocol("websocket"); + request.header(HttpHeader.SEC_WEBSOCKET_VERSION, WebSocketConstants.SPEC_VERSION_STRING); + } + + @Override + public void upgrade(HttpResponse response, EndPoint endPoint) + { + clientUpgradeRequest.upgrade(response, endPoint); + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java index 8241c520132..90fa9caa421 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java @@ -23,19 +23,16 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.server.internal.HandshakerSelector; import org.eclipse.jetty.websocket.core.server.internal.RFC6455Handshaker; +import org.eclipse.jetty.websocket.core.server.internal.RFC8441Handshaker; public interface Handshaker { static Handshaker newInstance() { - return new RFC6455Handshaker(); + return new HandshakerSelector(new RFC6455Handshaker(), new RFC8441Handshaker()); } - boolean upgradeRequest( - WebSocketNegotiator negotiator, - HttpServletRequest request, - HttpServletResponse response, - FrameHandler.Customizer defaultCustomizer) - throws IOException; + boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException; } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java new file mode 100644 index 00000000000..37ceeaaedc2 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java @@ -0,0 +1,58 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.core.server.internal; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.server.Handshaker; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; + +public class HandshakerSelector implements Handshaker +{ + private List handshakers = new ArrayList<>(); + + public HandshakerSelector(Handshaker... handshakers) + { + Collections.addAll(this.handshakers, handshakers); + } + + @Override + public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException + { + // TODO: we don't want to do a lot of work for every request that is not websocket. + // Something like: if (method == CONNECT) only try 8441, else if (method == GET) only try 6455. + // TODO: optimise (do pre checks and avoid iterating through handshakers) + // TODO: minimum simplest thing to do to return false + for (Handshaker handshaker : handshakers) + { + if (handshaker.upgradeRequest(negotiator, request, response, defaultCustomizer)) + return true; + + if (response.isCommitted()) + return false; + } + return false; + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java new file mode 100644 index 00000000000..241e82a196c --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java @@ -0,0 +1,249 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.core.server.internal; + +import java.io.IOException; +import java.util.concurrent.Executor; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.PreEncodedHttpField; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.ConnectionFactory; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.HttpTransport; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.websocket.core.Behavior; +import org.eclipse.jetty.websocket.core.ExtensionConfig; +import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.WebSocketConstants; +import org.eclipse.jetty.websocket.core.WebSocketException; +import org.eclipse.jetty.websocket.core.internal.ExtensionStack; +import org.eclipse.jetty.websocket.core.internal.Negotiated; +import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; +import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; +import org.eclipse.jetty.websocket.core.server.Handshaker; +import org.eclipse.jetty.websocket.core.server.Negotiation; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; + +public class RFC8441Handshaker implements Handshaker +{ + static final Logger LOG = Log.getLogger(RFC8441Handshaker.class); + private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION); + + @Override + public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException + { + Request baseRequest = Request.getBaseRequest(request); + HttpChannel httpChannel = baseRequest.getHttpChannel(); + Connector connector = httpChannel.getConnector(); + + if (!HttpVersion.HTTP_2.equals(baseRequest.getHttpVersion())) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded HttpVersion!=2 {}", baseRequest); + return false; + } + + if (!HttpMethod.CONNECT.is(request.getMethod())) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded method!=GET {}", baseRequest); + return false; + } + + if (negotiator == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no WebSocketNegotiator {}", baseRequest); + return false; + } + + ByteBufferPool pool = negotiator.getByteBufferPool(); + if (pool == null) + pool = baseRequest.getHttpChannel().getConnector().getByteBufferPool(); + + Negotiation negotiation = new RFC8441Negotiation(baseRequest, request, response, new WebSocketComponents()); + if (LOG.isDebugEnabled()) + LOG.debug("negotiation {}", negotiation); + + if (!negotiation.isUpgrade()) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no upgrade header or connection upgrade", baseRequest); + return false; + } + + if (!WebSocketConstants.SPEC_VERSION_STRING.equals(negotiation.getVersion())) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: unsupported version {} {}", negotiation.getVersion(), baseRequest); + return false; + } + + // Negotiate the FrameHandler + FrameHandler handler = negotiator.negotiate(negotiation); + if (LOG.isDebugEnabled()) + LOG.debug("negotiated handler {}", handler); + + // Handle error responses + if (response.isCommitted()) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: response committed {}", baseRequest); + baseRequest.setHandled(true); + return false; + } + if (response.getStatus() > 200) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: error sent {} {}", response.getStatus(), baseRequest); + response.flushBuffer(); + baseRequest.setHandled(true); + return false; + } + + // Check for handler + if (handler == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no frame handler provided {}", baseRequest); + return false; + } + + // validate negotiated subprotocol + String subprotocol = negotiation.getSubprotocol(); + if (subprotocol != null) + { + if (!negotiation.getOfferedSubprotocols().contains(subprotocol)) + throw new WebSocketException("not upgraded: selected a subprotocol not present in offered subprotocols"); + } + else + { + if (!negotiation.getOfferedSubprotocols().isEmpty()) + throw new WebSocketException("not upgraded: no subprotocol selected from offered subprotocols"); + } + + // validate negotiated extensions + for (ExtensionConfig config : negotiation.getNegotiatedExtensions()) + { + if (config.getName().startsWith("@")) + continue; + + long matches = negotiation.getOfferedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); + if (matches < 1) + throw new WebSocketException("Upgrade failed: negotiated extension not requested"); + + matches = negotiation.getNegotiatedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); + if (matches > 1) + throw new WebSocketException("Upgrade failed: multiple negotiated extensions of the same name"); + } + + // Create and Negotiate the ExtensionStack + ExtensionStack extensionStack = negotiation.getExtensionStack(); + + Negotiated negotiated = new Negotiated( + baseRequest.getHttpURI().toURI(), + subprotocol, + baseRequest.isSecure(), + extensionStack, + WebSocketConstants.SPEC_VERSION_STRING); + + // Create the Channel + WebSocketCoreSession coreSession = newWebSocketCoreSession(handler, negotiated); + if (defaultCustomizer != null) + defaultCustomizer.customize(coreSession); + negotiator.customize(coreSession); + + if (LOG.isDebugEnabled()) + LOG.debug("coreSession {}", coreSession); + + // Create a connection + EndPoint endPoint = baseRequest.getHttpChannel().getTunnellingEndPoint(); + WebSocketConnection connection = newWebSocketConnection(endPoint, connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); + if (LOG.isDebugEnabled()) + LOG.debug("connection {}", connection); + if (connection == null) + throw new WebSocketException("not upgraded: no connection"); + + for (Connection.Listener listener : connector.getBeans(Connection.Listener.class)) + { + connection.addListener(listener); + } + + coreSession.setWebSocketConnection(connection); + + // send upgrade response + Response baseResponse = baseRequest.getResponse(); + baseResponse.setStatus(HttpStatus.OK_200); + + // See bugs.eclipse.org/485969 + if (getSendServerVersion(connector)) + baseResponse.getHttpFields().put(SERVER_VERSION); + + baseRequest.setHandled(true); + + // upgrade + if (LOG.isDebugEnabled()) + LOG.debug("upgrade connection={} session={}", connection, coreSession); + + baseRequest.setAttribute(HttpTransport.UPGRADE_CONNECTION_ATTRIBUTE, connection); + return true; + } + + protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated) + { + return new WebSocketCoreSession(handler, Behavior.SERVER, negotiated); + } + + protected WebSocketConnection newWebSocketConnection(EndPoint endPoint, Executor executor, Scheduler scheduler, ByteBufferPool byteBufferPool, WebSocketCoreSession coreSession) + { + return new WebSocketConnection(endPoint, executor, scheduler, byteBufferPool, coreSession); + } + + private boolean getSendServerVersion(Connector connector) + { + ConnectionFactory connFactory = connector.getConnectionFactory(HttpVersion.HTTP_2.asString()); + if (connFactory == null) + return false; + + if (connFactory instanceof HttpConnectionFactory) + { + HttpConfiguration httpConf = ((HttpConnectionFactory)connFactory).getHttpConfiguration(); + if (httpConf != null) + return httpConf.getSendServerVersion(); + } + return false; + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java new file mode 100644 index 00000000000..ac3f01b8ccb --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.core.server.internal; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.BadMessageException; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.server.Negotiation; + +public class RFC8441Negotiation extends Negotiation +{ + public RFC8441Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents components) throws BadMessageException + { + super(baseRequest, request, response, components); + } + + @Override + public boolean isUpgrade() + { + if (!getBaseRequest().hasMetaData()) + return false; + + return "websocket".equals(getBaseRequest().getMetaData().getProtocol()); + } +} From 72ce7456eb3b86b175bec2e671a2548a62ba479c Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 12 Sep 2019 08:07:31 +1000 Subject: [PATCH 02/77] optimize HandShakeSelector Signed-off-by: Lachlan Roberts --- .../websocket/core/server/Handshaker.java | 4 +-- .../server/internal/HandshakerSelector.java | 35 +++++++++---------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java index 90fa9caa421..88a2fff7368 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java @@ -24,14 +24,12 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.server.internal.HandshakerSelector; -import org.eclipse.jetty.websocket.core.server.internal.RFC6455Handshaker; -import org.eclipse.jetty.websocket.core.server.internal.RFC8441Handshaker; public interface Handshaker { static Handshaker newInstance() { - return new HandshakerSelector(new RFC6455Handshaker(), new RFC8441Handshaker()); + return new HandshakerSelector(); } boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java index 37ceeaaedc2..245d083c395 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java @@ -19,40 +19,37 @@ package org.eclipse.jetty.websocket.core.server.internal; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.server.Handshaker; import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; public class HandshakerSelector implements Handshaker { - private List handshakers = new ArrayList<>(); - - public HandshakerSelector(Handshaker... handshakers) - { - Collections.addAll(this.handshakers, handshakers); - } + private final RFC6455Handshaker rfc6455 = new RFC6455Handshaker(); + private final RFC8441Handshaker rfc8441 = new RFC8441Handshaker(); @Override public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException { - // TODO: we don't want to do a lot of work for every request that is not websocket. - // Something like: if (method == CONNECT) only try 8441, else if (method == GET) only try 6455. - // TODO: optimise (do pre checks and avoid iterating through handshakers) - // TODO: minimum simplest thing to do to return false - for (Handshaker handshaker : handshakers) - { - if (handshaker.upgradeRequest(negotiator, request, response, defaultCustomizer)) - return true; + Request baseRequest = Request.getBaseRequest(request); + String method = request.getMethod(); + HttpVersion httpVersion = baseRequest.getHttpVersion(); - if (response.isCommitted()) - return false; + if (HttpMethod.GET.equals(method) && HttpVersion.HTTP_1_1.equals(httpVersion)) + { + return rfc6455.upgradeRequest(negotiator, request, response, defaultCustomizer); } + else if (HttpMethod.CONNECT.equals(method) && HttpVersion.HTTP_2.equals(httpVersion)) + { + return rfc8441.upgradeRequest(negotiator, request, response, defaultCustomizer); + } + return false; } } From 3068b4c8ae25e70496e723324de9f293fbda2496 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 12 Sep 2019 11:04:05 +1000 Subject: [PATCH 03/77] fix build issues Signed-off-by: Lachlan Roberts --- .../java/org/eclipse/jetty/server/HttpChannelOverHttp.java | 3 ++- .../websocket/core/server/internal/HandshakerSelector.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java index b525d02b621..e307079d800 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java @@ -408,9 +408,10 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque } @Override - protected void checkAndPrepareUpgrade() + protected boolean checkAndPrepareUpgrade() { // TODO: move the code from HttpConnection.upgrade() here? + return false; } /** diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java index 245d083c395..362963094fb 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java @@ -41,11 +41,11 @@ public class HandshakerSelector implements Handshaker String method = request.getMethod(); HttpVersion httpVersion = baseRequest.getHttpVersion(); - if (HttpMethod.GET.equals(method) && HttpVersion.HTTP_1_1.equals(httpVersion)) + if (HttpMethod.GET.is(method) && HttpVersion.HTTP_1_1.equals(httpVersion)) { return rfc6455.upgradeRequest(negotiator, request, response, defaultCustomizer); } - else if (HttpMethod.CONNECT.equals(method) && HttpVersion.HTTP_2.equals(httpVersion)) + else if (HttpMethod.CONNECT.is(method) && HttpVersion.HTTP_2.equals(httpVersion)) { return rfc8441.upgradeRequest(negotiator, request, response, defaultCustomizer); } From 17b17cb2b93b66072f3865c8dc92a259113761d1 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 12 Sep 2019 15:22:56 +1000 Subject: [PATCH 04/77] clean up websocket handshakers Signed-off-by: Lachlan Roberts --- .../core/server/WebSocketUpgradeHandler.java | 3 +- .../server/internal/RFC6455Handshaker.java | 26 +++----------- .../server/internal/RFC8441Handshaker.java | 34 ++++++------------- 3 files changed, 18 insertions(+), 45 deletions(-) diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketUpgradeHandler.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketUpgradeHandler.java index 651ccd984de..4e08dde927a 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketUpgradeHandler.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketUpgradeHandler.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.websocket.core.server; import java.io.IOException; +import java.util.Objects; import java.util.function.Function; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -47,7 +48,7 @@ public class WebSocketUpgradeHandler extends HandlerWrapper public WebSocketUpgradeHandler(WebSocketNegotiator negotiator, String... pathSpecs) { - this.negotiator = negotiator; + this.negotiator = Objects.requireNonNull(negotiator); addPathSpec(pathSpecs); } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java index b7fd481cb94..9859f16664e 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java @@ -68,24 +68,14 @@ public final class RFC6455Handshaker implements Handshaker public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException { - final Request baseRequest = Request.getBaseRequest(request); - final HttpChannel httpChannel = baseRequest.getHttpChannel(); - final Connector connector = httpChannel.getConnector(); - - if (negotiator == null) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no WebSocketNegotiator {}", baseRequest); - return false; - } - if (!HttpMethod.GET.is(request.getMethod())) { if (LOG.isDebugEnabled()) - LOG.debug("not upgraded method!=GET {}", baseRequest); + LOG.debug("not upgraded method!=GET {}", request); return false; } + final Request baseRequest = Request.getBaseRequest(request); if (!HttpVersion.HTTP_1_1.equals(baseRequest.getHttpVersion())) { if (LOG.isDebugEnabled()) @@ -93,15 +83,7 @@ public final class RFC6455Handshaker implements Handshaker return false; } - ByteBufferPool pool = negotiator.getByteBufferPool(); - if (pool == null) - pool = baseRequest.getHttpChannel().getConnector().getByteBufferPool(); - - Negotiation negotiation = new Negotiation( - baseRequest, - request, - response, - new WebSocketComponents()); + Negotiation negotiation = new Negotiation(baseRequest, request, response, new WebSocketComponents()); if (LOG.isDebugEnabled()) LOG.debug("negotiation {}", negotiation); @@ -200,6 +182,8 @@ public final class RFC6455Handshaker implements Handshaker LOG.debug("session {}", coreSession); // Create a connection + HttpChannel httpChannel = baseRequest.getHttpChannel(); + Connector connector = httpChannel.getConnector(); WebSocketConnection connection = newWebSocketConnection(httpChannel.getEndPoint(), connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); if (LOG.isDebugEnabled()) LOG.debug("connection {}", connection); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java index 241e82a196c..60080b3c041 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java @@ -65,10 +65,14 @@ public class RFC8441Handshaker implements Handshaker @Override public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException { - Request baseRequest = Request.getBaseRequest(request); - HttpChannel httpChannel = baseRequest.getHttpChannel(); - Connector connector = httpChannel.getConnector(); + if (!HttpMethod.CONNECT.is(request.getMethod())) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded method!=GET {}", request.toString()); + return false; + } + Request baseRequest = Request.getBaseRequest(request); if (!HttpVersion.HTTP_2.equals(baseRequest.getHttpVersion())) { if (LOG.isDebugEnabled()) @@ -76,24 +80,6 @@ public class RFC8441Handshaker implements Handshaker return false; } - if (!HttpMethod.CONNECT.is(request.getMethod())) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded method!=GET {}", baseRequest); - return false; - } - - if (negotiator == null) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no WebSocketNegotiator {}", baseRequest); - return false; - } - - ByteBufferPool pool = negotiator.getByteBufferPool(); - if (pool == null) - pool = baseRequest.getHttpChannel().getConnector().getByteBufferPool(); - Negotiation negotiation = new RFC8441Negotiation(baseRequest, request, response, new WebSocketComponents()); if (LOG.isDebugEnabled()) LOG.debug("negotiation {}", negotiation); @@ -189,8 +175,10 @@ public class RFC8441Handshaker implements Handshaker if (LOG.isDebugEnabled()) LOG.debug("coreSession {}", coreSession); - // Create a connection - EndPoint endPoint = baseRequest.getHttpChannel().getTunnellingEndPoint(); + // Create the Connection + HttpChannel httpChannel = baseRequest.getHttpChannel(); + Connector connector = httpChannel.getConnector(); + EndPoint endPoint = httpChannel.getTunnellingEndPoint(); WebSocketConnection connection = newWebSocketConnection(endPoint, connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); if (LOG.isDebugEnabled()) LOG.debug("connection {}", connection); From 5a08e48fe76152010c369966ea3fe1c6e638fa01 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 12 Sep 2019 16:46:47 +1000 Subject: [PATCH 05/77] don't duplicate checks in handshake selector Signed-off-by: Lachlan Roberts --- .../server/internal/HandshakerSelector.java | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java index 362963094fb..9fc54235365 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java @@ -22,13 +22,15 @@ import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.server.Request; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.server.Handshaker; import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; +/** + * Selects between the two Handshaker implementations, + * RFC6455 (HTTP/1.1 WebSocket Upgrades) + * and RFC68441 (HTTP/2 WebSocket Upgrades) + */ public class HandshakerSelector implements Handshaker { private final RFC6455Handshaker rfc6455 = new RFC6455Handshaker(); @@ -37,19 +39,8 @@ public class HandshakerSelector implements Handshaker @Override public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException { - Request baseRequest = Request.getBaseRequest(request); - String method = request.getMethod(); - HttpVersion httpVersion = baseRequest.getHttpVersion(); - - if (HttpMethod.GET.is(method) && HttpVersion.HTTP_1_1.equals(httpVersion)) - { - return rfc6455.upgradeRequest(negotiator, request, response, defaultCustomizer); - } - else if (HttpMethod.CONNECT.is(method) && HttpVersion.HTTP_2.equals(httpVersion)) - { - return rfc8441.upgradeRequest(negotiator, request, response, defaultCustomizer); - } - - return false; + // Try HTTP/1.1 WS upgrade, if this fails try an HTTP/2 WS upgrade if no response was committed. + return rfc6455.upgradeRequest(negotiator, request, response, defaultCustomizer) || + !response.isCommitted() && rfc8441.upgradeRequest(negotiator, request, response, defaultCustomizer); } } From c0866ebeae11360312f80049ea9af85c4b5242d7 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 7 Nov 2019 15:59:13 -0600 Subject: [PATCH 06/77] Issue #4269 - Restoring PrintWriter contract on errors Signed-off-by: Joakim Erdfelt --- .../main/java/org/eclipse/jetty/server/ResponseWriter.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java index f2c6352e623..094f98f1cbc 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java @@ -128,10 +128,13 @@ public class ResponseWriter extends PrintWriter private void isOpen() throws IOException { if (_ioException != null) - throw new RuntimeIOException(_ioException); + throw _ioException; if (_isClosed) - throw new EofException("Stream closed"); + { + _ioException = new EofException("Stream closed"); + throw _ioException; + } } @Override From ff7adab55a51ed44e24186e01e9c1835060c00fd Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 13 Nov 2019 14:47:53 -0600 Subject: [PATCH 07/77] Issue #4269 - Correcting PrintWriter test Signed-off-by: Joakim Erdfelt --- .../test/java/org/eclipse/jetty/server/ResponseTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 ac4bee7c9bc..e115fceeca6 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 @@ -54,7 +54,6 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.AbstractEndPoint; import org.eclipse.jetty.io.ByteArrayEndPoint; -import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ErrorHandler; @@ -711,7 +710,7 @@ public class ResponseTest } @Test - public void testWriteRuntimeIOException() throws Exception + public void testWriteCheckError() throws Exception { Response response = getResponse(); @@ -725,8 +724,8 @@ public class ResponseTest writer.println("test"); assertTrue(writer.checkError()); - RuntimeIOException e = assertThrows(RuntimeIOException.class, () -> writer.println("test")); - assertEquals(cause, e.getCause()); + writer.println("test"); // this should not cause an Exception + assertTrue(writer.checkError()); } @Test From 98574f28a062e0c6ec591c4260dda7e4f4d1a9b4 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 14 Nov 2019 17:46:40 +0100 Subject: [PATCH 08/77] Reduced code duplication in Handshakers and Negotiations. Signed-off-by: Simone Bordet --- .../websocket/core/server/Negotiation.java | 241 ++++++++---------- .../server/internal/AbstractHandshaker.java | 211 +++++++++++++++ .../server/internal/RFC6455Handshaker.java | 215 +++------------- .../server/internal/RFC6544Negotiation.java | 90 +++++++ .../server/internal/RFC8441Handshaker.java | 192 ++------------ .../server/internal/RFC8441Negotiation.java | 9 +- .../core/WebSocketNegotiationTest.java | 4 +- .../jetty/websocket/core/WebSocketServer.java | 7 +- .../core/chat/ChatWebSocketServer.java | 7 +- 9 files changed, 465 insertions(+), 511 deletions(-) create mode 100644 jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java create mode 100644 jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6544Negotiation.java diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java index 7db266a0d24..5ad5283d924 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java @@ -36,146 +36,25 @@ import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.internal.ExtensionStack; -public class Negotiation +public abstract class Negotiation { private final Request baseRequest; private final HttpServletRequest request; private final HttpServletResponse response; - private final List offeredExtensions; - private final List offeredSubprotocols; private final WebSocketComponents components; - private final String version; - private final Boolean upgrade; - private final String key; - + private String version; + private List offeredExtensions; private List negotiatedExtensions; - private String subprotocol; + private List offeredProtocols; private ExtensionStack extensionStack; + private String protocol; - /** - * @throws BadMessageException if there is any errors parsing the upgrade request - */ - public Negotiation( - Request baseRequest, - HttpServletRequest request, - HttpServletResponse response, - WebSocketComponents components) throws BadMessageException + public Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents) { this.baseRequest = baseRequest; this.request = request; this.response = response; - this.components = components; - - Boolean upgrade = null; - String key = null; - String version = null; - QuotedCSV connectionCSVs = null; - QuotedCSV extensions = null; - QuotedCSV subprotocols = null; - - try - { - for (HttpField field : baseRequest.getHttpFields()) - { - if (field.getHeader() != null) - { - switch (field.getHeader()) - { - case UPGRADE: - if (upgrade == null && "websocket".equalsIgnoreCase(field.getValue())) - upgrade = Boolean.TRUE; - break; - - case CONNECTION: - if (connectionCSVs == null) - connectionCSVs = new QuotedCSV(); - connectionCSVs.addValue(field.getValue()); - break; - - case SEC_WEBSOCKET_KEY: - key = field.getValue(); - break; - - case SEC_WEBSOCKET_VERSION: - version = field.getValue(); - break; - - case SEC_WEBSOCKET_EXTENSIONS: - if (extensions == null) - extensions = new QuotedCSV(field.getValue()); - else - extensions.addValue(field.getValue()); - break; - - case SEC_WEBSOCKET_SUBPROTOCOL: - if (subprotocols == null) - subprotocols = new QuotedCSV(field.getValue()); - else - subprotocols.addValue(field.getValue()); - break; - - default: - } - } - } - - this.version = version; - this.key = key; - this.upgrade = upgrade != null && connectionCSVs != null && connectionCSVs.getValues().stream().anyMatch(s -> s.equalsIgnoreCase("Upgrade")); - - Set available = components.getExtensionRegistry().getAvailableExtensionNames(); - offeredExtensions = extensions == null - ? Collections.emptyList() - : extensions.getValues().stream() - .map(ExtensionConfig::parse) - .filter(ec -> available.contains(ec.getName().toLowerCase()) && !ec.getName().startsWith("@")) - .collect(Collectors.toList()); - - offeredSubprotocols = subprotocols == null - ? Collections.emptyList() - : subprotocols.getValues(); - - negotiatedExtensions = new ArrayList<>(); - for (ExtensionConfig config : offeredExtensions) - { - long matches = negotiatedExtensions.stream() - .filter(negotiatedConfig -> negotiatedConfig.getName().equals(config.getName())).count(); - if (matches == 0) - negotiatedExtensions.add(config); - } - } - catch (Throwable t) - { - throw new BadMessageException("Invalid Handshake Request", t); - } - } - - public String getKey() - { - return key; - } - - public List getOfferedExtensions() - { - return offeredExtensions; - } - - public void setNegotiatedExtensions(List extensions) - { - if (extensions == offeredExtensions) - return; - negotiatedExtensions = extensions == null ? null : new ArrayList<>(extensions); - extensionStack = null; - } - - public List getNegotiatedExtensions() - { - return negotiatedExtensions; - } - - public List getOfferedSubprotocols() - { - return offeredSubprotocols; + this.components = webSocketComponents; } public Request getBaseRequest() @@ -193,25 +72,113 @@ public class Negotiation return response; } - public void setSubprotocol(String subprotocol) + public void negotiate() throws BadMessageException { - this.subprotocol = subprotocol; - response.setHeader(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL.asString(), subprotocol); + try + { + negotiateHeaders(getBaseRequest()); + } + catch (Throwable x) + { + throw new BadMessageException("Invalid upgrade request", x); + } } - public String getSubprotocol() + protected void negotiateHeaders(Request baseRequest) { - return subprotocol; + QuotedCSV extensions = null; + QuotedCSV protocols = null; + for (HttpField field : baseRequest.getHttpFields()) + { + if (field.getHeader() != null) + { + switch (field.getHeader()) + { + case SEC_WEBSOCKET_VERSION: + version = field.getValue(); + break; + + case SEC_WEBSOCKET_EXTENSIONS: + if (extensions == null) + extensions = new QuotedCSV(field.getValue()); + else + extensions.addValue(field.getValue()); + break; + + case SEC_WEBSOCKET_SUBPROTOCOL: + if (protocols == null) + protocols = new QuotedCSV(field.getValue()); + else + protocols.addValue(field.getValue()); + break; + + default: + break; + } + } + } + + Set available = components.getExtensionRegistry().getAvailableExtensionNames(); + offeredExtensions = extensions == null + ? Collections.emptyList() + : extensions.getValues().stream() + .map(ExtensionConfig::parse) + .filter(ec -> available.contains(ec.getName().toLowerCase()) && !ec.getName().startsWith("@")) + .collect(Collectors.toList()); + + offeredProtocols = protocols == null + ? Collections.emptyList() + : protocols.getValues(); + + negotiatedExtensions = new ArrayList<>(); + for (ExtensionConfig config : offeredExtensions) + { + long matches = negotiatedExtensions.stream() + .filter(negotiatedConfig -> negotiatedConfig.getName().equals(config.getName())).count(); + if (matches == 0) + negotiatedExtensions.add(config); + } } + public abstract boolean isSuccessful(); + public String getVersion() { return version; } - public boolean isUpgrade() + public String getSubprotocol() { - return upgrade; + return protocol; + } + + public void setSubprotocol(String protocol) + { + this.protocol = protocol; + response.setHeader(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL.asString(), protocol); + } + + public List getOfferedSubprotocols() + { + return offeredProtocols; + } + + public List getOfferedExtensions() + { + return offeredExtensions; + } + + public List getNegotiatedExtensions() + { + return negotiatedExtensions; + } + + public void setNegotiatedExtensions(List extensions) + { + if (extensions == offeredExtensions) + return; + negotiatedExtensions = extensions; + extensionStack = null; } public ExtensionStack getExtensionStack() @@ -229,14 +196,14 @@ public class Negotiation else baseRequest.getResponse().setHeader(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, null); } - return extensionStack; } @Override public String toString() { - return String.format("Negotiation@%x{uri=%s,oe=%s,op=%s}", + return String.format("%s@%x{uri=%s,oe=%s,op=%s}", + getClass().getSimpleName(), hashCode(), getRequest().getRequestURI(), getOfferedExtensions(), diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java new file mode 100644 index 00000000000..b11080af73e --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java @@ -0,0 +1,211 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.core.server.internal; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.Executor; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.PreEncodedHttpField; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpTransport; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.websocket.core.Behavior; +import org.eclipse.jetty.websocket.core.ExtensionConfig; +import org.eclipse.jetty.websocket.core.FrameHandler; +import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.WebSocketConstants; +import org.eclipse.jetty.websocket.core.WebSocketException; +import org.eclipse.jetty.websocket.core.internal.ExtensionStack; +import org.eclipse.jetty.websocket.core.internal.Negotiated; +import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; +import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; +import org.eclipse.jetty.websocket.core.server.Handshaker; +import org.eclipse.jetty.websocket.core.server.Negotiation; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; + +public abstract class AbstractHandshaker implements Handshaker +{ + protected static final Logger LOG = Log.getLogger(RFC8441Handshaker.class); + private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION); + + @Override + public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException + { + if (!validateRequest(request)) + return false; + + Negotiation negotiation = newNegotiation(request, response, new WebSocketComponents()); + if (LOG.isDebugEnabled()) + LOG.debug("negotiation {}", negotiation); + negotiation.negotiate(); + + if (!validateNegotiation(negotiation)) + return false; + + // Negotiate the FrameHandler + FrameHandler handler = negotiator.negotiate(negotiation); + if (handler == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no frame handler provided {}", request); + return false; + } + + // Handle error responses + Request baseRequest = negotiation.getBaseRequest(); + if (response.isCommitted()) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: response committed {}", request); + baseRequest.setHandled(true); + return false; + } + int httpStatus = response.getStatus(); + if (httpStatus > 200) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: invalid http code {} {}", httpStatus, request); + response.flushBuffer(); + baseRequest.setHandled(true); + return false; + } + + + // Validate negotiated protocol + String protocol = negotiation.getSubprotocol(); + List offeredProtocols = negotiation.getOfferedSubprotocols(); + if (protocol != null) + { + if (!offeredProtocols.contains(protocol)) + throw new WebSocketException("not upgraded: selected a protocol not present in offered protocols"); + } + else + { + if (!offeredProtocols.isEmpty()) + throw new WebSocketException("not upgraded: no protocol selected from offered protocols"); + } + + // validate negotiated extensions + for (ExtensionConfig config : negotiation.getNegotiatedExtensions()) + { + if (config.getName().startsWith("@")) + continue; + + long matches = negotiation.getOfferedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); + if (matches < 1) + throw new WebSocketException("Upgrade failed: negotiated extension not requested"); + + matches = negotiation.getNegotiatedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); + if (matches > 1) + throw new WebSocketException("Upgrade failed: multiple negotiated extensions of the same name"); + } + + // Create and Negotiate the ExtensionStack + ExtensionStack extensionStack = negotiation.getExtensionStack(); + + Negotiated negotiated = new Negotiated(baseRequest.getHttpURI().toURI(), protocol, baseRequest.isSecure(), extensionStack, WebSocketConstants.SPEC_VERSION_STRING); + + // Create the Session + WebSocketCoreSession coreSession = newWebSocketCoreSession(handler, negotiated); + if (defaultCustomizer != null) + defaultCustomizer.customize(coreSession); + negotiator.customize(coreSession); + + if (LOG.isDebugEnabled()) + LOG.debug("session {}", coreSession); + + WebSocketConnection connection = createWebSocketConnection(baseRequest, coreSession); + if (LOG.isDebugEnabled()) + LOG.debug("connection {}", connection); + if (connection == null) + throw new WebSocketException("not upgraded: no connection"); + + HttpChannel httpChannel = baseRequest.getHttpChannel(); + HttpConfiguration httpConfig = httpChannel.getHttpConfiguration(); + connection.setUseInputDirectByteBuffers(httpConfig.isUseInputDirectByteBuffers()); + connection.setUseOutputDirectByteBuffers(httpChannel.isUseOutputDirectByteBuffers()); + + httpChannel.getConnector().getEventListeners().forEach(connection::addEventListener); + + coreSession.setWebSocketConnection(connection); + + Response baseResponse = baseRequest.getResponse(); + prepareResponse(baseResponse, negotiation); + if (httpConfig.getSendServerVersion()) + baseResponse.getHttpFields().put(SERVER_VERSION); + baseResponse.flushBuffer(); + baseRequest.setHandled(true); + + baseRequest.setAttribute(HttpTransport.UPGRADE_CONNECTION_ATTRIBUTE, connection); + + if (LOG.isDebugEnabled()) + LOG.debug("upgrade connection={} session={} framehandler={}", connection, coreSession, handler); + + return true; + } + + protected abstract boolean validateRequest(HttpServletRequest request); + + protected abstract Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents); + + protected boolean validateNegotiation(Negotiation negotiation) + { + if (!negotiation.isSuccessful()) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no upgrade header or connection upgrade", negotiation.getBaseRequest()); + return false; + } + + if (!WebSocketConstants.SPEC_VERSION_STRING.equals(negotiation.getVersion())) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: unsupported version {} {}", negotiation.getVersion(), negotiation.getBaseRequest()); + return false; + } + + return true; + } + + protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated) + { + return new WebSocketCoreSession(handler, Behavior.SERVER, negotiated); + } + + protected abstract WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession); + + protected WebSocketConnection newWebSocketConnection(EndPoint endPoint, Executor executor, Scheduler scheduler, ByteBufferPool byteBufferPool, WebSocketCoreSession coreSession) + { + return new WebSocketConnection(endPoint, executor, scheduler, byteBufferPool, coreSession); + } + + protected abstract void prepareResponse(Response response, Negotiation negotiation); +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java index 314c4394dfc..f5398e0e491 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java @@ -18,54 +18,33 @@ package org.eclipse.jetty.websocket.core.server.internal; -import java.io.IOException; -import java.util.concurrent.Executor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.PreEncodedHttpField; -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpChannel; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.HttpTransport; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Scheduler; -import org.eclipse.jetty.websocket.core.Behavior; -import org.eclipse.jetty.websocket.core.ExtensionConfig; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; -import org.eclipse.jetty.websocket.core.WebSocketConstants; -import org.eclipse.jetty.websocket.core.WebSocketException; -import org.eclipse.jetty.websocket.core.internal.ExtensionStack; -import org.eclipse.jetty.websocket.core.internal.Negotiated; import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; import org.eclipse.jetty.websocket.core.internal.WebSocketCore; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; -import org.eclipse.jetty.websocket.core.server.Handshaker; import org.eclipse.jetty.websocket.core.server.Negotiation; -import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; -public final class RFC6455Handshaker implements Handshaker +public final class RFC6455Handshaker extends AbstractHandshaker { - static final Logger LOG = Log.getLogger(RFC6455Handshaker.class); private static final HttpField UPGRADE_WEBSOCKET = new PreEncodedHttpField(HttpHeader.UPGRADE, "WebSocket"); private static final HttpField CONNECTION_UPGRADE = new PreEncodedHttpField(HttpHeader.CONNECTION, HttpHeader.UPGRADE.asString()); - private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION); - public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, - FrameHandler.Customizer defaultCustomizer) throws IOException + @Override + protected boolean validateRequest(HttpServletRequest request) { if (!HttpMethod.GET.is(request.getMethod())) { @@ -74,176 +53,48 @@ public final class RFC6455Handshaker implements Handshaker return false; } - final Request baseRequest = Request.getBaseRequest(request); - if (!HttpVersion.HTTP_1_1.equals(baseRequest.getHttpVersion())) + if (!HttpVersion.HTTP_1_1.is(request.getProtocol())) { if (LOG.isDebugEnabled()) - LOG.debug("not upgraded version!=1.1 {}", baseRequest); + LOG.debug("not upgraded version!=1.1 {}", request); return false; } - Negotiation negotiation = new Negotiation(baseRequest, request, response, new WebSocketComponents()); - if (LOG.isDebugEnabled()) - LOG.debug("negotiation {}", negotiation); - - if (!negotiation.isUpgrade()) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no upgrade header or connection upgrade", baseRequest); - return false; - } - - if (!WebSocketConstants.SPEC_VERSION_STRING.equals(negotiation.getVersion())) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: unsupported version {} {}", negotiation.getVersion(), baseRequest); - return false; - } - - if (negotiation.getKey() == null) - throw new BadMessageException("Missing request header 'Sec-WebSocket-Key'"); - - // Negotiate the FrameHandler - FrameHandler handler = negotiator.negotiate(negotiation); - if (LOG.isDebugEnabled()) - LOG.debug("negotiated handler {}", handler); - - // Handle error responses - if (response.isCommitted()) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: response committed {}", baseRequest); - baseRequest.setHandled(true); - return false; - } - if (response.getStatus() > 200) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: error sent {} {}", response.getStatus(), baseRequest); - response.flushBuffer(); - baseRequest.setHandled(true); - return false; - } - - // Check for handler - if (handler == null) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no frame handler provided {}", baseRequest); - return false; - } - - // validate negotiated subprotocol - String subprotocol = negotiation.getSubprotocol(); - if (subprotocol != null) - { - if (!negotiation.getOfferedSubprotocols().contains(subprotocol)) - throw new WebSocketException("not upgraded: selected a subprotocol not present in offered subprotocols"); - } - else - { - if (!negotiation.getOfferedSubprotocols().isEmpty()) - throw new WebSocketException("not upgraded: no subprotocol selected from offered subprotocols"); - } - - // validate negotiated extensions - for (ExtensionConfig config : negotiation.getNegotiatedExtensions()) - { - if (config.getName().startsWith("@")) - continue; - - long matches = negotiation.getOfferedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); - if (matches < 1) - throw new WebSocketException("Upgrade failed: negotiated extension not requested"); - - matches = negotiation.getNegotiatedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); - if (matches > 1) - throw new WebSocketException("Upgrade failed: multiple negotiated extensions of the same name"); - } - - // Create and Negotiate the ExtensionStack - ExtensionStack extensionStack = negotiation.getExtensionStack(); - - Negotiated negotiated = new Negotiated( - baseRequest.getHttpURI().toURI(), - subprotocol, - baseRequest.isSecure(), - extensionStack, - WebSocketConstants.SPEC_VERSION_STRING); - - // Create the Session - WebSocketCoreSession coreSession = newWebSocketCoreSession(handler, negotiated); - if (defaultCustomizer != null) - defaultCustomizer.customize(coreSession); - negotiator.customize(coreSession); - - if (LOG.isDebugEnabled()) - LOG.debug("session {}", coreSession); - - // Create a connection - HttpChannel httpChannel = baseRequest.getHttpChannel(); - Connector connector = httpChannel.getConnector(); - WebSocketConnection connection = newWebSocketConnection(httpChannel.getEndPoint(), connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); - // TODO: perhaps use of direct buffers should be WebSocket specific - // rather than inheriting the setting from HttpConfiguration. - HttpConfiguration httpConfig = httpChannel.getHttpConfiguration(); - connection.setUseInputDirectByteBuffers(httpConfig.isUseInputDirectByteBuffers()); - connection.setUseOutputDirectByteBuffers(httpChannel.isUseOutputDirectByteBuffers()); - if (LOG.isDebugEnabled()) - LOG.debug("connection {}", connection); - if (connection == null) - throw new WebSocketException("not upgraded: no connection"); - - connector.getEventListeners().forEach(connection::addEventListener); - - coreSession.setWebSocketConnection(connection); - - // send upgrade response - Response baseResponse = baseRequest.getResponse(); - baseResponse.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); - baseResponse.getHttpFields().put(UPGRADE_WEBSOCKET); - baseResponse.getHttpFields().put(CONNECTION_UPGRADE); - baseResponse.getHttpFields().put(HttpHeader.SEC_WEBSOCKET_ACCEPT, WebSocketCore.hashKey(negotiation.getKey())); - - // See bugs.eclipse.org/485969 - if (getSendServerVersion(connector)) - { - baseResponse.getHttpFields().put(SERVER_VERSION); - } - - baseResponse.flushBuffer(); - baseRequest.setHandled(true); - - // upgrade - if (LOG.isDebugEnabled()) - LOG.debug("upgrade connection={} session={}", connection, coreSession); - - baseRequest.setAttribute(HttpTransport.UPGRADE_CONNECTION_ATTRIBUTE, connection); return true; } - protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated) + @Override + protected Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents) { - return new WebSocketCoreSession(handler, Behavior.SERVER, negotiated); + return new RFC6544Negotiation(Request.getBaseRequest(request), request, response, webSocketComponents); } - protected WebSocketConnection newWebSocketConnection(EndPoint endPoint, Executor executor, Scheduler scheduler, ByteBufferPool byteBufferPool, WebSocketCoreSession coreSession) + @Override + protected boolean validateNegotiation(Negotiation negotiation) { - return new WebSocketConnection(endPoint, executor, scheduler, byteBufferPool, coreSession); - } - - private boolean getSendServerVersion(Connector connector) - { - ConnectionFactory connFactory = connector.getConnectionFactory(HttpVersion.HTTP_1_1.asString()); - if (connFactory == null) + boolean result = super.validateNegotiation(negotiation); + if (!result) return false; + if (((RFC6544Negotiation)negotiation).getKey() == null) + throw new BadMessageException("Missing request header 'Sec-WebSocket-Key'"); + return true; + } - if (connFactory instanceof HttpConnectionFactory) - { - HttpConfiguration httpConf = ((HttpConnectionFactory)connFactory).getHttpConfiguration(); - if (httpConf != null) - return httpConf.getSendServerVersion(); - } - return false; + @Override + protected WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession) + { + HttpChannel httpChannel = baseRequest.getHttpChannel(); + Connector connector = httpChannel.getConnector(); + return newWebSocketConnection(httpChannel.getEndPoint(), connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); + } + + @Override + protected void prepareResponse(Response response, Negotiation negotiation) + { + response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); + HttpFields responseFields = response.getHttpFields(); + responseFields.put(UPGRADE_WEBSOCKET); + responseFields.put(CONNECTION_UPGRADE); + responseFields.put(HttpHeader.SEC_WEBSOCKET_ACCEPT, WebSocketCore.hashKey(((RFC6544Negotiation)negotiation).getKey())); } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6544Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6544Negotiation.java new file mode 100644 index 00000000000..f836c9b7986 --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6544Negotiation.java @@ -0,0 +1,90 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.core.server.internal; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.BadMessageException; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.QuotedCSV; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.websocket.core.WebSocketComponents; +import org.eclipse.jetty.websocket.core.server.Negotiation; + +public class RFC6544Negotiation extends Negotiation +{ + private boolean successful; + private String key; + + public RFC6544Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents components) throws BadMessageException + { + super(baseRequest, request, response, components); + } + + @Override + protected void negotiateHeaders(Request baseRequest) + { + super.negotiateHeaders(baseRequest); + + boolean upgrade = false; + QuotedCSV connectionCSVs = null; + for (HttpField field : baseRequest.getHttpFields()) + { + HttpHeader header = field.getHeader(); + if (header != null) + { + switch (header) + { + case UPGRADE: + upgrade = "websocket".equalsIgnoreCase(field.getValue()); + break; + + case CONNECTION: + if (connectionCSVs == null) + connectionCSVs = new QuotedCSV(); + connectionCSVs.addValue(field.getValue()); + break; + + case SEC_WEBSOCKET_KEY: + key = field.getValue(); + break; + + default: + break; + } + } + } + + successful = upgrade && connectionCSVs != null && + connectionCSVs.getValues().stream().anyMatch(s -> s.equalsIgnoreCase("upgrade")); + } + + @Override + public boolean isSuccessful() + { + return successful; + } + + public String getKey() + { + return key; + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java index 9c75b53a0ce..ae9c19364c1 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java @@ -18,220 +18,62 @@ package org.eclipse.jetty.websocket.core.server.internal; -import java.io.IOException; -import java.util.concurrent.Executor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.HttpField; -import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.http.PreEncodedHttpField; -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpChannel; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.HttpTransport; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Scheduler; -import org.eclipse.jetty.websocket.core.Behavior; -import org.eclipse.jetty.websocket.core.ExtensionConfig; -import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; -import org.eclipse.jetty.websocket.core.WebSocketConstants; -import org.eclipse.jetty.websocket.core.WebSocketException; -import org.eclipse.jetty.websocket.core.internal.ExtensionStack; -import org.eclipse.jetty.websocket.core.internal.Negotiated; import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; -import org.eclipse.jetty.websocket.core.server.Handshaker; import org.eclipse.jetty.websocket.core.server.Negotiation; -import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; -public class RFC8441Handshaker implements Handshaker +public class RFC8441Handshaker extends AbstractHandshaker { - static final Logger LOG = Log.getLogger(RFC8441Handshaker.class); - private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION); - @Override - public boolean upgradeRequest(WebSocketNegotiator negotiator, HttpServletRequest request, HttpServletResponse response, FrameHandler.Customizer defaultCustomizer) throws IOException + protected boolean validateRequest(HttpServletRequest request) { if (!HttpMethod.CONNECT.is(request.getMethod())) { if (LOG.isDebugEnabled()) - LOG.debug("not upgraded method!=GET {}", request.toString()); + LOG.debug("not upgraded method!=GET {}", request); return false; } - Request baseRequest = Request.getBaseRequest(request); - if (!HttpVersion.HTTP_2.equals(baseRequest.getHttpVersion())) + if (!HttpVersion.HTTP_2.is(request.getProtocol())) { if (LOG.isDebugEnabled()) - LOG.debug("not upgraded HttpVersion!=2 {}", baseRequest); + LOG.debug("not upgraded HttpVersion!=2 {}", request); return false; } - Negotiation negotiation = new RFC8441Negotiation(baseRequest, request, response, new WebSocketComponents()); - if (LOG.isDebugEnabled()) - LOG.debug("negotiation {}", negotiation); - - if (!negotiation.isUpgrade()) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no upgrade header or connection upgrade", baseRequest); - return false; - } - - if (!WebSocketConstants.SPEC_VERSION_STRING.equals(negotiation.getVersion())) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: unsupported version {} {}", negotiation.getVersion(), baseRequest); - return false; - } - - // Negotiate the FrameHandler - FrameHandler handler = negotiator.negotiate(negotiation); - if (LOG.isDebugEnabled()) - LOG.debug("negotiated handler {}", handler); - - // Handle error responses - if (response.isCommitted()) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: response committed {}", baseRequest); - baseRequest.setHandled(true); - return false; - } - if (response.getStatus() > 200) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: error sent {} {}", response.getStatus(), baseRequest); - response.flushBuffer(); - baseRequest.setHandled(true); - return false; - } - - // Check for handler - if (handler == null) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no frame handler provided {}", baseRequest); - return false; - } - - // validate negotiated subprotocol - String subprotocol = negotiation.getSubprotocol(); - if (subprotocol != null) - { - if (!negotiation.getOfferedSubprotocols().contains(subprotocol)) - throw new WebSocketException("not upgraded: selected a subprotocol not present in offered subprotocols"); - } - else - { - if (!negotiation.getOfferedSubprotocols().isEmpty()) - throw new WebSocketException("not upgraded: no subprotocol selected from offered subprotocols"); - } - - // validate negotiated extensions - for (ExtensionConfig config : negotiation.getNegotiatedExtensions()) - { - if (config.getName().startsWith("@")) - continue; - - long matches = negotiation.getOfferedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); - if (matches < 1) - throw new WebSocketException("Upgrade failed: negotiated extension not requested"); - - matches = negotiation.getNegotiatedExtensions().stream().filter(c -> config.getName().equalsIgnoreCase(c.getName())).count(); - if (matches > 1) - throw new WebSocketException("Upgrade failed: multiple negotiated extensions of the same name"); - } - - // Create and Negotiate the ExtensionStack - ExtensionStack extensionStack = negotiation.getExtensionStack(); - - Negotiated negotiated = new Negotiated( - baseRequest.getHttpURI().toURI(), - subprotocol, - baseRequest.isSecure(), - extensionStack, - WebSocketConstants.SPEC_VERSION_STRING); - - // Create the Channel - WebSocketCoreSession coreSession = newWebSocketCoreSession(handler, negotiated); - if (defaultCustomizer != null) - defaultCustomizer.customize(coreSession); - negotiator.customize(coreSession); - - if (LOG.isDebugEnabled()) - LOG.debug("coreSession {}", coreSession); - - // Create the Connection - HttpChannel httpChannel = baseRequest.getHttpChannel(); - Connector connector = httpChannel.getConnector(); - EndPoint endPoint = httpChannel.getTunnellingEndPoint(); - WebSocketConnection connection = newWebSocketConnection(endPoint, connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); - if (LOG.isDebugEnabled()) - LOG.debug("connection {}", connection); - if (connection == null) - throw new WebSocketException("not upgraded: no connection"); - - for (Connection.Listener listener : connector.getBeans(Connection.Listener.class)) - { - connection.addEventListener(listener); - } - - coreSession.setWebSocketConnection(connection); - - // send upgrade response - Response baseResponse = baseRequest.getResponse(); - baseResponse.setStatus(HttpStatus.OK_200); - - // See bugs.eclipse.org/485969 - if (getSendServerVersion(connector)) - baseResponse.getHttpFields().put(SERVER_VERSION); - - baseRequest.setHandled(true); - - // upgrade - if (LOG.isDebugEnabled()) - LOG.debug("upgrade connection={} session={}", connection, coreSession); - - baseRequest.setAttribute(HttpTransport.UPGRADE_CONNECTION_ATTRIBUTE, connection); return true; } - protected WebSocketCoreSession newWebSocketCoreSession(FrameHandler handler, Negotiated negotiated) + @Override + protected Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents) { - return new WebSocketCoreSession(handler, Behavior.SERVER, negotiated); + return new RFC8441Negotiation(Request.getBaseRequest(request), request, response, webSocketComponents); } - protected WebSocketConnection newWebSocketConnection(EndPoint endPoint, Executor executor, Scheduler scheduler, ByteBufferPool byteBufferPool, WebSocketCoreSession coreSession) + @Override + protected WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession) { - return new WebSocketConnection(endPoint, executor, scheduler, byteBufferPool, coreSession); + HttpChannel httpChannel = baseRequest.getHttpChannel(); + Connector connector = httpChannel.getConnector(); + EndPoint endPoint = httpChannel.getTunnellingEndPoint(); + return newWebSocketConnection(endPoint, connector.getExecutor(), connector.getScheduler(), connector.getByteBufferPool(), coreSession); } - private boolean getSendServerVersion(Connector connector) + @Override + protected void prepareResponse(Response response, Negotiation negotiation) { - ConnectionFactory connFactory = connector.getConnectionFactory(HttpVersion.HTTP_2.asString()); - if (connFactory == null) - return false; - - if (connFactory instanceof HttpConnectionFactory) - { - HttpConfiguration httpConf = ((HttpConnectionFactory)connFactory).getHttpConfiguration(); - if (httpConf != null) - return httpConf.getSendServerVersion(); - } - return false; + response.setStatus(HttpStatus.OK_200); } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java index ac3f01b8ccb..eaee84d6437 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java @@ -22,6 +22,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.BadMessageException; +import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.server.Negotiation; @@ -34,11 +35,11 @@ public class RFC8441Negotiation extends Negotiation } @Override - public boolean isUpgrade() + public boolean isSuccessful() { - if (!getBaseRequest().hasMetaData()) + MetaData.Request metaData = getBaseRequest().getMetaData(); + if (metaData == null) return false; - - return "websocket".equals(getBaseRequest().getMetaData().getProtocol()); + return "websocket".equals(metaData.getProtocol()); } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java index ce78b1cf86f..9e4e3e0cce6 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java @@ -97,7 +97,7 @@ public class WebSocketNegotiationTest extends WebSocketTester break; case "testNotAcceptingExtensions": - negotiation.setNegotiatedExtensions(Collections.EMPTY_LIST); + negotiation.setNegotiatedExtensions(Collections.emptyList()); break; case "testNoSubProtocolSelected": @@ -353,4 +353,4 @@ public class WebSocketNegotiationTest extends WebSocketTester assertThat(response, containsString("400 Bad Request")); } -} \ No newline at end of file +} diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServer.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServer.java index 478a57fb013..955fe846794 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServer.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServer.java @@ -26,15 +26,12 @@ import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.server.Negotiation; import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; import org.eclipse.jetty.websocket.core.server.WebSocketUpgradeHandler; public class WebSocketServer { - private static Logger LOG = Log.getLogger(WebSocketServer.class); private final Server server; private URI serverUri; @@ -59,12 +56,12 @@ public class WebSocketServer return server; } - public WebSocketServer(FrameHandler frameHandler) throws Exception + public WebSocketServer(FrameHandler frameHandler) { this(new DefaultNegotiator(frameHandler)); } - public WebSocketServer(WebSocketNegotiator negotiator) throws Exception + public WebSocketServer(WebSocketNegotiator negotiator) { server = new Server(); ServerConnector connector = new ServerConnector(server); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketServer.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketServer.java index 8b9e87911c0..c12c300b788 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketServer.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketServer.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -34,8 +33,6 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.MessageHandler; @@ -47,8 +44,6 @@ import static org.eclipse.jetty.util.Callback.NOOP; public class ChatWebSocketServer { - private static Logger LOG = Log.getLogger(ChatWebSocketServer.class); - private Set members = new HashSet<>(); private FrameHandler negotiate(Negotiation negotiation) @@ -77,7 +72,7 @@ public class ChatWebSocketServer { members.add(this); callback.succeeded(); - }, x -> callback.failed(x))); + }, callback::failed)); } @Override From 5e695919d98a28c05e3161b08ef814021ef5950b Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 14 Nov 2019 23:48:34 +0100 Subject: [PATCH 09/77] Implemented support for RFC 8441's SETTING_ENABLE_CONNECT_PROTOCOL. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/http2/HTTP2Session.java | 20 ++++++ .../jetty/http2/frames/SettingsFrame.java | 1 + .../AbstractHTTP2ServerConnectionFactory.java | 14 ++++ .../http2/server/HTTP2ServerSession.java | 10 +++ .../eclipse/jetty/server/session/Session.java | 2 +- jetty-websocket/jetty-websocket-tests/pom.xml | 12 ++++ .../tests/WebSocketOverHTTP2Test.java | 62 ++++++++++++++++-- .../src/test/resources/keystore.p12 | Bin 0 -> 2533 bytes .../server/internal/AbstractHandshaker.java | 3 +- .../server/internal/RFC6455Handshaker.java | 6 +- ...gotiation.java => RFC6455Negotiation.java} | 4 +- 11 files changed, 122 insertions(+), 12 deletions(-) create mode 100644 jetty-websocket/jetty-websocket-tests/src/test/resources/keystore.p12 rename jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/{RFC6544Negotiation.java => RFC6455Negotiation.java} (96%) diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java index d385acbdff1..89cadfa5ed9 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java @@ -97,6 +97,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio private int initialSessionRecvWindow; private int writeThreshold; private boolean pushEnabled; + private boolean connectProtocolEnabled; private long idleTime; private GoAwayFrame closeFrame; @@ -370,6 +371,14 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio generator.setMaxHeaderListSize(value); break; } + case SettingsFrame.ENABLE_CONNECT_PROTOCOL: + { + boolean enabled = value == 1; + if (LOG.isDebugEnabled()) + LOG.debug("{} CONNECT protocol for {}", enabled ? "Enabling" : "Disabling", this); + connectProtocolEnabled = enabled; + break; + } default: { if (LOG.isDebugEnabled()) @@ -906,6 +915,17 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio return pushEnabled; } + @ManagedAttribute(value = "Whether CONNECT requests supports a protocol", readonly = true) + public boolean isConnectProtocolEnabled() + { + return connectProtocolEnabled; + } + + public void setConnectProtocolEnabled(boolean connectProtocolEnabled) + { + this.connectProtocolEnabled = connectProtocolEnabled; + } + /** * A typical close by a remote peer involves a GO_AWAY frame followed by TCP FIN. * This method is invoked when the TCP FIN is received, or when an exception is diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/SettingsFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/SettingsFrame.java index 4a4e2d4247f..e030491ca19 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/SettingsFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/SettingsFrame.java @@ -30,6 +30,7 @@ public class SettingsFrame extends Frame public static final int INITIAL_WINDOW_SIZE = 4; public static final int MAX_FRAME_SIZE = 5; public static final int MAX_HEADER_LIST_SIZE = 6; + public static final int ENABLE_CONNECT_PROTOCOL = 8; private final Map settings; private final boolean reply; diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java index 7f55001654a..62401bbb7ab 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java @@ -60,6 +60,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne private int maxHeaderBlockFragment = 0; private int maxFrameLength = Frame.DEFAULT_MAX_LENGTH; private int maxSettingsKeys = SettingsFrame.DEFAULT_MAX_KEYS; + private boolean connectProtocolEnabled = true; private RateControl.Factory rateControlFactory = new WindowRateControl.Factory(20); private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F); private long streamIdleTimeout; @@ -185,6 +186,17 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne this.maxSettingsKeys = maxSettingsKeys; } + @ManagedAttribute("Whether CONNECT requests supports a protocol") + public boolean isConnectProtocolEnabled() + { + return connectProtocolEnabled; + } + + public void setConnectProtocolEnabled(boolean connectProtocolEnabled) + { + this.connectProtocolEnabled = connectProtocolEnabled; + } + /** * @return the factory that creates RateControl objects */ @@ -237,6 +249,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne if (maxConcurrentStreams >= 0) settings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, maxConcurrentStreams); settings.put(SettingsFrame.MAX_HEADER_LIST_SIZE, getHttpConfiguration().getRequestHeaderSize()); + settings.put(SettingsFrame.ENABLE_CONNECT_PROTOCOL, isConnectProtocolEnabled() ? 1 : 0); return settings; } @@ -259,6 +272,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne session.setStreamIdleTimeout(streamIdleTimeout); session.setInitialSessionRecvWindow(getInitialSessionRecvWindow()); session.setWriteThreshold(getHttpConfiguration().getOutputBufferSize()); + session.setConnectProtocolEnabled(isConnectProtocolEnabled()); ServerParser parser = newServerParser(connector, session, getRateControlFactory().newRateControl(endPoint)); parser.setMaxFrameLength(getMaxFrameLength()); diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java index b5ee20f1463..8b728dd984a 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerSession.java @@ -108,6 +108,16 @@ public class HTTP2ServerSession extends HTTP2Session implements ServerParser.Lis if (stream != null) { onStreamOpened(stream); + + if (metaData instanceof MetaData.ConnectRequest) + { + if (!isConnectProtocolEnabled() && ((MetaData.ConnectRequest)metaData).getProtocol() != null) + { + stream.reset(new ResetFrame(streamId, ErrorCode.PROTOCOL_ERROR.code), Callback.NOOP); + return; + } + } + stream.process(frame, Callback.NOOP); Stream.Listener listener = notifyNewStream(stream, frame); stream.setListener(listener); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java index 50656e17f40..6fe973e6ff1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java @@ -378,7 +378,7 @@ public class Session implements SessionHandler.SessionIf try { HttpSessionEvent event = new HttpSessionEvent(this); - for (String name : _sessionData.getKeys()) + for (String name : _sessionData.getKeys()) { Object value = _sessionData.getAttribute(name); if (value instanceof HttpSessionActivationListener) diff --git a/jetty-websocket/jetty-websocket-tests/pom.xml b/jetty-websocket/jetty-websocket-tests/pom.xml index 371005bd234..99eca30543a 100644 --- a/jetty-websocket/jetty-websocket-tests/pom.xml +++ b/jetty-websocket/jetty-websocket-tests/pom.xml @@ -45,6 +45,18 @@ ${project.version} test + + org.eclipse.jetty + jetty-alpn-server + ${project.version} + test + + + org.eclipse.jetty + jetty-alpn-java-server + ${project.version} + test + org.eclipse.jetty.http2 http2-http-client-transport diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java index 492b7c3afcc..84ae11d94d4 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java @@ -19,23 +19,32 @@ package org.eclipse.jetty.websocket.tests; import java.net.URI; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.function.Function; +import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; import org.eclipse.jetty.client.http.HttpClientConnectionFactory; +import org.eclipse.jetty.http2.ErrorCode; +import org.eclipse.jetty.http2.HTTP2Cipher; import org.eclipse.jetty.http2.client.HTTP2Client; import org.eclipse.jetty.http2.client.http.ClientConnectionFactoryOverHTTP2; +import org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory; import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; +import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.SslConnectionFactory; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; @@ -44,9 +53,12 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsStringIgnoringCase; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -56,6 +68,7 @@ public class WebSocketOverHTTP2Test { private Server server; private ServerConnector connector; + private ServerConnector tlsConnector; @BeforeEach public void startServer() throws Exception @@ -63,12 +76,27 @@ public class WebSocketOverHTTP2Test QueuedThreadPool serverThreads = new QueuedThreadPool(); serverThreads.setName("server"); server = new Server(serverThreads); - HttpConfiguration httpConfiguration = new HttpConfiguration(); - HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration); - HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(httpConfiguration); - connector = new ServerConnector(server, 1, 1, h1, h2c); + HttpConfiguration httpConfig = new HttpConfiguration(); + HttpConnectionFactory h1c = new HttpConnectionFactory(httpConfig); + HTTP2CServerConnectionFactory h2c = new HTTP2CServerConnectionFactory(httpConfig); + connector = new ServerConnector(server, 1, 1, h1c, h2c); server.addConnector(connector); + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12"); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); + + HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); + httpsConfig.addCustomizer(new SecureRequestCustomizer()); + HttpConnectionFactory h1s = new HttpConnectionFactory(httpsConfig); + HTTP2ServerConnectionFactory h2s = new HTTP2ServerConnectionFactory(httpsConfig); + ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); + alpn.setDefaultProtocol(h1c.getProtocol()); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol()); + tlsConnector = new ServerConnector(server, 1, 1, ssl, alpn, h2s, h1s); + server.addConnector(tlsConnector); + ServletContextHandler context = new ServletContextHandler(server, "/"); context.addServlet(new ServletHolder(new JettyWebSocketServlet() { @@ -128,4 +156,30 @@ public class WebSocketOverHTTP2Test assertEquals(StatusCode.NORMAL, wsEndPoint.statusCode); assertNull(wsEndPoint.error); } + + @Test + public void testConnectProtocolDisabled() throws Exception + { + AbstractHTTP2ServerConnectionFactory h2c = connector.getBean(AbstractHTTP2ServerConnectionFactory.class); + h2c.setConnectProtocolEnabled(false); + + ClientConnector clientConnector = new ClientConnector(); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + clientConnector.setExecutor(clientThreads); + HTTP2Client http2Client = new HTTP2Client(clientConnector); + HttpClient httpClient = new HttpClient(new HttpClientTransportDynamic(clientConnector, new ClientConnectionFactoryOverHTTP2.H2C(http2Client))); + + WebSocketClient wsClient = new WebSocketClient(httpClient); + wsClient.start(); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/echo"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause.getMessage(), containsStringIgnoringCase(ErrorCode.PROTOCOL_ERROR.name())); + } } diff --git a/jetty-websocket/jetty-websocket-tests/src/test/resources/keystore.p12 b/jetty-websocket/jetty-websocket-tests/src/test/resources/keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..b51c835024b001ff73c04030e2b9ad05406849a0 GIT binary patch literal 2533 zcmY+^byO3K8U}E-u`ytDC@Ecvj?U3BO8h{&MM_{GT@rI5&4w@mnKD8?1PKAZ$v`PZ zM=B*MF-kr{7}63K&$;)0_x|yo_nhZB=lSyoM>A4^01zC_SOsB}OGT#cu>cqVrD(=N zdNgDHS&W6F=}rHsAf;$}^|MGB2%tNA^8YjdxFCe--wQAR1kOqiO-#}Ck&VG8))Pn#Bz(?eKUb&Nha~qzhIBNt+>-sRp}puUUj#DoLPg6w z$9*AC!tg2TJfxqEIXVx~GaMElN9g{ra85qK81%a+3LuH^W@IJ{vv$qf9~KIzHGOXk9|N@8wv2Gj^q}-M#VL zUOsguE;bXJ2Ev6JwLD3Q@wpQ%wDtWotFDN-K(N*Ql3a5X%`i<(MZayaR$BwL? zP-YMX$uU!_t?GHzjc(E~uKRlG@E5T@gXVmdvyV2zLOd3VKbebhsziQpt4yv(Ay_+_ z-Dl{a#F5RF<|%cng&owG#p~I6<-ckow-* zfRA>4MKD7e54m-VCK$^#?cB)V0^y#&QF~{#kM#c9j**Vvg#y>e-F2o6Cx>mlY2e$P zD;ZqJy?gbf5Cii+BT-IY&l@{wVbc`{dfwvITFfTcnCLiYA}Z_S&c(0I^HUUnP*o0h z%1P6+_;)H(=J(7m2VYqT6dF<0KdLeeNWHadhsgL0JvZOHq#;*UtU2*w9d2c{PY`Z# z7q^Ja=rfUF4d1aO<9{5tGjpZSio2}OL)f{ejb@<#924H8(TT8|t zs9d$Uy5GsrP;wns1l6_dh3zPOT~lIf$Vs<(L^Q~aeoj5ml4N4QQC}|u+fdg9tAwHui@^(PC58#pg&qswvlnG!Li*Fl2Qe}&tmRR=tVCS z2ekssWW!+wefY;9FMRH;OJAZ!-Z;weSg6;Of6NKOOiMz&)8vCScoAv5$42#FLj2u7U~eUEhcns#iO&vmQ>xK< zHUJT9WdP9Lvw#gV!6b^r)(1~p?`Mv=+U`e^u_4WluUurgJDD=YJmN)DJp>@{ru!%b zW68!oxh`{DB5H)Lk)ST(Wb&tBQOwgg1a%vl{Fk(rZ^BHF;Ca1aI2x?~KVX!i!HV=~ z@a3~u?(C!>%>Uto2>?8E=EoT@EB~ho=(j4;wT&bvZ`iBfs?ek9-@hnW3mJ+=HVZC` z>UY)UJ={AQ96c19+GLz00Qjh8H;3S40!Lp6Wp*-<4st_|I5uB5U~gLROF;3J{~fB< z)G)&NHjRbX;I2yG^E|$cp#{FKT3zEJ$@OVLLL3x{^?JbJ@aSlOM4S&2&Y{RIHMQ5X zjDKNwHUm>=*?TbN(?lfu1-4+!|Wwa(9+)xEu zajP`HP(IQouchNTcME4f)L)UZiYdNc=PD0FVyFgO2%=;n8H0U)sA8#uwOI=tU54Jk z+k0g=!7dg)o>8c{`*?xbUMz70%;6rMfMapq-&m2k7YvwDR&8Ha`P?q36&}f#aQN4F zARR`9q6p$!OlA5&D9ylWCXYKHaM{%oEZGeu8^H*HednNX{9!rn2X+9qpqf!NmC zx-q|M>D55C3{LNy^69Jmo&NEwNTTg_m4q%?2Hs^YPZhT|bGL3zbLavO$ee>Gxr*Rp zU6x7*Xe)CdqJFfWqJ3D5Es# zM0|`OaIdby3s+4vT%|Sq@b8n)aHXiiudw1{Y%O9DZ^)>B5|7wV%#CW$BBL zfP_AJO#yFF+zMP1VvU&`=v)ZXO?=ZP$Z`5(GME=LO9)DIi5T_n&TL+h+U)XQ20g_+ zJY_Pmb7?wdi7Kt!m^1MtXD@%3uE^+=nGG|zKr-g11cdj2s>3NXTUUmJJZS^las!ij zEYzbmoxKK{e|HvzihU9ssMFUpPiT3bbx%{nY3M=SPHBR2tzD(AehdEQ{$ISGPlAtp zY5LWiWrxVM0{SNfXlbm~hss+EweiUN4JIVbmrUm?pUx3IH+7Q|`ZD`|nR)n+&6wnm zg*26s6uA7fab$Ptz#`DtQD5-R9nLRC_+0A+cD1b{Y63emkiqSmS9~g+7A307aXM10 z<%$u#@I$e5L2gI9hjPsn(+HU18p$q#JH5=vEnVmGv8%cNNpMRoPbL`lvqDwc4#F^G z<9Ae*G+xd9Qe7%l{F@^GjJsckttA1q73}(}!ZtkwyAw2W$bxZNE_glxt0n)@O*>#6 zsBiU`$;G5-^C(Ed#s8}#BaZ?vJvU!zk?rBuCz2C$1)VjyhTOMR@ENWE7lkuIz!zCT qKz=YCJ@+QG$EQu(N&pRTtMA>#eKmjz#n3~YrzrDW%~|ummHZb7Y^aO? literal 0 HcmV?d00001 diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java index b11080af73e..fc8f1dbfe83 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java @@ -53,7 +53,7 @@ import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; public abstract class AbstractHandshaker implements Handshaker { - protected static final Logger LOG = Log.getLogger(RFC8441Handshaker.class); + protected static final Logger LOG = Log.getLogger(AbstractHandshaker.class); private static final HttpField SERVER_VERSION = new PreEncodedHttpField(HttpHeader.SERVER, HttpConfiguration.SERVER_VERSION); @Override @@ -98,7 +98,6 @@ public abstract class AbstractHandshaker implements Handshaker return false; } - // Validate negotiated protocol String protocol = negotiation.getSubprotocol(); List offeredProtocols = negotiation.getOfferedSubprotocols(); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java index f5398e0e491..7053def75d9 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java @@ -66,7 +66,7 @@ public final class RFC6455Handshaker extends AbstractHandshaker @Override protected Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents) { - return new RFC6544Negotiation(Request.getBaseRequest(request), request, response, webSocketComponents); + return new RFC6455Negotiation(Request.getBaseRequest(request), request, response, webSocketComponents); } @Override @@ -75,7 +75,7 @@ public final class RFC6455Handshaker extends AbstractHandshaker boolean result = super.validateNegotiation(negotiation); if (!result) return false; - if (((RFC6544Negotiation)negotiation).getKey() == null) + if (((RFC6455Negotiation)negotiation).getKey() == null) throw new BadMessageException("Missing request header 'Sec-WebSocket-Key'"); return true; } @@ -95,6 +95,6 @@ public final class RFC6455Handshaker extends AbstractHandshaker HttpFields responseFields = response.getHttpFields(); responseFields.put(UPGRADE_WEBSOCKET); responseFields.put(CONNECTION_UPGRADE); - responseFields.put(HttpHeader.SEC_WEBSOCKET_ACCEPT, WebSocketCore.hashKey(((RFC6544Negotiation)negotiation).getKey())); + responseFields.put(HttpHeader.SEC_WEBSOCKET_ACCEPT, WebSocketCore.hashKey(((RFC6455Negotiation)negotiation).getKey())); } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6544Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java similarity index 96% rename from jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6544Negotiation.java rename to jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java index f836c9b7986..1703787ab75 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6544Negotiation.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java @@ -29,12 +29,12 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.server.Negotiation; -public class RFC6544Negotiation extends Negotiation +public class RFC6455Negotiation extends Negotiation { private boolean successful; private String key; - public RFC6544Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents components) throws BadMessageException + public RFC6455Negotiation(Request baseRequest, HttpServletRequest request, HttpServletResponse response, WebSocketComponents components) throws BadMessageException { super(baseRequest, request, response, components); } From c6ec9fb4d2a92b7317d0f022c9ec23be88e9f029 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Sat, 16 Nov 2019 19:56:00 +0100 Subject: [PATCH 10/77] Fixed handling of DATA frames arriving _before_ the upgrade. Now CONNECT with :protocol requests will demand DATA frames only after the upgrade. Other requests will demand DATA frames during the handling of the request HEADERS frame. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/client/HttpClient.java | 2 +- .../dynamic/HttpClientTransportDynamic.java | 4 +- .../org/eclipse/jetty/http2/HTTP2Stream.java | 6 +- .../server/HTTP2ServerConnectionFactory.java | 9 ++ .../http2/server/HttpChannelOverHTTP2.java | 8 +- .../http2/server/HttpTransportOverHTTP2.java | 7 +- .../tests/WebSocketOverHTTP2Test.java | 117 +++++++++++++----- 7 files changed, 113 insertions(+), 40 deletions(-) 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 1680193d1b7..147c4b402c5 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 @@ -1101,7 +1101,7 @@ public class HttpClient extends ContainerLifeCycle return port == 80; } - static boolean isSchemeSecure(String scheme) + public static boolean isSchemeSecure(String scheme) { return HttpScheme.HTTPS.is(scheme) || HttpScheme.WSS.is(scheme); } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java b/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java index 4deca44721f..9e2bcd7e821 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/dynamic/HttpClientTransportDynamic.java @@ -29,6 +29,7 @@ import java.util.stream.Collectors; import org.eclipse.jetty.alpn.client.ALPNClientConnection; import org.eclipse.jetty.alpn.client.ALPNClientConnectionFactory; import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport; +import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpClientTransport; import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.HttpRequest; @@ -36,7 +37,6 @@ import org.eclipse.jetty.client.MultiplexConnectionPool; import org.eclipse.jetty.client.MultiplexHttpDestination; import org.eclipse.jetty.client.Origin; import org.eclipse.jetty.client.http.HttpClientConnectionFactory; -import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.ClientConnector; @@ -121,7 +121,7 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans @Override public HttpDestination.Key newDestinationKey(HttpRequest request, Origin origin) { - boolean ssl = HttpScheme.HTTPS.is(request.getScheme()); + boolean ssl = HttpClient.isSchemeSecure(request.getScheme()); String http1 = "http/1.1"; String http2 = ssl ? "h2" : "h2c"; List protocols = List.of(); diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java index 9209243c75d..691bb28c14d 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java @@ -372,16 +372,18 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa dataProcess = proceed = dataDemand > 0; } } - if (LOG.isDebugEnabled()) - LOG.debug("{} data processing of {} for {}", initial ? "Starting" : proceed ? "Proceeding" : "Stalling", frame, this); if (initial) { + if (LOG.isDebugEnabled()) + LOG.debug("Starting data processing of {} for {}", frame, this); notifyBeforeData(this); try (AutoLock l = lock.lock()) { dataProcess = proceed = dataDemand > 0; } } + if (LOG.isDebugEnabled()) + LOG.debug("{} data processing of {} for {}", proceed ? "Proceeding" : "Stalling", frame, this); if (proceed) processData(); } diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java index 7e45753e5c0..3273c8bd19c 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java @@ -102,6 +102,15 @@ public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionF return this; } + @Override + public void onBeforeData(Stream stream) + { + // Do not notify DATA frame listeners until demanded. + // This allows CONNECT requests with pseudo header :protocol + // (e.g. WebSocket over HTTP/2) to buffer DATA frames + // until they upgrade and are ready to process them. + } + @Override public boolean onIdleTimeout(Session session) { diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java index 93ca8fd6626..6abe0d8ff3c 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java @@ -29,7 +29,6 @@ import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpGenerator; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; -import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.PreEncodedHttpField; @@ -140,8 +139,13 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ onRequestComplete(); } + boolean connect = request instanceof MetaData.ConnectRequest; _delayedUntilContent = getHttpConfiguration().isDelayDispatchUntilContent() && - !endStream && !_expect100Continue && !HttpMethod.CONNECT.is(request.getMethod()); + !endStream && !_expect100Continue && !connect; + + // Delay the demand of DATA frames for CONNECT with :protocol. + if (!connect || request.getProtocol() == null) + getStream().demand(1); if (LOG.isDebugEnabled()) { diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java index 4cb11d8bb1b..f92c9023c9c 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java @@ -318,12 +318,15 @@ public class HttpTransportOverHTTP2 implements HttpTransport { HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); Request request = channel.getRequest(); + if (request.getHttpInput().hasContent()) + return channel.sendErrorOrAbort("Unexpected content in CONNECT request"); Connection connection = (Connection)request.getAttribute(UPGRADE_CONNECTION_ATTRIBUTE); EndPoint endPoint = connection.getEndPoint(); endPoint.upgrade(connection); stream.setAttachment(endPoint); - if (request.getHttpInput().hasContent()) - return channel.sendErrorOrAbort("Unexpected content in CONNECT request"); + // Only now that we have switched the attachment, + // we can demand DATA frames to process them. + stream.demand(1); return false; } diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java index 84ae11d94d4..37db5c9c88a 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java @@ -18,10 +18,15 @@ package org.eclipse.jetty.websocket.tests; +import java.io.IOException; +import java.io.InterruptedIOException; import java.net.URI; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.function.Function; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; import org.eclipse.jetty.client.HttpClient; @@ -54,7 +59,6 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -69,9 +73,14 @@ public class WebSocketOverHTTP2Test private Server server; private ServerConnector connector; private ServerConnector tlsConnector; + private WebSocketClient wsClient; - @BeforeEach - public void startServer() throws Exception + private void startServer() throws Exception + { + startServer(new TestJettyWebSocketServlet()); + } + + private void startServer(TestJettyWebSocketServlet servlet) throws Exception { QueuedThreadPool serverThreads = new QueuedThreadPool(); serverThreads.setName("server"); @@ -92,29 +101,37 @@ public class WebSocketOverHTTP2Test HttpConnectionFactory h1s = new HttpConnectionFactory(httpsConfig); HTTP2ServerConnectionFactory h2s = new HTTP2ServerConnectionFactory(httpsConfig); ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); - alpn.setDefaultProtocol(h1c.getProtocol()); + alpn.setDefaultProtocol(h1s.getProtocol()); SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol()); - tlsConnector = new ServerConnector(server, 1, 1, ssl, alpn, h2s, h1s); + tlsConnector = new ServerConnector(server, 1, 1, ssl, alpn, h1s, h2s); server.addConnector(tlsConnector); ServletContextHandler context = new ServletContextHandler(server, "/"); - context.addServlet(new ServletHolder(new JettyWebSocketServlet() - { - @Override - protected void configure(JettyWebSocketServletFactory factory) - { - factory.addMapping("/ws/echo", (req, resp) -> new EchoSocket()); - } - }), "/ws/*"); + context.addServlet(new ServletHolder(servlet), "/ws/*"); JettyWebSocketServletContainerInitializer.initialize(context); server.start(); } + private void startClient(Function protocolFn) throws Exception + { + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setSslContextFactory(new SslContextFactory.Client(true)); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + clientConnector.setExecutor(clientThreads); + HttpClient httpClient = new HttpClient(new HttpClientTransportDynamic(clientConnector, protocolFn.apply(clientConnector))); + wsClient = new WebSocketClient(httpClient); + wsClient.start(); + } + @AfterEach public void stopServer() throws Exception { - server.stop(); + if (server != null) + server.stop(); + if (wsClient != null) + wsClient.stop(); } @Test @@ -131,14 +148,8 @@ public class WebSocketOverHTTP2Test private void testWebSocketOverDynamicTransport(Function protocolFn) throws Exception { - ClientConnector clientConnector = new ClientConnector(); - QueuedThreadPool clientThreads = new QueuedThreadPool(); - clientThreads.setName("client"); - clientConnector.setExecutor(clientThreads); - HttpClient httpClient = new HttpClient(new HttpClientTransportDynamic(clientConnector, protocolFn.apply(clientConnector))); - - WebSocketClient wsClient = new WebSocketClient(httpClient); - wsClient.start(); + startServer(); + startClient(protocolFn); EventSocket wsEndPoint = new EventSocket(); URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/echo"); @@ -160,18 +171,11 @@ public class WebSocketOverHTTP2Test @Test public void testConnectProtocolDisabled() throws Exception { + startServer(); AbstractHTTP2ServerConnectionFactory h2c = connector.getBean(AbstractHTTP2ServerConnectionFactory.class); h2c.setConnectProtocolEnabled(false); - ClientConnector clientConnector = new ClientConnector(); - QueuedThreadPool clientThreads = new QueuedThreadPool(); - clientThreads.setName("client"); - clientConnector.setExecutor(clientThreads); - HTTP2Client http2Client = new HTTP2Client(clientConnector); - HttpClient httpClient = new HttpClient(new HttpClientTransportDynamic(clientConnector, new ClientConnectionFactoryOverHTTP2.H2C(http2Client))); - - WebSocketClient wsClient = new WebSocketClient(httpClient); - wsClient.start(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2C(new HTTP2Client(clientConnector))); EventSocket wsEndPoint = new EventSocket(); URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/echo"); @@ -182,4 +186,55 @@ public class WebSocketOverHTTP2Test Throwable cause = failure.getCause(); assertThat(cause.getMessage(), containsStringIgnoringCase(ErrorCode.PROTOCOL_ERROR.name())); } + + @Test + public void testSlowWebSocketUpgradeWithHTTP2DataFramesQueued() throws Exception + { + startServer(new TestJettyWebSocketServlet() + { + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + try + { + super.service(request, response); + // Flush the response to the client then wait before exiting + // this method so that the client can send HTTP/2 DATA frames + // that will be processed by the server while this method sleeps. + response.flushBuffer(); + Thread.sleep(1000); + } + catch (InterruptedException x) + { + throw new InterruptedIOException(); + } + } + }); + + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + // Connect and send immediately a message, so the message + // arrives to the server while the server is still upgrading. + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("wss://localhost:" + tlsConnector.getLocalPort() + "/ws/echo"); + Session session = wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS); + String text = "websocket"; + session.getRemote().sendString(text); + + String message = wsEndPoint.messageQueue.poll(5, TimeUnit.SECONDS); + assertNotNull(message); + assertEquals(text, message); + + session.close(StatusCode.NORMAL, null); + assertTrue(wsEndPoint.closeLatch.await(5, TimeUnit.SECONDS)); + } + + private static class TestJettyWebSocketServlet extends JettyWebSocketServlet + { + @Override + protected void configure(JettyWebSocketServletFactory factory) + { + factory.addMapping("/ws/echo", (request, response) -> new EchoSocket()); + } + } } From 79a017d3baf5bc276cbe552d845774b67693896d Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Mon, 18 Nov 2019 14:29:18 +1100 Subject: [PATCH 11/77] notify handshake listener after request headers are set Signed-off-by: Lachlan Roberts --- .../eclipse/jetty/http2/server/HttpTransportOverHTTP2.java | 4 ++++ .../jetty/websocket/core/client/ClientUpgradeRequest.java | 3 +-- .../jetty/websocket/core/client/HttpUpgraderOverHTTP.java | 4 ++++ .../jetty/websocket/core/client/HttpUpgraderOverHTTP2.java | 3 +++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java index f92c9023c9c..82a9e4f78a1 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java @@ -327,6 +327,10 @@ public class HttpTransportOverHTTP2 implements HttpTransport // Only now that we have switched the attachment, // we can demand DATA frames to process them. stream.demand(1); + + if (LOG.isDebugEnabled()) + LOG.debug("Upgrading to {}", connection); + return false; } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java index 9873f95334c..505b9ce5833 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java @@ -197,7 +197,6 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon throw new IllegalArgumentException("FrameHandler could not be created", t); } - initWebSocketHeaders(); super.send(listener); } @@ -295,7 +294,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon public abstract FrameHandler getFrameHandler(); - private void initWebSocketHeaders() + void requestComplete() { notifyUpgradeListeners((listener) -> listener.onHandshakeRequest(this)); } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java index 19775d420bb..2f2c147c8a3 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP.java @@ -51,12 +51,16 @@ public class HttpUpgraderOverHTTP implements HttpUpgrader request.header(HttpHeader.UPGRADE, "websocket"); request.header(HttpHeader.CONNECTION, "Upgrade"); request.header(HttpHeader.SEC_WEBSOCKET_KEY, generateRandomKey()); + // Per the hybi list: Add no-cache headers to avoid compatibility issue. // There are some proxies that rewrite "Connection: upgrade" to // "Connection: close" in the response if a request doesn't contain // these headers. request.header(HttpHeader.PRAGMA, "no-cache"); request.header(HttpHeader.CACHE_CONTROL, "no-cache"); + + // Notify the UpgradeListeners now the headers are set. + clientUpgradeRequest.requestComplete(); } private String generateRandomKey() diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java index 6d7ae2c4015..6df466acd9a 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/HttpUpgraderOverHTTP2.java @@ -41,6 +41,9 @@ public class HttpUpgraderOverHTTP2 implements HttpUpgrader request.method(HttpMethod.CONNECT); request.upgradeProtocol("websocket"); request.header(HttpHeader.SEC_WEBSOCKET_VERSION, WebSocketConstants.SPEC_VERSION_STRING); + + // Notify the UpgradeListeners now the headers are set. + clientUpgradeRequest.requestComplete(); } @Override From afc3aed5d32b6a838b13ca134984901a6e1586cd Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Mon, 18 Nov 2019 17:21:15 +1100 Subject: [PATCH 12/77] return 503 if null FrameHandler in 8441 and add new tests Signed-off-by: Lachlan Roberts --- .../tests/WebSocketOverHTTP2Test.java | 80 ++++++++++++++++++- .../websocket/core/server/Negotiation.java | 2 +- .../server/internal/AbstractHandshaker.java | 10 +-- .../server/internal/RFC6455Handshaker.java | 14 ++++ .../server/internal/RFC6455Negotiation.java | 2 +- .../server/internal/RFC8441Handshaker.java | 15 ++++ .../server/internal/RFC8441Negotiation.java | 2 +- 7 files changed, 115 insertions(+), 10 deletions(-) diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java index 37db5c9c88a..f028132af0a 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.tests; import java.io.IOException; import java.io.InterruptedIOException; +import java.net.ConnectException; import java.net.URI; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -41,6 +42,7 @@ import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.SecureRequestCustomizer; @@ -49,10 +51,12 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.SslConnectionFactory; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.UpgradeException; import org.eclipse.jetty.websocket.client.WebSocketClient; import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; @@ -63,6 +67,7 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsStringIgnoringCase; +import static org.hamcrest.Matchers.instanceOf; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -108,7 +113,7 @@ public class WebSocketOverHTTP2Test ServletContextHandler context = new ServletContextHandler(server, "/"); context.addServlet(new ServletHolder(servlet), "/ws/*"); - JettyWebSocketServletContainerInitializer.initialize(context); + JettyWebSocketServletContainerInitializer.configure(context, null); server.start(); } @@ -229,12 +234,85 @@ public class WebSocketOverHTTP2Test assertTrue(wsEndPoint.closeLatch.await(5, TimeUnit.SECONDS)); } + @Test void testWebSocketConnectPortDoesNotExist() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + (connector.getLocalPort()+1) + "/ws/echo"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(ConnectException.class)); + assertThat(cause.getMessage(), containsStringIgnoringCase("Connection refused")); + } + + @Test void testWebSocketNotFound() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/nothing"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(UpgradeException.class)); + assertThat(cause.getMessage(), containsStringIgnoringCase("Unexpected HTTP Response Status Code: 501")); + } + + @Test void testNotNegotiated() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/null"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(UpgradeException.class)); + assertThat(cause.getMessage(), containsStringIgnoringCase("Unexpected HTTP Response Status Code: 503")); + } + + @Test void testThrowFromCreator() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/throw"); + + ExecutionException failure; + try (StacklessLogging stacklessLogging = new StacklessLogging(HttpChannel.class)) + { + failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + } + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(UpgradeException.class)); + assertThat(cause.getMessage(), containsStringIgnoringCase("Unexpected HTTP Response Status Code: 500")); + } + private static class TestJettyWebSocketServlet extends JettyWebSocketServlet { @Override protected void configure(JettyWebSocketServletFactory factory) { factory.addMapping("/ws/echo", (request, response) -> new EchoSocket()); + factory.addMapping("/ws/null", (request, response) -> null); + factory.addMapping("/ws/throw", (request, response) -> + { + throw new RuntimeException("throwing from creator"); + }); } } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java index 5ad5283d924..6187c99e358 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/Negotiation.java @@ -140,7 +140,7 @@ public abstract class Negotiation } } - public abstract boolean isSuccessful(); + public abstract boolean validateHeaders(); public String getVersion() { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java index fc8f1dbfe83..0eff2f5e3c4 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java @@ -72,12 +72,8 @@ public abstract class AbstractHandshaker implements Handshaker // Negotiate the FrameHandler FrameHandler handler = negotiator.negotiate(negotiation); - if (handler == null) - { - if (LOG.isDebugEnabled()) - LOG.debug("not upgraded: no frame handler provided {}", request); + if (!validateFrameHandler(handler, response)) return false; - } // Handle error responses Request baseRequest = negotiation.getBaseRequest(); @@ -175,9 +171,11 @@ public abstract class AbstractHandshaker implements Handshaker protected abstract Negotiation newNegotiation(HttpServletRequest request, HttpServletResponse response, WebSocketComponents webSocketComponents); + protected abstract boolean validateFrameHandler(FrameHandler frameHandler, HttpServletResponse response); + protected boolean validateNegotiation(Negotiation negotiation) { - if (!negotiation.isSuccessful()) + if (!negotiation.validateHeaders()) { if (LOG.isDebugEnabled()) LOG.debug("not upgraded: no upgrade header or connection upgrade", negotiation.getBaseRequest()); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java index 7053def75d9..4815e04f87c 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java @@ -32,6 +32,7 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; import org.eclipse.jetty.websocket.core.internal.WebSocketCore; @@ -80,6 +81,19 @@ public final class RFC6455Handshaker extends AbstractHandshaker return true; } + @Override + protected boolean validateFrameHandler(FrameHandler frameHandler, HttpServletResponse response) + { + if (frameHandler == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no frame handler provided"); + return false; + } + + return true; + } + @Override protected WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession) { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java index 1703787ab75..745a67c2760 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java @@ -78,7 +78,7 @@ public class RFC6455Negotiation extends Negotiation } @Override - public boolean isSuccessful() + public boolean validateHeaders() { return successful; } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java index ae9c19364c1..378fe50eadc 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java @@ -29,6 +29,7 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; import org.eclipse.jetty.websocket.core.internal.WebSocketConnection; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; @@ -62,6 +63,20 @@ public class RFC8441Handshaker extends AbstractHandshaker return new RFC8441Negotiation(Request.getBaseRequest(request), request, response, webSocketComponents); } + @Override + protected boolean validateFrameHandler(FrameHandler frameHandler, HttpServletResponse response) + { + if (frameHandler == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("not upgraded: no frame handler provided"); + + response.setStatus(HttpStatus.SERVICE_UNAVAILABLE_503); + } + + return true; + } + @Override protected WebSocketConnection createWebSocketConnection(Request baseRequest, WebSocketCoreSession coreSession) { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java index eaee84d6437..d0e0452b087 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java @@ -35,7 +35,7 @@ public class RFC8441Negotiation extends Negotiation } @Override - public boolean isSuccessful() + public boolean validateHeaders() { MetaData.Request metaData = getBaseRequest().getMetaData(); if (metaData == null) From 738de7bb022a83ab79ae4b86684ec4e397b3e71d Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Mon, 18 Nov 2019 19:16:01 +1100 Subject: [PATCH 13/77] Issue #4315 - stop WebSocketSessions only after onClose Signed-off-by: Lachlan Roberts --- .../websocket/common/SessionTracker.java | 5 +++- .../websocket/common/WebSocketSession.java | 21 --------------- ...erStopTest.java => WebSocketStopTest.java} | 27 ++++++++++++++++--- .../core/internal/WebSocketCoreSession.java | 4 +-- 4 files changed, 29 insertions(+), 28 deletions(-) rename jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/{WriteAfterStopTest.java => WebSocketStopTest.java} (78%) diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java index 4bcbbb0a26f..554667c3c1f 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java +++ b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java @@ -25,6 +25,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketSessionListener; public class SessionTracker extends AbstractLifeCycle implements WebSocketSessionListener @@ -55,8 +56,10 @@ public class SessionTracker extends AbstractLifeCycle implements WebSocketSessio { for (Session session : sessions) { - LifeCycle.stop(session); + // SHUTDOWN is abnormal close status so it will hard close connection after sent. + session.close(StatusCode.SHUTDOWN, "Container being shut down"); } + super.doStop(); } } diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java index 80a5fcc2493..1f08a22542a 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java +++ b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java @@ -23,14 +23,12 @@ import java.net.SocketAddress; import java.time.Duration; import java.util.Objects; -import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.component.AbstractLifeCycle; 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.websocket.api.CloseStatus; import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.SuspendToken; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; @@ -243,25 +241,6 @@ public class WebSocketSession extends AbstractLifeCycle implements Session, Susp return coreSession; } - @Override - protected void doStop() throws Exception - { - coreSession.close(StatusCode.SHUTDOWN, "Container being shut down", new Callback() - { - @Override - public void succeeded() - { - coreSession.abort(); - } - - @Override - public void failed(Throwable x) - { - coreSession.abort(); - } - }); - } - @Override public void dump(Appendable out, String indent) throws IOException { diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WriteAfterStopTest.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStopTest.java similarity index 78% rename from jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WriteAfterStopTest.java rename to jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStopTest.java index 30a7b37431d..5ecc1702044 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WriteAfterStopTest.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStopTest.java @@ -38,12 +38,12 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -public class WriteAfterStopTest +public class WebSocketStopTest { - public class UpgradeServlet extends JettyWebSocketServlet { @Override @@ -83,7 +83,28 @@ public class WriteAfterStopTest } @Test - public void test() throws Exception + public void stopWithOpenSessions() throws Exception + { + final URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); + + // Connect to two sessions to the server. + EventSocket clientSocket1 = new EventSocket(); + EventSocket clientSocket2 = new EventSocket(); + assertNotNull(client.connect(clientSocket1, uri).get(5, TimeUnit.SECONDS)); + assertNotNull(client.connect(clientSocket2, uri).get(5, TimeUnit.SECONDS)); + assertTrue(clientSocket1.openLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket2.openLatch.await(5, TimeUnit.SECONDS)); + + // WS client is stopped and closes sessions with SHUTDOWN code. + client.stop(); + assertTrue(clientSocket1.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(clientSocket2.closeLatch.await(5, TimeUnit.SECONDS)); + assertThat(clientSocket1.statusCode, is(StatusCode.SHUTDOWN)); + assertThat(clientSocket2.statusCode, is(StatusCode.SHUTDOWN)); + } + + @Test + public void testWriteAfterStop() throws Exception { URI uri = new URI("ws://localhost:" + connector.getLocalPort() + "/"); EventSocket clientSocket = new EventSocket(); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java index 6f84f84c330..c42ca57039b 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java @@ -311,9 +311,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe if (LOG.isDebugEnabled()) LOG.debug("closeConnection() {} {} {}", closeStatus, this); - connection.cancelDemand(); - if (connection.getEndPoint().isOpen()) - connection.close(); + abort(); // Forward Errors to Local WebSocket EndPoint if (closeStatus.isAbnormal() && closeStatus.getCause() != null) From 4d1031899e34157d6f247c72700648f6430e7272 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 19 Nov 2019 14:17:56 -0600 Subject: [PATCH 14/77] Issue #4329 - New testcase for demo-base /test/session/ Signed-off-by: Joakim Erdfelt --- .../tests/distribution/DemoBaseTests.java | 40 +++++++++++++++++++ .../src/main/java/com/acme/SessionDump.java | 1 + 2 files changed, 41 insertions(+) diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java index a4f06e74c49..d53aa03a43e 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java @@ -22,7 +22,10 @@ import java.nio.file.Paths; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.util.FormContentProvider; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.util.Fields; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnJre; import org.junit.jupiter.api.condition.JRE; @@ -32,6 +35,7 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; public class DemoBaseTests extends AbstractDistributionTest @@ -173,4 +177,40 @@ public class DemoBaseTests extends AbstractDistributionTest assertEquals(HttpStatus.OK_200, response.getStatus()); } } + + @Test + public void testSessionDump() throws Exception + { + String jettyVersion = System.getProperty("jettyVersion"); + DistributionTester distribution = DistributionTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .jettyBase(Paths.get("demo-base")) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + + int httpPort = distribution.freePort(); + int httpsPort = distribution.freePort(); + String[] args = { + "jetty.http.port=" + httpPort, + "jetty.httpConfig.port=" + httpsPort, + "jetty.ssl.port=" + httpsPort + }; + try (DistributionTester.Run run = distribution.start(args)) + { + assertTrue(run.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + + startHttpClient(); + ContentResponse response = client.GET("http://localhost:" + httpPort + "/test/session/"); + assertEquals(HttpStatus.OK_200, response.getStatus()); + + Fields action = new Fields(); + action.add("Action", "New Session"); + response = client.POST("http://localhost:" + httpPort + "/test/session/") + .content(new FormContentProvider(action)) + .send(); + assertEquals(HttpStatus.FOUND_302, response.getStatus()); + String location = response.getHeaders().get(HttpHeader.LOCATION); + assertNotNull(location); + } + } } diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java index cf36c029411..8cc74ab0d60 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java @@ -124,6 +124,7 @@ public class SessionDump extends HttpServlet } catch (IllegalStateException e) { + e.printStackTrace(System.err); session = null; } From 9e40fc9a6fbe93850233b7f03f048b1272530942 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 20 Nov 2019 09:47:33 -0600 Subject: [PATCH 15/77] Issue #4334 - Improve testing of ErrorHandler behavior Signed-off-by: Joakim Erdfelt --- .../jetty/server/handler/ErrorHandler.java | 19 +- .../jetty/server/ErrorHandlerTest.java | 340 ++++++++++++++---- 2 files changed, 283 insertions(+), 76 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java index 4cc5389b1b2..ed044c333fd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java @@ -21,6 +21,7 @@ package org.eclipse.jetty.server.handler; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; +import java.io.StringWriter; import java.io.Writer; import java.nio.BufferOverflowException; import java.nio.ByteBuffer; @@ -491,16 +492,18 @@ public class ErrorHandler extends AbstractHandler throws IOException { Throwable th = (Throwable)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); - if (_showStacks && th != null) + while (th != null) { - PrintWriter pw = writer instanceof PrintWriter ? (PrintWriter)writer : new PrintWriter(writer); - pw.write("

");
-            while (th != null)
-            {
-                th.printStackTrace(pw);
-                th = th.getCause();
-            }
+            writer.write("

Caused by:

");
+            // You have to pre-generate and then use #write(writer, String)
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            th.printStackTrace(pw);
+            pw.flush();
+            write(writer, sw.getBuffer().toString()); // IMPORTANT STEP
             writer.write("
\n"); + + th = th.getCause(); } } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java index dcc30b1ff72..97a7f736b40 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java @@ -20,7 +20,6 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.util.Map; - import javax.servlet.DispatcherType; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; @@ -28,7 +27,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.BadMessageException; -import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.handler.AbstractHandler; @@ -36,13 +34,16 @@ import org.eclipse.jetty.util.ajax.JSON; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.Matchers.nullValue; public class ErrorHandlerTest { @@ -79,7 +80,43 @@ public class ErrorHandlerTest if (target.startsWith("/badmessage/")) { - throw new ServletException(new BadMessageException(Integer.valueOf(target.substring(12)))); + int code = Integer.valueOf(target.substring(target.lastIndexOf('/') + 1)); + throw new ServletException(new BadMessageException(code)); + } + + // produce an exception with an JSON formatted cause message + if (target.startsWith("/jsonmessage/")) + { + StringBuilder message = new StringBuilder(); + message.append("{\n \"glossary\": {\n \"title\": \"example\"\n }\n }"); + throw new ServletException(new RuntimeException(message.toString())); + } + + // produce an exception with an XML cause message + if (target.startsWith("/xmlmessage/")) + { + StringBuilder message = new StringBuilder(); + message.append("\n"); + message.append(" \n"); + message.append(" example glossary\n"); + message.append(" "); + throw new ServletException(new RuntimeException(message.toString())); + } + + // produce an exception with an HTML cause message + if (target.startsWith("/htmlmessage/")) + { + StringBuilder message = new StringBuilder(); + message.append("
"); + throw new ServletException(new RuntimeException(message.toString())); + } + + // produce an exception with a UTF-8 cause message + if (target.startsWith("/utf8message/")) + { + StringBuilder message = new StringBuilder(); + message.append("Euro is € and \u20AC and %E2%82%AC"); + throw new ServletException(new RuntimeException(message.toString())); } } }); @@ -95,188 +132,232 @@ public class ErrorHandlerTest @Test public void test404NoAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void test404EmptyAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Accept: \r\n" + "Host: Localhost\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, containsString("Content-Length: 0")); - assertThat(response, not(containsString("Content-Type"))); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), is(0)); + assertThat("Response Content-Type", response.getField(HttpHeader.CONTENT_TYPE), is(nullValue())); } @Test public void test404UnAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Accept: text/*;q=0\r\n" + "Host: Localhost\r\n" + "\r\n"); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, containsString("Content-Length: 0")); - assertThat(response, not(containsString("Content-Type"))); + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), is(0)); + assertThat("Response Content-Type", response.getField(HttpHeader.CONTENT_TYPE), is(nullValue())); } @Test public void test404AllAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: */*\r\n" + "\r\n"); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void test404HtmlAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void testMoreSpecificAccept() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html, some/other;specific=true\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void test404HtmlAcceptAnyCharset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: *\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=utf-8")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + assertContent(response); } @Test public void test404HtmlAcceptUtf8Charset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: utf-8\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=utf-8")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + assertContent(response); } @Test public void test404HtmlAcceptNotUtf8Charset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: utf-8;q=0\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=iso-8859-1")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); } @Test public void test404HtmlAcceptNotUtf8UnknownCharset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: utf-8;q=0,unknown\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, containsString("Content-Length: 0")); - assertThat(response, not(containsString("Content-Type"))); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), is(0)); + assertThat("Response Content-Type", response.getField(HttpHeader.CONTENT_TYPE), is(nullValue())); } @Test public void test404HtmlAcceptUnknownUtf8Charset() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html\r\n" + "Accept-Charset: utf-8;q=0.1,unknown\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=utf-8")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + assertContent(response); } @Test public void test404PreferHtml() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html;q=1.0,text/json;q=0.5,*/*\r\n" + "Accept-Charset: *\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/html;charset=utf-8")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + assertContent(response); } @Test public void test404PreferJson() throws Exception { - String response = connector.getResponse( + String rawResponse = connector.getResponse( "GET / HTTP/1.1\r\n" + "Host: Localhost\r\n" + "Accept: text/html;q=0.5,text/json;q=1.0,*/*\r\n" + "Accept-Charset: *\r\n" + "\r\n"); - assertThat(response, startsWith("HTTP/1.1 404 ")); - assertThat(response, not(containsString("Content-Length: 0"))); - assertThat(response, containsString("Content-Type: text/json")); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/json")); + + assertContent(response); } @Test @@ -287,12 +368,14 @@ public class ErrorHandlerTest "Host: Localhost\r\n" + "Accept: text/plain\r\n" + "\r\n"); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); assertThat("Response status code", response.getStatus(), is(404)); - HttpField contentType = response.getField(HttpHeader.CONTENT_TYPE); - assertThat("Response Content-Type", contentType, is(notNullValue())); - assertThat("Response Content-Type value", contentType.getValue(), not(containsString("null"))); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/plain")); + + assertContent(response); } @Test @@ -302,29 +385,150 @@ public class ErrorHandlerTest "GET /badmessage/444 HTTP/1.1\r\n" + "Host: Localhost\r\n" + "\r\n"); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); assertThat("Response status code", response.getStatus(), is(444)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + assertContent(response); + } + + @ParameterizedTest + @ValueSource(strings = { + "/jsonmessage/", + "/xmlmessage/", + "/htmlmessage/", + "/utf8message/", + }) + public void testComplexCauseMessageNoAcceptHeader(String path) throws Exception + { + String rawResponse = connector.getResponse( + "GET " + path + " HTTP/1.1\r\n" + + "Host: Localhost\r\n" + + "\r\n"); + + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(500)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=ISO-8859-1")); + + String content = assertContent(response); + + if (path.startsWith("/utf8")) + { + // we are Not expecting UTF-8 output, look for mangled ISO-8859-1 version + assertThat("content", content, containsString("Euro is &euro; and ? and %E2%82%AC")); + } + } + + @ParameterizedTest + @ValueSource(strings = { + "/jsonmessage/", + "/xmlmessage/", + "/htmlmessage/", + "/utf8message/", + }) + public void testComplexCauseMessageAcceptUtf8Header(String path) throws Exception + { + String rawResponse = connector.getResponse( + "GET " + path + " HTTP/1.1\r\n" + + "Host: Localhost\r\n" + + "Accept: text/html\r\n" + + "Accept-Charset: utf-8\r\n" + + "\r\n"); + + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(500)); + assertThat("Response Content-Length", response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0)); + assertThat("Response Content-Type", response.get(HttpHeader.CONTENT_TYPE), containsString("text/html;charset=UTF-8")); + + String content = assertContent(response); + + if (path.startsWith("/utf8")) + { + // we are Not expecting UTF-8 output, look for mangled ISO-8859-1 version + assertThat("content", content, containsString("Euro is &euro; and \u20AC and %E2%82%AC")); + } + } + + private String assertContent(HttpTester.Response response) + { + String contentType = response.get(HttpHeader.CONTENT_TYPE); + String content = response.getContent(); + + if (contentType.contains("text/html")) + { + assertThat(content, not(containsString(""); - throw new ServletException(new RuntimeException(message.toString())); + String message = "
%3Cscript%3E"; + throw new ServletException(new RuntimeException(message)); } // produce an exception with a UTF-8 cause message if (target.startsWith("/utf8message/")) { - StringBuilder message = new StringBuilder(); - message.append("Euro is € and \u20AC and %E2%82%AC"); - throw new ServletException(new RuntimeException(message.toString())); + String message = "Euro is € and \u20AC and %E2%82%AC"; + throw new ServletException(new RuntimeException(message)); } } }); @@ -127,6 +128,7 @@ public class ErrorHandlerTest public static void after() throws Exception { server.stop(); + stacklessLogging.close(); } @Test @@ -469,12 +471,16 @@ public class ErrorHandlerTest } else if (contentType.contains("text/json")) { - Map jo = (Map)JSON.parse(response.getContent()); + Map jo = (Map)JSON.parse(response.getContent()); assertThat("url field", jo.get("url"), is(notNullValue())); String expectedStatus = String.valueOf(response.getStatus()); assertThat("status field", jo.get("status"), is(expectedStatus)); - assertThat("message field", jo.get("message"), is(notNullValue())); + String message = (String)jo.get("message"); + assertThat("message field", message, is(notNullValue())); + assertThat("message field", message, anyOf( + not(containsString("<")), + not(containsString(">")))); } else if (contentType.contains("text/plain")) { @@ -528,7 +534,7 @@ public class ErrorHandlerTest if (path.startsWith("/utf8")) { // we are expecting UTF-8 output, look for it. - assertThat("content", content, containsString("Euro is € and \u20AC and %E2%82%AC")); + assertThat("content", content, containsString("Euro is &euro; and \u20AC and %E2%82%AC")); } } } From 09641c9581d82c43b8db94904c6a45fd1c2c4134 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 20 Nov 2019 14:09:44 -0600 Subject: [PATCH 20/77] Issue #4329 - Fixing RuleContainer to handle path parameters + Introducing HttpURI.setParam(String) + Updating DemoBaseTest.testSessionDump() to follow expected behavior Signed-off-by: Joakim Erdfelt --- .../java/org/eclipse/jetty/http/HttpURI.java | 9 +++++ .../jetty/rewrite/handler/RuleContainer.java | 15 ++++++++- .../handler/CookiePatternRuleTest.java | 4 --- .../tests/distribution/DemoBaseTests.java | 33 ++++++++++++++----- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java index 4fb2a36989e..e634eaca19a 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java @@ -573,6 +573,15 @@ public class HttpURI return _param; } + public void setParam(String param) + { + _param = param; + if (_path != null && !_path.contains(_param)) + { + _path += ";" + _param; + } + } + public String getQuery() { return _query; diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java index f04b7f3c1bd..11ea53e5bea 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java @@ -22,8 +22,10 @@ import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.ArrayUtil; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.log.Log; @@ -185,7 +187,18 @@ public class RuleContainer extends Rule implements Dumpable if (rule instanceof Rule.ApplyURI) ((Rule.ApplyURI)rule).applyURI(baseRequest, baseRequest.getRequestURI(), encoded); else - baseRequest.setURIPathQuery(encoded); + { + String uriPathQuery = encoded; + HttpURI baseUri = baseRequest.getHttpURI(); + // Copy path params from original URI if present + if ((baseUri != null) && StringUtil.isNotBlank(baseUri.getParam())) + { + HttpURI uri = new HttpURI(uriPathQuery); + uri.setParam(baseUri.getParam()); + uriPathQuery = uri.toString(); + } + baseRequest.setURIPathQuery(uriPathQuery); + } } if (_rewritePathInfo) diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java index e0c024fd173..0a4fdd03a7b 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java @@ -37,7 +37,6 @@ import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -48,7 +47,6 @@ import static org.junit.jupiter.api.Assertions.fail; public class CookiePatternRuleTest { - private Server server; private LocalConnector localConnector; @@ -150,7 +148,6 @@ public class CookiePatternRuleTest } @Test - @Disabled("See #2675 for details") // TODO: needs to be fixed in RuleContainer public void testUrlParameter() throws Exception { CookiePatternRule rule = new CookiePatternRule(); @@ -170,7 +167,6 @@ public class CookiePatternRuleTest HttpTester.Response response = HttpTester.parseResponse(rawResponse); String responseContent = response.getContent(); - System.out.println(responseContent); assertResponseContentLine(responseContent, "baseRequest.requestUri=", "/other;fruit=apple"); // verify diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java index d53aa03a43e..cc7c340d5e4 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java @@ -18,12 +18,12 @@ package org.eclipse.jetty.tests.distribution; +import java.net.URI; import java.nio.file.Paths; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.util.FormContentProvider; -import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.util.Fields; import org.junit.jupiter.api.Test; @@ -35,7 +35,6 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; public class DemoBaseTests extends AbstractDistributionTest @@ -200,17 +199,35 @@ public class DemoBaseTests extends AbstractDistributionTest assertTrue(run.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); startHttpClient(); + client.setFollowRedirects(true); ContentResponse response = client.GET("http://localhost:" + httpPort + "/test/session/"); assertEquals(HttpStatus.OK_200, response.getStatus()); - Fields action = new Fields(); - action.add("Action", "New Session"); + // Submit "New Session" + Fields form = new Fields(); + form.add("Action", "New Session"); response = client.POST("http://localhost:" + httpPort + "/test/session/") - .content(new FormContentProvider(action)) + .content(new FormContentProvider(form)) .send(); - assertEquals(HttpStatus.FOUND_302, response.getStatus()); - String location = response.getHeaders().get(HttpHeader.LOCATION); - assertNotNull(location); + assertEquals(HttpStatus.OK_200, response.getStatus()); + String content = response.getContentAsString(); + assertThat("Content", content, containsString("test: value
")); + assertThat("Content", content, containsString("WEBCL: {}
")); + + // Last Location + URI location = response.getRequest().getURI(); + + // Submit a "Set" for a new entry in the cookie + form = new Fields(); + form.add("Action", "Set"); + form.add("Name", "Zed"); + form.add("Value", "[alpha]"); + response = client.POST(location) + .content(new FormContentProvider(form)) + .send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); + content = response.getContentAsString(); + assertThat("Content", content, containsString("Zed: [alpha]
")); } } } From 363d5f2df3a8a28de40604320230664b9c793c16 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 20 Nov 2019 15:25:01 -0600 Subject: [PATCH 21/77] Updating to version 9.4.24.v20191120 --- VERSION.txt | 10 +- aggregates/jetty-all-compact3/pom.xml | 2 +- aggregates/jetty-all/pom.xml | 2 +- apache-jsp/pom.xml | 2 +- apache-jstl/pom.xml | 2 +- build-resources/pom.xml | 2 +- examples/async-rest/async-rest-jar/pom.xml | 2 +- examples/async-rest/async-rest-webapp/pom.xml | 2 +- examples/async-rest/pom.xml | 2 +- examples/embedded/pom.xml | 2 +- examples/pom.xml | 2 +- jetty-alpn/jetty-alpn-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-openjdk8-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-openjdk8-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-server/pom.xml | 2 +- jetty-alpn/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-ant/pom.xml | 2 +- jetty-bom/pom.xml | 134 +++++++++--------- jetty-cdi/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-continuation/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-documentation/pom.xml | 2 +- jetty-fcgi/fcgi-client/pom.xml | 2 +- jetty-fcgi/fcgi-server/pom.xml | 2 +- jetty-fcgi/pom.xml | 2 +- .../jetty-gcloud-session-manager/pom.xml | 2 +- jetty-gcloud/pom.xml | 2 +- jetty-hazelcast/pom.xml | 2 +- jetty-home/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-http2/http2-alpn-tests/pom.xml | 2 +- jetty-http2/http2-client/pom.xml | 2 +- jetty-http2/http2-common/pom.xml | 2 +- jetty-http2/http2-hpack/pom.xml | 2 +- .../http2-http-client-transport/pom.xml | 2 +- jetty-http2/http2-server/pom.xml | 2 +- jetty-http2/pom.xml | 2 +- jetty-infinispan/infinispan-common/pom.xml | 2 +- .../infinispan-embedded-query/pom.xml | 2 +- jetty-infinispan/infinispan-embedded/pom.xml | 2 +- .../infinispan-remote-query/pom.xml | 2 +- jetty-infinispan/infinispan-remote/pom.xml | 2 +- jetty-infinispan/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaas/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmh/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jspc-maven-plugin/pom.xml | 2 +- jetty-maven-plugin/pom.xml | 2 +- .../jetty-memcached-sessions/pom.xml | 2 +- jetty-memcached/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-openid/pom.xml | 2 +- jetty-osgi/jetty-osgi-alpn/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-context/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-fragment/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-server/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-webapp/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-proxy/pom.xml | 2 +- jetty-quickstart/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-runner/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spring/pom.xml | 2 +- jetty-start/pom.xml | 2 +- jetty-unixsocket/pom.xml | 2 +- jetty-util-ajax/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- .../javax-websocket-client-impl/pom.xml | 2 +- .../javax-websocket-server-impl/pom.xml | 2 +- jetty-websocket/jetty-websocket-tests/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-websocket/websocket-api/pom.xml | 2 +- jetty-websocket/websocket-client/pom.xml | 2 +- jetty-websocket/websocket-common/pom.xml | 2 +- jetty-websocket/websocket-server/pom.xml | 2 +- jetty-websocket/websocket-servlet/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-continuation/pom.xml | 2 +- tests/test-distribution/pom.xml | 2 +- tests/test-http-client-transport/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-jmx/jmx-webapp-it/pom.xml | 2 +- tests/test-jmx/jmx-webapp/pom.xml | 2 +- tests/test-jmx/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-quickstart/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- .../test-sessions/test-file-sessions/pom.xml | 2 +- .../test-gcloud-sessions/pom.xml | 2 +- .../test-hazelcast-sessions/pom.xml | 2 +- .../test-infinispan-sessions/pom.xml | 2 +- .../test-sessions/test-jdbc-sessions/pom.xml | 2 +- .../test-memcached-sessions/pom.xml | 2 +- .../test-mongodb-sessions/pom.xml | 2 +- .../test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- .../test-cdi-common-webapp/pom.xml | 2 +- tests/test-webapps/test-felix-webapp/pom.xml | 2 +- tests/test-webapps/test-http2-webapp/pom.xml | 2 +- tests/test-webapps/test-jaas-webapp/pom.xml | 2 +- tests/test-webapps/test-jetty-webapp/pom.xml | 2 +- tests/test-webapps/test-jndi-webapp/pom.xml | 2 +- .../test-webapps/test-mock-resources/pom.xml | 2 +- .../test-webapps/test-owb-cdi-webapp/pom.xml | 2 +- tests/test-webapps/test-proxy-webapp/pom.xml | 2 +- tests/test-webapps/test-servlet-spec/pom.xml | 2 +- .../test-container-initializer/pom.xml | 2 +- .../test-spec-webapp/pom.xml | 2 +- .../test-web-fragment/pom.xml | 2 +- tests/test-webapps/test-simple-webapp/pom.xml | 2 +- .../test-webapps/test-webapp-rfc2616/pom.xml | 2 +- .../test-webapps/test-weld-cdi-webapp/pom.xml | 2 +- 136 files changed, 208 insertions(+), 204 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 87c6d688468..7a468552f39 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,4 +1,8 @@ -jetty-9.4.24-SNAPSHOT +jetty-9.4.24.v20191120 - 20 November 2019 + + 3083 The ini-template for jetty.console-capture.dir does not match the + default value + + 4128 OpenIdCredetials can't decode JWT ID token + + 4334 Better test ErrorHandler changes jetty-9.4.23.v20191118 - 18 November 2019 + 1485 Add systemd service file @@ -13,7 +17,7 @@ jetty-9.4.23.v20191118 - 18 November 2019 URIUtil.equalsIgnoreEncodings() + 4138 OpenID module should use HttpClient instead of HttpURLConnection + 4156 IllegalStateException when forwarding to jsp with new session - + 4161 Regression: EofException: request lifecycle violation + + 4161 Regression: EofException: request lifecycle violation + 4173 NullPointerException warning in log from WebInfConfiguration after upgrade + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop @@ -30,7 +34,7 @@ jetty-9.4.23.v20191118 - 18 November 2019 + 4277 Reading streamed gzipped body never terminates + 4279 Regression: ResponseWriter#close blocks indefinitely + 4282 Review HttpParser handling in case of no content - + 4283 Wrong package for OpenJDK8ClientALPNProcessor + + 4283 Wrong package for OpenJDK8ClientALPNProcessor + 4284 Possible NullPointerException in Main.java when stopped from command line + 4287 Move getUriLastPathSegment(URI uri) to URIUtil diff --git a/aggregates/jetty-all-compact3/pom.xml b/aggregates/jetty-all-compact3/pom.xml index 444f9f0c1b1..1573b1e9f22 100644 --- a/aggregates/jetty-all-compact3/pom.xml +++ b/aggregates/jetty-all-compact3/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../../pom.xml 4.0.0 diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index 1889f5c91e3..9a6c1f5f0ad 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../../pom.xml 4.0.0 diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml index 8310c6d4e98..7150aa1d3ae 100644 --- a/apache-jsp/pom.xml +++ b/apache-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 apache-jsp diff --git a/apache-jstl/pom.xml b/apache-jstl/pom.xml index 3e5aa304a3c..ad1e8be6751 100644 --- a/apache-jstl/pom.xml +++ b/apache-jstl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 apache-jstl diff --git a/build-resources/pom.xml b/build-resources/pom.xml index 6bb007e4f53..130dda39218 100644 --- a/build-resources/pom.xml +++ b/build-resources/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.eclipse.jetty build-resources - 9.4.24-SNAPSHOT + 9.4.24.v20191120 jar Jetty :: Build Resources diff --git a/examples/async-rest/async-rest-jar/pom.xml b/examples/async-rest/async-rest-jar/pom.xml index 3e5d15a9b07..35b2f0b6204 100644 --- a/examples/async-rest/async-rest-jar/pom.xml +++ b/examples/async-rest/async-rest-jar/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/examples/async-rest/async-rest-webapp/pom.xml b/examples/async-rest/async-rest-webapp/pom.xml index 5646ed77ce9..2ca1872e69a 100644 --- a/examples/async-rest/async-rest-webapp/pom.xml +++ b/examples/async-rest/async-rest-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/examples/async-rest/pom.xml b/examples/async-rest/pom.xml index 1f6ad6db75f..fd08e0eaaca 100644 --- a/examples/async-rest/pom.xml +++ b/examples/async-rest/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml index 7c580955fc2..f36ca8d511f 100644 --- a/examples/embedded/pom.xml +++ b/examples/embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index 12254839a16..75531a33cd1 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-alpn/jetty-alpn-client/pom.xml b/jetty-alpn/jetty-alpn-client/pom.xml index ad89762ccbe..9ea7e663aee 100644 --- a/jetty-alpn/jetty-alpn-client/pom.xml +++ b/jetty-alpn/jetty-alpn-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-alpn-client diff --git a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml index dee462cc898..55da9916d95 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml index 458c4d5cd55..02d76affd18 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-client/pom.xml b/jetty-alpn/jetty-alpn-java-client/pom.xml index d8730fdba10..3a179216e6f 100644 --- a/jetty-alpn/jetty-alpn-java-client/pom.xml +++ b/jetty-alpn/jetty-alpn-java-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-server/pom.xml b/jetty-alpn/jetty-alpn-java-server/pom.xml index f747b2ce790..58e1b8ac057 100644 --- a/jetty-alpn/jetty-alpn-java-server/pom.xml +++ b/jetty-alpn/jetty-alpn-java-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml b/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml index d860a828b6d..4d28bc00639 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml +++ b/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml b/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml index 9fac60a839c..7488df48ec7 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml +++ b/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-alpn/jetty-alpn-server/pom.xml b/jetty-alpn/jetty-alpn-server/pom.xml index 05da2dd6694..1fc69ac9736 100644 --- a/jetty-alpn/jetty-alpn-server/pom.xml +++ b/jetty-alpn/jetty-alpn-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-alpn-server diff --git a/jetty-alpn/pom.xml b/jetty-alpn/pom.xml index 1cd6bad868e..9f270513cda 100644 --- a/jetty-alpn/pom.xml +++ b/jetty-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-alpn-parent diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 5d976518b22..0f08f5626bc 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-annotations diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml index d65f4ca6e28..4bcae7832fa 100644 --- a/jetty-ant/pom.xml +++ b/jetty-ant/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-ant diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index b2a2b17b95e..8eff5788bef 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -9,7 +9,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 @@ -53,336 +53,336 @@ org.eclipse.jetty apache-jsp - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty apache-jstl - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-alpn-client - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-alpn-java-client - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-alpn-java-server - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-alpn-openjdk8-client - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-alpn-openjdk8-server - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-alpn-conscrypt-client - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-alpn-conscrypt-server - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-alpn-server - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-annotations - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-ant - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-client - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-continuation - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-deploy - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-distribution - 9.4.24-SNAPSHOT + 9.4.24.v20191120 zip org.eclipse.jetty jetty-distribution - 9.4.24-SNAPSHOT + 9.4.24.v20191120 tar.gz org.eclipse.jetty.fcgi fcgi-client - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.fcgi fcgi-server - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.gcloud jetty-gcloud-session-manager - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-home - 9.4.24-SNAPSHOT + 9.4.24.v20191120 zip org.eclipse.jetty jetty-home - 9.4.24-SNAPSHOT + 9.4.24.v20191120 tar.gz org.eclipse.jetty jetty-http - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.http2 http2-client - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.http2 http2-common - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.http2 http2-hpack - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.http2 http2-http-client-transport - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.http2 http2-server - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-http-spi - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty infinispan-common - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty infinispan-remote-query - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty infinispan-embedded-query - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-hazelcast - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-io - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-jaas - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-jaspi - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-jmx - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-jndi - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.memcached jetty-memcached-sessions - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-nosql - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.osgi jetty-osgi-boot - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.osgi jetty-osgi-boot-jsp - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.osgi jetty-osgi-boot-warurl - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.osgi jetty-httpservice - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-plus - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-proxy - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-quickstart - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-rewrite - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-security - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-openid - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-server - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-servlet - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-servlets - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-spring - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-unixsocket - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-util - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-util-ajax - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-webapp - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.websocket javax-websocket-client-impl - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.websocket javax-websocket-server-impl - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.websocket websocket-api - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.websocket websocket-client - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.websocket websocket-common - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.websocket websocket-server - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty.websocket websocket-servlet - 9.4.24-SNAPSHOT + 9.4.24.v20191120 org.eclipse.jetty jetty-xml - 9.4.24-SNAPSHOT + 9.4.24.v20191120 diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index d045752ae0e..d2bfa9e42e2 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 org.eclipse.jetty diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index d142f82a643..63b58ff40f2 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml index ec47aadf595..55073849404 100644 --- a/jetty-continuation/pom.xml +++ b/jetty-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-continuation diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index 5073bd5679a..bf79939adbd 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-deploy diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index aa6eadc0dc4..038dff55fd5 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-distribution diff --git a/jetty-documentation/pom.xml b/jetty-documentation/pom.xml index 88e3e05f06a..9f90f964e56 100644 --- a/jetty-documentation/pom.xml +++ b/jetty-documentation/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 jetty-documentation Jetty :: Documentation diff --git a/jetty-fcgi/fcgi-client/pom.xml b/jetty-fcgi/fcgi-client/pom.xml index d98db618862..ac2a731018d 100644 --- a/jetty-fcgi/fcgi-client/pom.xml +++ b/jetty-fcgi/fcgi-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-fcgi/fcgi-server/pom.xml b/jetty-fcgi/fcgi-server/pom.xml index f08d4f7dd76..67743979684 100644 --- a/jetty-fcgi/fcgi-server/pom.xml +++ b/jetty-fcgi/fcgi-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-fcgi/pom.xml b/jetty-fcgi/pom.xml index 0d001cbb3e3..846c65ae46b 100644 --- a/jetty-fcgi/pom.xml +++ b/jetty-fcgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index 0f4bdffca12..13d9a4e710f 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-gcloud/pom.xml b/jetty-gcloud/pom.xml index 056a4f2e019..36fc59703c0 100644 --- a/jetty-gcloud/pom.xml +++ b/jetty-gcloud/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index 5bc1582f624..811c2722d08 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index 2478200d046..0919be7f11b 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-home diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index 9fad6844913..2622841ae1a 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index 8416966073a..bceebc7a553 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-http diff --git a/jetty-http2/http2-alpn-tests/pom.xml b/jetty-http2/http2-alpn-tests/pom.xml index 28dca75e221..62c7d0c1ef3 100644 --- a/jetty-http2/http2-alpn-tests/pom.xml +++ b/jetty-http2/http2-alpn-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-http2/http2-client/pom.xml b/jetty-http2/http2-client/pom.xml index 62cd39c53e7..4cce7cee19b 100644 --- a/jetty-http2/http2-client/pom.xml +++ b/jetty-http2/http2-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-http2/http2-common/pom.xml b/jetty-http2/http2-common/pom.xml index a306aaf5132..8477a2eb69a 100644 --- a/jetty-http2/http2-common/pom.xml +++ b/jetty-http2/http2-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-http2/http2-hpack/pom.xml b/jetty-http2/http2-hpack/pom.xml index 64e6bcf2e3a..68032aa34fa 100644 --- a/jetty-http2/http2-hpack/pom.xml +++ b/jetty-http2/http2-hpack/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-http2/http2-http-client-transport/pom.xml b/jetty-http2/http2-http-client-transport/pom.xml index 4bb6775879c..bcad68df932 100644 --- a/jetty-http2/http2-http-client-transport/pom.xml +++ b/jetty-http2/http2-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index edb7f54fbba..a732e96ce7f 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-http2/pom.xml b/jetty-http2/pom.xml index 375c665b7ff..326b811d7e5 100644 --- a/jetty-http2/pom.xml +++ b/jetty-http2/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-infinispan/infinispan-common/pom.xml b/jetty-infinispan/infinispan-common/pom.xml index ad7cdd6acdc..0536118d90d 100644 --- a/jetty-infinispan/infinispan-common/pom.xml +++ b/jetty-infinispan/infinispan-common/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 infinispan-common diff --git a/jetty-infinispan/infinispan-embedded-query/pom.xml b/jetty-infinispan/infinispan-embedded-query/pom.xml index f90d532ab87..366c616d518 100644 --- a/jetty-infinispan/infinispan-embedded-query/pom.xml +++ b/jetty-infinispan/infinispan-embedded-query/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 infinispan-embedded-query diff --git a/jetty-infinispan/infinispan-embedded/pom.xml b/jetty-infinispan/infinispan-embedded/pom.xml index df8881eafca..ca1b384df48 100644 --- a/jetty-infinispan/infinispan-embedded/pom.xml +++ b/jetty-infinispan/infinispan-embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 infinispan-embedded diff --git a/jetty-infinispan/infinispan-remote-query/pom.xml b/jetty-infinispan/infinispan-remote-query/pom.xml index 2bcb1dd73f5..77d6db664d0 100644 --- a/jetty-infinispan/infinispan-remote-query/pom.xml +++ b/jetty-infinispan/infinispan-remote-query/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 infinispan-remote-query diff --git a/jetty-infinispan/infinispan-remote/pom.xml b/jetty-infinispan/infinispan-remote/pom.xml index 20d00b295d7..e9b9bce76bb 100644 --- a/jetty-infinispan/infinispan-remote/pom.xml +++ b/jetty-infinispan/infinispan-remote/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 infinispan-remote diff --git a/jetty-infinispan/pom.xml b/jetty-infinispan/pom.xml index d70fe24db52..18767f10e40 100644 --- a/jetty-infinispan/pom.xml +++ b/jetty-infinispan/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index ecd83830522..e6e15bf9ec4 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-io diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index a45e8be0aa6..390a55ba7ff 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-jaas diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index 595ea0066bd..c1754e6faf3 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-jmh/pom.xml b/jetty-jmh/pom.xml index e360dd7ac8d..c61ef420aba 100644 --- a/jetty-jmh/pom.xml +++ b/jetty-jmh/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index 8286960d0c3..d44243e00e4 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index c2644dda69e..6669b01b27c 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-jndi diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 9b37fe65beb..0df0420b71f 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-jspc-maven-plugin diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index 0b3cb801cc8..23dc47f25c4 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-maven-plugin diff --git a/jetty-memcached/jetty-memcached-sessions/pom.xml b/jetty-memcached/jetty-memcached-sessions/pom.xml index a5842dcffdb..965e96496e5 100644 --- a/jetty-memcached/jetty-memcached-sessions/pom.xml +++ b/jetty-memcached/jetty-memcached-sessions/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.memcached memcached-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-memcached/pom.xml b/jetty-memcached/pom.xml index d7e378f3cdb..e155bea63dc 100644 --- a/jetty-memcached/pom.xml +++ b/jetty-memcached/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 67eb2c67785..010bcb01587 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-nosql diff --git a/jetty-openid/pom.xml b/jetty-openid/pom.xml index ef800ac6ead..048067441e3 100644 --- a/jetty-openid/pom.xml +++ b/jetty-openid/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-osgi/jetty-osgi-alpn/pom.xml b/jetty-osgi/jetty-osgi-alpn/pom.xml index 26825db21c4..df1186ef605 100644 --- a/jetty-osgi/jetty-osgi-alpn/pom.xml +++ b/jetty-osgi/jetty-osgi-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-osgi-alpn diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index 4d1041fa624..58e6778f7e9 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-osgi-boot-jsp diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index 995a851c89e..6c7f981a8d5 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index ee24f3db9b0..02dec50cb39 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-osgi-boot diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index 644dbb26b71..6ed22156851 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-httpservice diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index ed3ceefd649..f07d971e99a 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index e35eb60497c..a6b34521f60 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 test-jetty-osgi-context diff --git a/jetty-osgi/test-jetty-osgi-fragment/pom.xml b/jetty-osgi/test-jetty-osgi-fragment/pom.xml index e1dcb11d419..3ab9a98edec 100644 --- a/jetty-osgi/test-jetty-osgi-fragment/pom.xml +++ b/jetty-osgi/test-jetty-osgi-fragment/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-server/pom.xml b/jetty-osgi/test-jetty-osgi-server/pom.xml index 951a4818b7f..a46a9d0847a 100644 --- a/jetty-osgi/test-jetty-osgi-server/pom.xml +++ b/jetty-osgi/test-jetty-osgi-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 test-jetty-osgi-server diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index ba24794060b..d7a3c21aee5 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 0d2242bf3e3..ec1edfef102 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml 4.0.0 diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index c263936fbec..da780936e09 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-plus diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml index 7549b952815..0ce35a9715c 100644 --- a/jetty-proxy/pom.xml +++ b/jetty-proxy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-proxy diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml index b950c28bbb8..1f6c13de3be 100644 --- a/jetty-quickstart/pom.xml +++ b/jetty-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 org.eclipse.jetty diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 0a42bf696d5..d6076d11707 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-rewrite diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml index 366582ad9bc..339a815a787 100644 --- a/jetty-runner/pom.xml +++ b/jetty-runner/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-runner diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index d2ef0f78d5c..2ea4002db86 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-security diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index 0dd312e6655..df0e651924b 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-server diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index ed8251c6cad..108add12a66 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-servlet diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index bd80b6edeff..15ebcddfb12 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-servlets diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml index 816f0eb6f47..98ef4b8c5a5 100644 --- a/jetty-spring/pom.xml +++ b/jetty-spring/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-spring diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index a34fac4c4af..b68c7161830 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-start diff --git a/jetty-unixsocket/pom.xml b/jetty-unixsocket/pom.xml index f2e2e94afad..1f3e4b4a72d 100644 --- a/jetty-unixsocket/pom.xml +++ b/jetty-unixsocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-unixsocket diff --git a/jetty-util-ajax/pom.xml b/jetty-util-ajax/pom.xml index 529f53f142f..51d5c24a8ae 100644 --- a/jetty-util-ajax/pom.xml +++ b/jetty-util-ajax/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-util-ajax diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index 0727af493b4..52454b85786 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index b735d58a1e0..da970c5a32b 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-webapp diff --git a/jetty-websocket/javax-websocket-client-impl/pom.xml b/jetty-websocket/javax-websocket-client-impl/pom.xml index b923794be97..f7d44f0b2a3 100644 --- a/jetty-websocket/javax-websocket-client-impl/pom.xml +++ b/jetty-websocket/javax-websocket-client-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-websocket/javax-websocket-server-impl/pom.xml b/jetty-websocket/javax-websocket-server-impl/pom.xml index fb505e57f02..9284d93f56b 100644 --- a/jetty-websocket/javax-websocket-server-impl/pom.xml +++ b/jetty-websocket/javax-websocket-server-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-websocket/jetty-websocket-tests/pom.xml b/jetty-websocket/jetty-websocket-tests/pom.xml index 0f7f8d37b1b..6ad5ae24f86 100644 --- a/jetty-websocket/jetty-websocket-tests/pom.xml +++ b/jetty-websocket/jetty-websocket-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index 6373df8eab4..3a22cd44b58 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-websocket/websocket-api/pom.xml b/jetty-websocket/websocket-api/pom.xml index 9dd5a186c07..d92138a8f97 100644 --- a/jetty-websocket/websocket-api/pom.xml +++ b/jetty-websocket/websocket-api/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml index 97743dbb5ee..91dc0e853aa 100644 --- a/jetty-websocket/websocket-client/pom.xml +++ b/jetty-websocket/websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml index 925c0196ffc..59f16de0e80 100644 --- a/jetty-websocket/websocket-common/pom.xml +++ b/jetty-websocket/websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-websocket/websocket-server/pom.xml b/jetty-websocket/websocket-server/pom.xml index 9879aebb89a..c6a7f180520 100644 --- a/jetty-websocket/websocket-server/pom.xml +++ b/jetty-websocket/websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml index c5b768e5d2c..7e8afd8ce9d 100644 --- a/jetty-websocket/websocket-servlet/pom.xml +++ b/jetty-websocket/websocket-servlet/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index e16f38ab18a..1bd7ff19700 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index d289cf52e9f..1b256c53589 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 Jetty :: Project The Eclipse Jetty Project pom diff --git a/tests/pom.xml b/tests/pom.xml index 878cff47b15..78da89afa26 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml org.eclipse.jetty.tests diff --git a/tests/test-continuation/pom.xml b/tests/test-continuation/pom.xml index a4b443e4d06..d6cead9d149 100644 --- a/tests/test-continuation/pom.xml +++ b/tests/test-continuation/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml 4.0.0 diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml index e83f5ff5da3..407fc894bda 100644 --- a/tests/test-distribution/pom.xml +++ b/tests/test-distribution/pom.xml @@ -2,7 +2,7 @@ tests-parent org.eclipse.jetty.tests - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/tests/test-http-client-transport/pom.xml b/tests/test-http-client-transport/pom.xml index 2936d6b6994..bbc2b50e9af 100644 --- a/tests/test-http-client-transport/pom.xml +++ b/tests/test-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index 6568c44c587..d215a85d1a4 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 test-integration diff --git a/tests/test-jmx/jmx-webapp-it/pom.xml b/tests/test-jmx/jmx-webapp-it/pom.xml index 167233438c4..78a7e2013f8 100644 --- a/tests/test-jmx/jmx-webapp-it/pom.xml +++ b/tests/test-jmx/jmx-webapp-it/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 jmx-webapp-it diff --git a/tests/test-jmx/jmx-webapp/pom.xml b/tests/test-jmx/jmx-webapp/pom.xml index 3c9cbed0a63..6f120b4cd58 100644 --- a/tests/test-jmx/jmx-webapp/pom.xml +++ b/tests/test-jmx/jmx-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 jmx-webapp war diff --git a/tests/test-jmx/pom.xml b/tests/test-jmx/pom.xml index 75c78a25acd..fa9fd00d9e9 100644 --- a/tests/test-jmx/pom.xml +++ b/tests/test-jmx/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 test-jmx-parent diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index a58526488cc..2e44648814d 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index 481c85140ed..c4e8cfefc94 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml 4.0.0 diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 29151e6bad1..1acea012517 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-file-sessions/pom.xml b/tests/test-sessions/test-file-sessions/pom.xml index f4d6e3acdcc..7f9c7a4ad38 100644 --- a/tests/test-sessions/test-file-sessions/pom.xml +++ b/tests/test-sessions/test-file-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-file-sessions Jetty Tests :: Sessions :: File diff --git a/tests/test-sessions/test-gcloud-sessions/pom.xml b/tests/test-sessions/test-gcloud-sessions/pom.xml index cc5dc6617e5..e5279cc6d14 100644 --- a/tests/test-sessions/test-gcloud-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-gcloud-sessions Jetty Tests :: Sessions :: GCloud diff --git a/tests/test-sessions/test-hazelcast-sessions/pom.xml b/tests/test-sessions/test-hazelcast-sessions/pom.xml index 5adf60a176e..ed5324b9be2 100644 --- a/tests/test-sessions/test-hazelcast-sessions/pom.xml +++ b/tests/test-sessions/test-hazelcast-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-hazelcast-sessions Jetty Tests :: Sessions :: Hazelcast diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index 544b490f66f..6584c450768 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-infinispan-sessions Jetty Tests :: Sessions :: Infinispan diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index 805fff9eaf4..ca8f56fc4f0 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-memcached-sessions/pom.xml b/tests/test-sessions/test-memcached-sessions/pom.xml index ce8e99a3448..cd0ed2c81a5 100644 --- a/tests/test-sessions/test-memcached-sessions/pom.xml +++ b/tests/test-sessions/test-memcached-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-memcached-sessions Jetty Tests :: Sessions :: Memcached diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index af8663e6592..0173d130552 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index ec294c4f33e..6b52d4a95cb 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index d7f8bcc76e0..5339598d104 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml test-webapps-parent diff --git a/tests/test-webapps/test-cdi-common-webapp/pom.xml b/tests/test-webapps/test-cdi-common-webapp/pom.xml index 19f9238a5cd..9733392a94d 100644 --- a/tests/test-webapps/test-cdi-common-webapp/pom.xml +++ b/tests/test-webapps/test-cdi-common-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/tests/test-webapps/test-felix-webapp/pom.xml b/tests/test-webapps/test-felix-webapp/pom.xml index e1394066610..f394b5e59ce 100644 --- a/tests/test-webapps/test-felix-webapp/pom.xml +++ b/tests/test-webapps/test-felix-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/tests/test-webapps/test-http2-webapp/pom.xml b/tests/test-webapps/test-http2-webapp/pom.xml index 7d0a970d852..0c8548b3565 100644 --- a/tests/test-webapps/test-http2-webapp/pom.xml +++ b/tests/test-webapps/test-http2-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml index 8adf4101eca..8f9c7bef7a2 100644 --- a/tests/test-webapps/test-jaas-webapp/pom.xml +++ b/tests/test-webapps/test-jaas-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-jaas-webapp Jetty Tests :: WebApp :: JAAS diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index 4c679e6c1de..091605ba94f 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml index cca41896ce4..c76b43e5fb1 100644 --- a/tests/test-webapps/test-jndi-webapp/pom.xml +++ b/tests/test-webapps/test-jndi-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-jndi-webapp Jetty Tests :: WebApp :: JNDI diff --git a/tests/test-webapps/test-mock-resources/pom.xml b/tests/test-webapps/test-mock-resources/pom.xml index 1b5a443b9ef..5d8f8923561 100644 --- a/tests/test-webapps/test-mock-resources/pom.xml +++ b/tests/test-webapps/test-mock-resources/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 Jetty Tests :: WebApp :: Mock Resources test-mock-resources diff --git a/tests/test-webapps/test-owb-cdi-webapp/pom.xml b/tests/test-webapps/test-owb-cdi-webapp/pom.xml index e62bba5c89a..e3ece021a37 100644 --- a/tests/test-webapps/test-owb-cdi-webapp/pom.xml +++ b/tests/test-webapps/test-owb-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml index ba804778441..30d3f1ea8fd 100644 --- a/tests/test-webapps/test-proxy-webapp/pom.xml +++ b/tests/test-webapps/test-proxy-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-servlet-spec/pom.xml b/tests/test-webapps/test-servlet-spec/pom.xml index c09e9af3e66..e35670c9821 100644 --- a/tests/test-webapps/test-servlet-spec/pom.xml +++ b/tests/test-webapps/test-servlet-spec/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-servlet-spec-parent Jetty Tests :: Spec Test WebApp :: Parent diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml index b02bc7c7615..afc6d7c6c77 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-container-initializer jar diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml index ac2113d9346..c4c5db23634 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 Jetty Tests :: Webapps :: Spec Webapp test-spec-webapp diff --git a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml index 367ce938ce6..9fa2b56cde7 100644 --- a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar diff --git a/tests/test-webapps/test-simple-webapp/pom.xml b/tests/test-webapps/test-simple-webapp/pom.xml index 5412168dd5b..edd773141a3 100644 --- a/tests/test-webapps/test-simple-webapp/pom.xml +++ b/tests/test-webapps/test-simple-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-simple-webapp diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index adbd46184f7..72db0e93f70 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 diff --git a/tests/test-webapps/test-weld-cdi-webapp/pom.xml b/tests/test-webapps/test-weld-cdi-webapp/pom.xml index 64a9ff3b714..67a7571cc7b 100644 --- a/tests/test-webapps/test-weld-cdi-webapp/pom.xml +++ b/tests/test-webapps/test-weld-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24-SNAPSHOT + 9.4.24.v20191120 4.0.0 From 217602e97f2b9de41e042620148f910a82626cd0 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 20 Nov 2019 15:47:53 -0600 Subject: [PATCH 22/77] Issue #4334 - Enhancing JSON Test Signed-off-by: Joakim Erdfelt --- .../jetty/server/ErrorHandlerTest.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java index 87184c19e32..8fc405a163d 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java @@ -19,7 +19,9 @@ package org.eclipse.jetty.server; import java.io.IOException; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import javax.servlet.DispatcherType; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; @@ -42,10 +44,12 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertTrue; public class ErrorHandlerTest { @@ -91,7 +95,7 @@ public class ErrorHandlerTest // produce an exception with an JSON formatted cause message if (target.startsWith("/jsonmessage/")) { - String message = "{\n \"glossary\": {\n \"title\": \"example\"\n }\n }"; + String message = "\"}, \"glossary\": {\n \"title\": \"example\"\n }\n {\""; throw new ServletException(new RuntimeException(message)); } @@ -473,6 +477,25 @@ public class ErrorHandlerTest { Map jo = (Map)JSON.parse(response.getContent()); + Set acceptableKeyNames = new HashSet<>(); + acceptableKeyNames.add("url"); + acceptableKeyNames.add("status"); + acceptableKeyNames.add("message"); + acceptableKeyNames.add("servlet"); + acceptableKeyNames.add("cause0"); + acceptableKeyNames.add("cause1"); + acceptableKeyNames.add("cause2"); + + for (Object key : jo.keySet()) + { + String keyStr = (String)key; + assertTrue(acceptableKeyNames.contains(keyStr), "Unexpected Key [" + keyStr + "]"); + + Object value = jo.get(key); + assertThat("Unexpected value type (" + value.getClass().getName() + ")", + value, instanceOf(String.class)); + } + assertThat("url field", jo.get("url"), is(notNullValue())); String expectedStatus = String.valueOf(response.getStatus()); assertThat("status field", jo.get("status"), is(expectedStatus)); From 0f7a3b2d91a0d01da4c596ff09c58df6eac922f7 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 20 Nov 2019 16:08:38 -0600 Subject: [PATCH 23/77] Updating to version 9.4.25-SNAPSHOT --- VERSION.txt | 2 + aggregates/jetty-all-compact3/pom.xml | 2 +- aggregates/jetty-all/pom.xml | 2 +- apache-jsp/pom.xml | 2 +- apache-jstl/pom.xml | 2 +- build-resources/pom.xml | 2 +- examples/async-rest/async-rest-jar/pom.xml | 2 +- examples/async-rest/async-rest-webapp/pom.xml | 2 +- examples/async-rest/pom.xml | 2 +- examples/embedded/pom.xml | 2 +- examples/pom.xml | 2 +- jetty-alpn/jetty-alpn-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-openjdk8-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-openjdk8-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-server/pom.xml | 2 +- jetty-alpn/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-ant/pom.xml | 2 +- jetty-bom/pom.xml | 134 +++++++++--------- jetty-cdi/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-continuation/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-documentation/pom.xml | 2 +- jetty-fcgi/fcgi-client/pom.xml | 2 +- jetty-fcgi/fcgi-server/pom.xml | 2 +- jetty-fcgi/pom.xml | 2 +- .../jetty-gcloud-session-manager/pom.xml | 2 +- jetty-gcloud/pom.xml | 2 +- jetty-hazelcast/pom.xml | 2 +- jetty-home/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-http2/http2-alpn-tests/pom.xml | 2 +- jetty-http2/http2-client/pom.xml | 2 +- jetty-http2/http2-common/pom.xml | 2 +- jetty-http2/http2-hpack/pom.xml | 2 +- .../http2-http-client-transport/pom.xml | 2 +- jetty-http2/http2-server/pom.xml | 2 +- jetty-http2/pom.xml | 2 +- jetty-infinispan/infinispan-common/pom.xml | 2 +- .../infinispan-embedded-query/pom.xml | 2 +- jetty-infinispan/infinispan-embedded/pom.xml | 2 +- .../infinispan-remote-query/pom.xml | 2 +- jetty-infinispan/infinispan-remote/pom.xml | 2 +- jetty-infinispan/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaas/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmh/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jspc-maven-plugin/pom.xml | 2 +- jetty-maven-plugin/pom.xml | 2 +- .../jetty-memcached-sessions/pom.xml | 2 +- jetty-memcached/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-openid/pom.xml | 2 +- jetty-osgi/jetty-osgi-alpn/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-context/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-fragment/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-server/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-webapp/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-proxy/pom.xml | 2 +- jetty-quickstart/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-runner/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spring/pom.xml | 2 +- jetty-start/pom.xml | 2 +- jetty-unixsocket/pom.xml | 2 +- jetty-util-ajax/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- .../javax-websocket-client-impl/pom.xml | 2 +- .../javax-websocket-server-impl/pom.xml | 2 +- jetty-websocket/jetty-websocket-tests/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-websocket/websocket-api/pom.xml | 2 +- jetty-websocket/websocket-client/pom.xml | 2 +- jetty-websocket/websocket-common/pom.xml | 2 +- jetty-websocket/websocket-server/pom.xml | 2 +- jetty-websocket/websocket-servlet/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-continuation/pom.xml | 2 +- tests/test-distribution/pom.xml | 2 +- tests/test-http-client-transport/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-jmx/jmx-webapp-it/pom.xml | 2 +- tests/test-jmx/jmx-webapp/pom.xml | 2 +- tests/test-jmx/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-quickstart/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- .../test-sessions/test-file-sessions/pom.xml | 2 +- .../test-gcloud-sessions/pom.xml | 2 +- .../test-hazelcast-sessions/pom.xml | 2 +- .../test-infinispan-sessions/pom.xml | 2 +- .../test-sessions/test-jdbc-sessions/pom.xml | 2 +- .../test-memcached-sessions/pom.xml | 2 +- .../test-mongodb-sessions/pom.xml | 2 +- .../test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- .../test-cdi-common-webapp/pom.xml | 2 +- tests/test-webapps/test-felix-webapp/pom.xml | 2 +- tests/test-webapps/test-http2-webapp/pom.xml | 2 +- tests/test-webapps/test-jaas-webapp/pom.xml | 2 +- tests/test-webapps/test-jetty-webapp/pom.xml | 2 +- tests/test-webapps/test-jndi-webapp/pom.xml | 2 +- .../test-webapps/test-mock-resources/pom.xml | 2 +- .../test-webapps/test-owb-cdi-webapp/pom.xml | 2 +- tests/test-webapps/test-proxy-webapp/pom.xml | 2 +- tests/test-webapps/test-servlet-spec/pom.xml | 2 +- .../test-container-initializer/pom.xml | 2 +- .../test-spec-webapp/pom.xml | 2 +- .../test-web-fragment/pom.xml | 2 +- tests/test-webapps/test-simple-webapp/pom.xml | 2 +- .../test-webapps/test-webapp-rfc2616/pom.xml | 2 +- .../test-webapps/test-weld-cdi-webapp/pom.xml | 2 +- 136 files changed, 203 insertions(+), 201 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 7a468552f39..665e2296f89 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,3 +1,5 @@ +jetty-9.4.25-SNAPSHOT + jetty-9.4.24.v20191120 - 20 November 2019 + 3083 The ini-template for jetty.console-capture.dir does not match the default value diff --git a/aggregates/jetty-all-compact3/pom.xml b/aggregates/jetty-all-compact3/pom.xml index 1573b1e9f22..34b04df37d9 100644 --- a/aggregates/jetty-all-compact3/pom.xml +++ b/aggregates/jetty-all-compact3/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index 9a6c1f5f0ad..0ca5eb35a8b 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml index 7150aa1d3ae..9c17689c4e3 100644 --- a/apache-jsp/pom.xml +++ b/apache-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 apache-jsp diff --git a/apache-jstl/pom.xml b/apache-jstl/pom.xml index ad1e8be6751..316aa9bf61e 100644 --- a/apache-jstl/pom.xml +++ b/apache-jstl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 apache-jstl diff --git a/build-resources/pom.xml b/build-resources/pom.xml index 130dda39218..6ee4fe67a15 100644 --- a/build-resources/pom.xml +++ b/build-resources/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.eclipse.jetty build-resources - 9.4.24.v20191120 + 9.4.25-SNAPSHOT jar Jetty :: Build Resources diff --git a/examples/async-rest/async-rest-jar/pom.xml b/examples/async-rest/async-rest-jar/pom.xml index 35b2f0b6204..0aa4046b7bd 100644 --- a/examples/async-rest/async-rest-jar/pom.xml +++ b/examples/async-rest/async-rest-jar/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/examples/async-rest/async-rest-webapp/pom.xml b/examples/async-rest/async-rest-webapp/pom.xml index 2ca1872e69a..22c4b77e3e3 100644 --- a/examples/async-rest/async-rest-webapp/pom.xml +++ b/examples/async-rest/async-rest-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/examples/async-rest/pom.xml b/examples/async-rest/pom.xml index fd08e0eaaca..9f7a557bc52 100644 --- a/examples/async-rest/pom.xml +++ b/examples/async-rest/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml index f36ca8d511f..bbf9cb0ec78 100644 --- a/examples/embedded/pom.xml +++ b/examples/embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index 75531a33cd1..14d89530f74 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-client/pom.xml b/jetty-alpn/jetty-alpn-client/pom.xml index 9ea7e663aee..6ef8cf53211 100644 --- a/jetty-alpn/jetty-alpn-client/pom.xml +++ b/jetty-alpn/jetty-alpn-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-alpn-client diff --git a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml index 55da9916d95..78261afca65 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml index 02d76affd18..5ed8fbb5910 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-client/pom.xml b/jetty-alpn/jetty-alpn-java-client/pom.xml index 3a179216e6f..c451eab7f68 100644 --- a/jetty-alpn/jetty-alpn-java-client/pom.xml +++ b/jetty-alpn/jetty-alpn-java-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-server/pom.xml b/jetty-alpn/jetty-alpn-java-server/pom.xml index 58e1b8ac057..ba74e65d63d 100644 --- a/jetty-alpn/jetty-alpn-java-server/pom.xml +++ b/jetty-alpn/jetty-alpn-java-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml b/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml index 4d28bc00639..8113ba96282 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml +++ b/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml b/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml index 7488df48ec7..ae7a72d44a3 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml +++ b/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-server/pom.xml b/jetty-alpn/jetty-alpn-server/pom.xml index 1fc69ac9736..9f6cc6a3c90 100644 --- a/jetty-alpn/jetty-alpn-server/pom.xml +++ b/jetty-alpn/jetty-alpn-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-alpn-server diff --git a/jetty-alpn/pom.xml b/jetty-alpn/pom.xml index 9f270513cda..04c26054e17 100644 --- a/jetty-alpn/pom.xml +++ b/jetty-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-alpn-parent diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 0f08f5626bc..30d59b80eaf 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-annotations diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml index 4bcae7832fa..67bae7b6bdd 100644 --- a/jetty-ant/pom.xml +++ b/jetty-ant/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-ant diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index 8eff5788bef..b826e8a3dcb 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -9,7 +9,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT @@ -53,336 +53,336 @@ org.eclipse.jetty apache-jsp - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty apache-jstl - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-alpn-client - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-alpn-java-client - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-alpn-java-server - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-alpn-openjdk8-client - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-alpn-openjdk8-server - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-alpn-conscrypt-client - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-alpn-conscrypt-server - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-alpn-server - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-annotations - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-ant - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-client - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-continuation - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-deploy - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-distribution - 9.4.24.v20191120 + 9.4.25-SNAPSHOT zip org.eclipse.jetty jetty-distribution - 9.4.24.v20191120 + 9.4.25-SNAPSHOT tar.gz org.eclipse.jetty.fcgi fcgi-client - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.fcgi fcgi-server - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.gcloud jetty-gcloud-session-manager - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-home - 9.4.24.v20191120 + 9.4.25-SNAPSHOT zip org.eclipse.jetty jetty-home - 9.4.24.v20191120 + 9.4.25-SNAPSHOT tar.gz org.eclipse.jetty jetty-http - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.http2 http2-client - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.http2 http2-common - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.http2 http2-hpack - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.http2 http2-http-client-transport - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.http2 http2-server - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-http-spi - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty infinispan-common - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty infinispan-remote-query - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty infinispan-embedded-query - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-hazelcast - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-io - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-jaas - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-jaspi - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-jmx - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-jndi - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.memcached jetty-memcached-sessions - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-nosql - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.osgi jetty-osgi-boot - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.osgi jetty-osgi-boot-jsp - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.osgi jetty-osgi-boot-warurl - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.osgi jetty-httpservice - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-plus - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-proxy - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-quickstart - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-rewrite - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-security - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-openid - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-server - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-servlet - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-servlets - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-spring - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-unixsocket - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-util - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-util-ajax - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-webapp - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.websocket javax-websocket-client-impl - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.websocket javax-websocket-server-impl - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.websocket websocket-api - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.websocket websocket-client - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.websocket websocket-common - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.websocket websocket-server - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty.websocket websocket-servlet - 9.4.24.v20191120 + 9.4.25-SNAPSHOT org.eclipse.jetty jetty-xml - 9.4.24.v20191120 + 9.4.25-SNAPSHOT diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index d2bfa9e42e2..926bfa2965a 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 org.eclipse.jetty diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index 63b58ff40f2..7aaf7e28be3 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml index 55073849404..add2e5ee0cc 100644 --- a/jetty-continuation/pom.xml +++ b/jetty-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-continuation diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index bf79939adbd..4c49a584cfa 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-deploy diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 038dff55fd5..72f62961a71 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-distribution diff --git a/jetty-documentation/pom.xml b/jetty-documentation/pom.xml index 9f90f964e56..0aa65d04c32 100644 --- a/jetty-documentation/pom.xml +++ b/jetty-documentation/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT jetty-documentation Jetty :: Documentation diff --git a/jetty-fcgi/fcgi-client/pom.xml b/jetty-fcgi/fcgi-client/pom.xml index ac2a731018d..4b2651a0919 100644 --- a/jetty-fcgi/fcgi-client/pom.xml +++ b/jetty-fcgi/fcgi-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-fcgi/fcgi-server/pom.xml b/jetty-fcgi/fcgi-server/pom.xml index 67743979684..a24515ca9b4 100644 --- a/jetty-fcgi/fcgi-server/pom.xml +++ b/jetty-fcgi/fcgi-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-fcgi/pom.xml b/jetty-fcgi/pom.xml index 846c65ae46b..97e42b3329d 100644 --- a/jetty-fcgi/pom.xml +++ b/jetty-fcgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index 13d9a4e710f..595a14bff45 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-gcloud/pom.xml b/jetty-gcloud/pom.xml index 36fc59703c0..26410b87e15 100644 --- a/jetty-gcloud/pom.xml +++ b/jetty-gcloud/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index 811c2722d08..d4d29d78f3b 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index 0919be7f11b..758f774557d 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-home diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index 2622841ae1a..a23be08b8c2 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index bceebc7a553..c257d0f503f 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-http diff --git a/jetty-http2/http2-alpn-tests/pom.xml b/jetty-http2/http2-alpn-tests/pom.xml index 62c7d0c1ef3..8c749139f75 100644 --- a/jetty-http2/http2-alpn-tests/pom.xml +++ b/jetty-http2/http2-alpn-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-client/pom.xml b/jetty-http2/http2-client/pom.xml index 4cce7cee19b..d6ed4948183 100644 --- a/jetty-http2/http2-client/pom.xml +++ b/jetty-http2/http2-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-common/pom.xml b/jetty-http2/http2-common/pom.xml index 8477a2eb69a..9a2c324953b 100644 --- a/jetty-http2/http2-common/pom.xml +++ b/jetty-http2/http2-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-hpack/pom.xml b/jetty-http2/http2-hpack/pom.xml index 68032aa34fa..baf054ec05b 100644 --- a/jetty-http2/http2-hpack/pom.xml +++ b/jetty-http2/http2-hpack/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-http-client-transport/pom.xml b/jetty-http2/http2-http-client-transport/pom.xml index bcad68df932..6c1c2cd231d 100644 --- a/jetty-http2/http2-http-client-transport/pom.xml +++ b/jetty-http2/http2-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index a732e96ce7f..ce00e5e4071 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-http2/pom.xml b/jetty-http2/pom.xml index 326b811d7e5..37e3b1242bd 100644 --- a/jetty-http2/pom.xml +++ b/jetty-http2/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-infinispan/infinispan-common/pom.xml b/jetty-infinispan/infinispan-common/pom.xml index 0536118d90d..daa09b7cc24 100644 --- a/jetty-infinispan/infinispan-common/pom.xml +++ b/jetty-infinispan/infinispan-common/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 infinispan-common diff --git a/jetty-infinispan/infinispan-embedded-query/pom.xml b/jetty-infinispan/infinispan-embedded-query/pom.xml index 366c616d518..3a25e0ebc55 100644 --- a/jetty-infinispan/infinispan-embedded-query/pom.xml +++ b/jetty-infinispan/infinispan-embedded-query/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 infinispan-embedded-query diff --git a/jetty-infinispan/infinispan-embedded/pom.xml b/jetty-infinispan/infinispan-embedded/pom.xml index ca1b384df48..2c714961d08 100644 --- a/jetty-infinispan/infinispan-embedded/pom.xml +++ b/jetty-infinispan/infinispan-embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 infinispan-embedded diff --git a/jetty-infinispan/infinispan-remote-query/pom.xml b/jetty-infinispan/infinispan-remote-query/pom.xml index 77d6db664d0..7dba5896e0e 100644 --- a/jetty-infinispan/infinispan-remote-query/pom.xml +++ b/jetty-infinispan/infinispan-remote-query/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 infinispan-remote-query diff --git a/jetty-infinispan/infinispan-remote/pom.xml b/jetty-infinispan/infinispan-remote/pom.xml index e9b9bce76bb..c2186de6038 100644 --- a/jetty-infinispan/infinispan-remote/pom.xml +++ b/jetty-infinispan/infinispan-remote/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 infinispan-remote diff --git a/jetty-infinispan/pom.xml b/jetty-infinispan/pom.xml index 18767f10e40..02766dbe1b0 100644 --- a/jetty-infinispan/pom.xml +++ b/jetty-infinispan/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index e6e15bf9ec4..9410e5998cf 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-io diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index 390a55ba7ff..00b69758a6a 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-jaas diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index c1754e6faf3..b84e8d88721 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-jmh/pom.xml b/jetty-jmh/pom.xml index c61ef420aba..a80b383a94d 100644 --- a/jetty-jmh/pom.xml +++ b/jetty-jmh/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index d44243e00e4..368fa9c2ca3 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 6669b01b27c..f197de664c2 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-jndi diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 0df0420b71f..b2eda791736 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-jspc-maven-plugin diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index 23dc47f25c4..708e0a84fa1 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-maven-plugin diff --git a/jetty-memcached/jetty-memcached-sessions/pom.xml b/jetty-memcached/jetty-memcached-sessions/pom.xml index 965e96496e5..dccaff17f68 100644 --- a/jetty-memcached/jetty-memcached-sessions/pom.xml +++ b/jetty-memcached/jetty-memcached-sessions/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.memcached memcached-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-memcached/pom.xml b/jetty-memcached/pom.xml index e155bea63dc..e0b5b55186b 100644 --- a/jetty-memcached/pom.xml +++ b/jetty-memcached/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 010bcb01587..d7d606ab028 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-nosql diff --git a/jetty-openid/pom.xml b/jetty-openid/pom.xml index 048067441e3..fb1d61b0399 100644 --- a/jetty-openid/pom.xml +++ b/jetty-openid/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-osgi/jetty-osgi-alpn/pom.xml b/jetty-osgi/jetty-osgi-alpn/pom.xml index df1186ef605..5e30c9983e0 100644 --- a/jetty-osgi/jetty-osgi-alpn/pom.xml +++ b/jetty-osgi/jetty-osgi-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-osgi-alpn diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index 58e6778f7e9..73f31c7e18e 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-osgi-boot-jsp diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index 6c7f981a8d5..de472b735fa 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index 02dec50cb39..2e738e17a57 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-osgi-boot diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index 6ed22156851..6de1f0f8e1c 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-httpservice diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index f07d971e99a..c35d169828c 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index a6b34521f60..2e8b50060b4 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 test-jetty-osgi-context diff --git a/jetty-osgi/test-jetty-osgi-fragment/pom.xml b/jetty-osgi/test-jetty-osgi-fragment/pom.xml index 3ab9a98edec..531df70188d 100644 --- a/jetty-osgi/test-jetty-osgi-fragment/pom.xml +++ b/jetty-osgi/test-jetty-osgi-fragment/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-server/pom.xml b/jetty-osgi/test-jetty-osgi-server/pom.xml index a46a9d0847a..d571a798e6a 100644 --- a/jetty-osgi/test-jetty-osgi-server/pom.xml +++ b/jetty-osgi/test-jetty-osgi-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 test-jetty-osgi-server diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index d7a3c21aee5..d6c1cfa35a1 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index ec1edfef102..ee5a40a7a2a 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index da780936e09..ef03be2d78b 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-plus diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml index 0ce35a9715c..a1dd245d418 100644 --- a/jetty-proxy/pom.xml +++ b/jetty-proxy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-proxy diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml index 1f6c13de3be..573928cf875 100644 --- a/jetty-quickstart/pom.xml +++ b/jetty-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 org.eclipse.jetty diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index d6076d11707..2f64c90363b 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-rewrite diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml index 339a815a787..def93882cba 100644 --- a/jetty-runner/pom.xml +++ b/jetty-runner/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-runner diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index 2ea4002db86..cf661fb3a76 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-security diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index df0e651924b..5b78224fdde 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-server diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index 108add12a66..96f066bb1ec 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-servlet diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 15ebcddfb12..5f7b2c671fd 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-servlets diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml index 98ef4b8c5a5..8cb6991327d 100644 --- a/jetty-spring/pom.xml +++ b/jetty-spring/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-spring diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index b68c7161830..668b50f4472 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-start diff --git a/jetty-unixsocket/pom.xml b/jetty-unixsocket/pom.xml index 1f3e4b4a72d..9cd0880c5c9 100644 --- a/jetty-unixsocket/pom.xml +++ b/jetty-unixsocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-unixsocket diff --git a/jetty-util-ajax/pom.xml b/jetty-util-ajax/pom.xml index 51d5c24a8ae..22604ff4581 100644 --- a/jetty-util-ajax/pom.xml +++ b/jetty-util-ajax/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-util-ajax diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index 52454b85786..482b947511e 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index da970c5a32b..1eebcdda6e0 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-webapp diff --git a/jetty-websocket/javax-websocket-client-impl/pom.xml b/jetty-websocket/javax-websocket-client-impl/pom.xml index f7d44f0b2a3..3cf0b5686e6 100644 --- a/jetty-websocket/javax-websocket-client-impl/pom.xml +++ b/jetty-websocket/javax-websocket-client-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/javax-websocket-server-impl/pom.xml b/jetty-websocket/javax-websocket-server-impl/pom.xml index 9284d93f56b..81e9ed83a6e 100644 --- a/jetty-websocket/javax-websocket-server-impl/pom.xml +++ b/jetty-websocket/javax-websocket-server-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/jetty-websocket-tests/pom.xml b/jetty-websocket/jetty-websocket-tests/pom.xml index 6ad5ae24f86..e0da1f3eb7f 100644 --- a/jetty-websocket/jetty-websocket-tests/pom.xml +++ b/jetty-websocket/jetty-websocket-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index 3a22cd44b58..0dd82439c36 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-api/pom.xml b/jetty-websocket/websocket-api/pom.xml index d92138a8f97..4658e3e9182 100644 --- a/jetty-websocket/websocket-api/pom.xml +++ b/jetty-websocket/websocket-api/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml index 91dc0e853aa..d4684964262 100644 --- a/jetty-websocket/websocket-client/pom.xml +++ b/jetty-websocket/websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml index 59f16de0e80..0ae394c2a66 100644 --- a/jetty-websocket/websocket-common/pom.xml +++ b/jetty-websocket/websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-server/pom.xml b/jetty-websocket/websocket-server/pom.xml index c6a7f180520..3aa6686ce2f 100644 --- a/jetty-websocket/websocket-server/pom.xml +++ b/jetty-websocket/websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml index 7e8afd8ce9d..4607c3c63e6 100644 --- a/jetty-websocket/websocket-servlet/pom.xml +++ b/jetty-websocket/websocket-servlet/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index 1bd7ff19700..54f2f4ad4f3 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index 1b256c53589..1d24d41326c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT Jetty :: Project The Eclipse Jetty Project pom diff --git a/tests/pom.xml b/tests/pom.xml index 78da89afa26..640e7578b84 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml org.eclipse.jetty.tests diff --git a/tests/test-continuation/pom.xml b/tests/test-continuation/pom.xml index d6cead9d149..bf938e32557 100644 --- a/tests/test-continuation/pom.xml +++ b/tests/test-continuation/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml index 407fc894bda..cf823098f27 100644 --- a/tests/test-distribution/pom.xml +++ b/tests/test-distribution/pom.xml @@ -2,7 +2,7 @@ tests-parent org.eclipse.jetty.tests - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/tests/test-http-client-transport/pom.xml b/tests/test-http-client-transport/pom.xml index bbc2b50e9af..592aa987ee5 100644 --- a/tests/test-http-client-transport/pom.xml +++ b/tests/test-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index d215a85d1a4..33bde0d8c66 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 test-integration diff --git a/tests/test-jmx/jmx-webapp-it/pom.xml b/tests/test-jmx/jmx-webapp-it/pom.xml index 78a7e2013f8..11513daf3f4 100644 --- a/tests/test-jmx/jmx-webapp-it/pom.xml +++ b/tests/test-jmx/jmx-webapp-it/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 jmx-webapp-it diff --git a/tests/test-jmx/jmx-webapp/pom.xml b/tests/test-jmx/jmx-webapp/pom.xml index 6f120b4cd58..1821516a1c6 100644 --- a/tests/test-jmx/jmx-webapp/pom.xml +++ b/tests/test-jmx/jmx-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT jmx-webapp war diff --git a/tests/test-jmx/pom.xml b/tests/test-jmx/pom.xml index fa9fd00d9e9..67d974c2f93 100644 --- a/tests/test-jmx/pom.xml +++ b/tests/test-jmx/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 test-jmx-parent diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index 2e44648814d..e1444178e96 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index c4e8cfefc94..cb0264e6920 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 1acea012517..7b64e74ad7b 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-file-sessions/pom.xml b/tests/test-sessions/test-file-sessions/pom.xml index 7f9c7a4ad38..c628d5325a4 100644 --- a/tests/test-sessions/test-file-sessions/pom.xml +++ b/tests/test-sessions/test-file-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-file-sessions Jetty Tests :: Sessions :: File diff --git a/tests/test-sessions/test-gcloud-sessions/pom.xml b/tests/test-sessions/test-gcloud-sessions/pom.xml index e5279cc6d14..4c26ad3809f 100644 --- a/tests/test-sessions/test-gcloud-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-gcloud-sessions Jetty Tests :: Sessions :: GCloud diff --git a/tests/test-sessions/test-hazelcast-sessions/pom.xml b/tests/test-sessions/test-hazelcast-sessions/pom.xml index ed5324b9be2..3cda58ceb66 100644 --- a/tests/test-sessions/test-hazelcast-sessions/pom.xml +++ b/tests/test-sessions/test-hazelcast-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-hazelcast-sessions Jetty Tests :: Sessions :: Hazelcast diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index 6584c450768..8169501d1bb 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-infinispan-sessions Jetty Tests :: Sessions :: Infinispan diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index ca8f56fc4f0..78011a05a17 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-memcached-sessions/pom.xml b/tests/test-sessions/test-memcached-sessions/pom.xml index cd0ed2c81a5..eea20319a75 100644 --- a/tests/test-sessions/test-memcached-sessions/pom.xml +++ b/tests/test-sessions/test-memcached-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-memcached-sessions Jetty Tests :: Sessions :: Memcached diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index 0173d130552..5c1b285b546 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index 6b52d4a95cb..e1756858f7d 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index 5339598d104..d6ce8fb476a 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml test-webapps-parent diff --git a/tests/test-webapps/test-cdi-common-webapp/pom.xml b/tests/test-webapps/test-cdi-common-webapp/pom.xml index 9733392a94d..a976fa29952 100644 --- a/tests/test-webapps/test-cdi-common-webapp/pom.xml +++ b/tests/test-webapps/test-cdi-common-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-felix-webapp/pom.xml b/tests/test-webapps/test-felix-webapp/pom.xml index f394b5e59ce..1e2359c6acc 100644 --- a/tests/test-webapps/test-felix-webapp/pom.xml +++ b/tests/test-webapps/test-felix-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-http2-webapp/pom.xml b/tests/test-webapps/test-http2-webapp/pom.xml index 0c8548b3565..6e5d2770c0e 100644 --- a/tests/test-webapps/test-http2-webapp/pom.xml +++ b/tests/test-webapps/test-http2-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml index 8f9c7bef7a2..10030733611 100644 --- a/tests/test-webapps/test-jaas-webapp/pom.xml +++ b/tests/test-webapps/test-jaas-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-jaas-webapp Jetty Tests :: WebApp :: JAAS diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index 091605ba94f..d4fb7396320 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml index c76b43e5fb1..bce0f663e79 100644 --- a/tests/test-webapps/test-jndi-webapp/pom.xml +++ b/tests/test-webapps/test-jndi-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-jndi-webapp Jetty Tests :: WebApp :: JNDI diff --git a/tests/test-webapps/test-mock-resources/pom.xml b/tests/test-webapps/test-mock-resources/pom.xml index 5d8f8923561..6647b9a958d 100644 --- a/tests/test-webapps/test-mock-resources/pom.xml +++ b/tests/test-webapps/test-mock-resources/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT Jetty Tests :: WebApp :: Mock Resources test-mock-resources diff --git a/tests/test-webapps/test-owb-cdi-webapp/pom.xml b/tests/test-webapps/test-owb-cdi-webapp/pom.xml index e3ece021a37..63e313d17ae 100644 --- a/tests/test-webapps/test-owb-cdi-webapp/pom.xml +++ b/tests/test-webapps/test-owb-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml index 30d3f1ea8fd..a7cc5669b59 100644 --- a/tests/test-webapps/test-proxy-webapp/pom.xml +++ b/tests/test-webapps/test-proxy-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-servlet-spec/pom.xml b/tests/test-webapps/test-servlet-spec/pom.xml index e35670c9821..ef2175f8901 100644 --- a/tests/test-webapps/test-servlet-spec/pom.xml +++ b/tests/test-webapps/test-servlet-spec/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-servlet-spec-parent Jetty Tests :: Spec Test WebApp :: Parent diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml index afc6d7c6c77..8d1cf510b51 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-container-initializer jar diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml index c4c5db23634..67fa5de0afc 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT Jetty Tests :: Webapps :: Spec Webapp test-spec-webapp diff --git a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml index 9fa2b56cde7..6e8e949d7f2 100644 --- a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar diff --git a/tests/test-webapps/test-simple-webapp/pom.xml b/tests/test-webapps/test-simple-webapp/pom.xml index edd773141a3..31a274f5d5a 100644 --- a/tests/test-webapps/test-simple-webapp/pom.xml +++ b/tests/test-webapps/test-simple-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-simple-webapp diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index 72db0e93f70..d2628609711 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 diff --git a/tests/test-webapps/test-weld-cdi-webapp/pom.xml b/tests/test-webapps/test-weld-cdi-webapp/pom.xml index 67a7571cc7b..93c8e2dbf1c 100644 --- a/tests/test-webapps/test-weld-cdi-webapp/pom.xml +++ b/tests/test-webapps/test-weld-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.24.v20191120 + 9.4.25-SNAPSHOT 4.0.0 From 07680b4bb20f9acafdee9ea2fde550c23661f32b Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Thu, 21 Nov 2019 17:04:16 +1000 Subject: [PATCH 24/77] Issue #2634 fix occasional exception stack trace in UnixSocketTest (#4339) Signed-off-by: olivier lamy --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d289cf52e9f..1526f01c761 100644 --- a/pom.xml +++ b/pom.xml @@ -1101,7 +1101,7 @@ com.github.jnr jnr-unixsocket - 0.22 + 0.24 From 668cd862835190c94ef9f2d144139f813379935f Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 22 Nov 2019 17:50:28 +1100 Subject: [PATCH 25/77] Issue #995 - UrlEncoded.encodeString should not encode unreserved chars Signed-off-by: Lachlan Roberts --- .../src/main/java/org/eclipse/jetty/util/UrlEncoded.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java index d5f91f4e584..f76688d84b5 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java @@ -945,7 +945,8 @@ public class UrlEncoded extends MultiMap implements Cloneable } else if (b >= 'a' && b <= 'z' || b >= 'A' && b <= 'Z' || - b >= '0' && b <= '9') + b >= '0' && b <= '9' || + b == '-' || b == '.' || b == '_' || b == '~') { encoded[n++] = b; } From dc4ada14ea30af144d4c2ee100b0655d30ba5c80 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 22 Nov 2019 21:13:39 +1100 Subject: [PATCH 26/77] add extra test for server connection close before ws handshake Signed-off-by: Lachlan Roberts --- .../tests/WebSocketOverHTTP2Test.java | 38 +++++++++++++++++-- .../internal/UpgradeHttpServletRequest.java | 12 +++++- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java index f028132af0a..16351aa533f 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketOverHTTP2Test.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InterruptedIOException; import java.net.ConnectException; import java.net.URI; +import java.nio.channels.ClosedChannelException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.function.Function; @@ -45,6 +46,7 @@ import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -61,6 +63,7 @@ import org.eclipse.jetty.websocket.client.WebSocketClient; import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.servlet.internal.UpgradeHttpServletRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -234,7 +237,8 @@ public class WebSocketOverHTTP2Test assertTrue(wsEndPoint.closeLatch.await(5, TimeUnit.SECONDS)); } - @Test void testWebSocketConnectPortDoesNotExist() throws Exception + @Test + public void testWebSocketConnectPortDoesNotExist() throws Exception { startServer(); startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); @@ -250,7 +254,8 @@ public class WebSocketOverHTTP2Test assertThat(cause.getMessage(), containsStringIgnoringCase("Connection refused")); } - @Test void testWebSocketNotFound() throws Exception + @Test + public void testWebSocketNotFound() throws Exception { startServer(); startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); @@ -266,7 +271,8 @@ public class WebSocketOverHTTP2Test assertThat(cause.getMessage(), containsStringIgnoringCase("Unexpected HTTP Response Status Code: 501")); } - @Test void testNotNegotiated() throws Exception + @Test + public void testNotNegotiated() throws Exception { startServer(); startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); @@ -282,7 +288,8 @@ public class WebSocketOverHTTP2Test assertThat(cause.getMessage(), containsStringIgnoringCase("Unexpected HTTP Response Status Code: 503")); } - @Test void testThrowFromCreator() throws Exception + @Test + public void testThrowFromCreator() throws Exception { startServer(); startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); @@ -302,6 +309,22 @@ public class WebSocketOverHTTP2Test assertThat(cause.getMessage(), containsStringIgnoringCase("Unexpected HTTP Response Status Code: 500")); } + @Test + public void testServerConnectionClose() throws Exception + { + startServer(); + startClient(clientConnector -> new ClientConnectionFactoryOverHTTP2.H2(new HTTP2Client(clientConnector))); + + EventSocket wsEndPoint = new EventSocket(); + URI uri = URI.create("ws://localhost:" + connector.getLocalPort() + "/ws/connectionClose"); + + ExecutionException failure = Assertions.assertThrows(ExecutionException.class, () -> + wsClient.connect(wsEndPoint, uri).get(5, TimeUnit.SECONDS)); + + Throwable cause = failure.getCause(); + assertThat(cause, instanceOf(ClosedChannelException.class)); + } + private static class TestJettyWebSocketServlet extends JettyWebSocketServlet { @Override @@ -313,6 +336,13 @@ public class WebSocketOverHTTP2Test { throw new RuntimeException("throwing from creator"); }); + factory.addMapping("/ws/connectionClose", (request, response) -> + { + UpgradeHttpServletRequest servletRequest = (UpgradeHttpServletRequest)request.getHttpServletRequest(); + Request baseRequest = servletRequest.getBaseRequest(); + baseRequest.getHttpChannel().getEndPoint().close(); + return new EchoSocket(); + }); } } } diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/internal/UpgradeHttpServletRequest.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/internal/UpgradeHttpServletRequest.java index 85fa5b968e6..5d13c47b74e 100644 --- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/internal/UpgradeHttpServletRequest.java +++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/internal/UpgradeHttpServletRequest.java @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.TreeMap; import javax.servlet.AsyncContext; import javax.servlet.DispatcherType; @@ -55,6 +56,7 @@ public class UpgradeHttpServletRequest implements HttpServletRequest { private static final String UNSUPPORTED_WITH_WEBSOCKET_UPGRADE = "Feature unsupported with a Upgraded to WebSocket HttpServletRequest"; + private final Request baseRequest; private final ServletContext context; private final DispatcherType dispatcher; private final String method; @@ -110,8 +112,9 @@ public class UpgradeHttpServletRequest implements HttpServletRequest remoteUser = httpRequest.getRemoteUser(); principal = httpRequest.getUserPrincipal(); - authentication = Request.getBaseRequest(httpRequest).getAuthentication(); - scope = Request.getBaseRequest(httpRequest).getUserIdentityScope(); + baseRequest = Objects.requireNonNull(Request.getBaseRequest(httpRequest)); + authentication = baseRequest.getAuthentication(); + scope = baseRequest.getUserIdentityScope(); Enumeration headerNames = httpRequest.getHeaderNames(); while (headerNames.hasMoreElements()) @@ -278,6 +281,11 @@ public class UpgradeHttpServletRequest implements HttpServletRequest return session; } + public Request getBaseRequest() + { + return baseRequest; + } + @Override public String getRequestedSessionId() { From ec2ad2099e8cbf6d9a1874346bab6a5b017161b0 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Mon, 25 Nov 2019 11:57:19 +1100 Subject: [PATCH 27/77] Issue #4351 Lazy servlet init is not atomic Signed-off-by: Jan Bartel --- .../eclipse/jetty/servlet/ServletHolder.java | 17 +- .../jetty/servlet/InitServletTest.java | 152 ++++++++++++++++++ 2 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java index db8a0295ab0..a344566a453 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java @@ -470,21 +470,16 @@ public class ServletHolder extends Holder implements UserIdentity.Scope public Servlet getServlet() throws ServletException { - Servlet servlet = _servlet; - if (servlet == null) + synchronized (this) { - synchronized (this) + if (_servlet == null && isRunning()) { - servlet = _servlet; - if (servlet == null && isRunning()) - { - if (getHeldClass() != null) - initServlet(); - servlet = _servlet; - } + if (getHeldClass() != null) + initServlet(); } } - return servlet; + + return _servlet; } /** diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java new file mode 100644 index 00000000000..d9bd87e8450 --- /dev/null +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java @@ -0,0 +1,152 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.servlet; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.client.api.Result; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.NetworkConnector; +import org.eclipse.jetty.server.Server; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.array; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class InitServletTest +{ + + public static class DemoServlet extends HttpServlet + { + AtomicInteger initCount = new AtomicInteger(); + + @Override + public void init() throws ServletException + { + super.init(); + try + { + //Make the initialization last a little while so + //other request can run + Thread.sleep(5000); + } + catch (InterruptedException e) + { + throw new ServletException(e); + } + //check the servlet hasn't been initialized before + int val = initCount.addAndGet(1); + assertThat(val, Matchers.equalTo(1)); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + if (initCount.get() != 1) + { + resp.sendError(500, "Servlet not initialized!"); + } + } + } + + private static class AsyncResponseListener implements Response.CompleteListener + { + private CountDownLatch resultsLatch; + private Integer[] results; + private AtomicInteger index = new AtomicInteger(); + + public AsyncResponseListener(int count) + { + resultsLatch = new CountDownLatch(count); + results = new Integer[count]; + } + + public void onComplete(Result result) + { + results[index.getAndAdd(1)] = result.getResponse().getStatus(); + resultsLatch.countDown(); + } + + public void awaitCompletion() throws InterruptedException + { + assertTrue(resultsLatch.await(60L, TimeUnit.SECONDS)); + } + + public Integer[] getResults() + { + return results; + } + } + + @Test + public void testServletInitialization() throws Exception + { + Server server = new Server(0); + ServletContextHandler context = new ServletContextHandler(server, "/"); + server.setHandler(context); + //add a lazily instantiated servlet + context.addServlet(new ServletHolder(DemoServlet.class), "/*"); + server.start(); + final int port = ((NetworkConnector)server.getConnectors()[0]).getLocalPort(); + HttpClient client = new HttpClient(); + try + { + client.start(); + + //Expect 2 responses + final AsyncResponseListener l = new AsyncResponseListener(2); + + //req1 + Request r1 = client.newRequest("http://localhost:" + port + "/r1"); + r1.method(HttpMethod.GET).send(l); + + //Need to give 1st request a head start before request2 + Thread.sleep(1000); + + //req2 + Request r2 = client.newRequest("http://localhost:" + port + "/r2"); + r2.method(HttpMethod.GET).send(l); + + l.awaitCompletion(); + + assertThat(l.getResults(), is(array(equalTo(HttpStatus.OK_200), equalTo(HttpStatus.OK_200)))); + } + finally + { + client.stop(); + server.stop(); + } + } +} From 3b7400b3f74d1a89437ef751c56da86b14bdda72 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Mon, 25 Nov 2019 16:09:39 +1000 Subject: [PATCH 28/77] rerunFailingTestsCount only for Jenkins Signed-off-by: olivier lamy --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1526f01c761..45111e03915 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 1.3 ${project.build.directory}/local-repo src/it/settings.xml - 3 + 0 @@ -1347,6 +1347,7 @@ ci ${env.GLOBAL_MVN_SETTINGS} + 3 aggregates/jetty-all From f0a3d465ec0d8311e4bfc16164a7f83cb712b77a Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 26 Nov 2019 08:43:11 +1100 Subject: [PATCH 29/77] Issue #4351 Changes post review. Signed-off-by: Jan Bartel --- .../eclipse/jetty/servlet/ServletHolder.java | 2 +- .../jetty/servlet/InitServletTest.java | 31 +++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java index a344566a453..decacb58fdf 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java @@ -621,7 +621,7 @@ public class ServletHolder extends Holder implements UserIdentity.Scope ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext()); /* Set the webapp's classpath for Jasper */ - ch.setAttribute("org.apache.catalina.jspgetHeldClass()path", ch.getClassPath()); + ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath()); /* Set up other classpath attribute */ if ("?".equals(getInitParameter("classpath"))) diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java index d9bd87e8450..66362223a77 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java @@ -47,7 +47,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class InitServletTest { - public static class DemoServlet extends HttpServlet { AtomicInteger initCount = new AtomicInteger(); @@ -66,14 +65,14 @@ public class InitServletTest { throw new ServletException(e); } - //check the servlet hasn't been initialized before - int val = initCount.addAndGet(1); - assertThat(val, Matchers.equalTo(1)); + initCount.addAndGet(1); } @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + //Check that the init() method has been totally finished (by another request) before + //the servlet service() method is called. if (initCount.get() != 1) { resp.sendError(500, "Servlet not initialized!"); @@ -83,14 +82,15 @@ public class InitServletTest private static class AsyncResponseListener implements Response.CompleteListener { + private CountDownLatch resultsLatch; private Integer[] results; private AtomicInteger index = new AtomicInteger(); - public AsyncResponseListener(int count) + public AsyncResponseListener(CountDownLatch resultsLatch, Integer[] results) { - resultsLatch = new CountDownLatch(count); - results = new Integer[count]; + this.resultsLatch = resultsLatch; + this.results = results; } public void onComplete(Result result) @@ -103,11 +103,6 @@ public class InitServletTest { assertTrue(resultsLatch.await(60L, TimeUnit.SECONDS)); } - - public Integer[] getResults() - { - return results; - } } @Test @@ -119,29 +114,31 @@ public class InitServletTest //add a lazily instantiated servlet context.addServlet(new ServletHolder(DemoServlet.class), "/*"); server.start(); - final int port = ((NetworkConnector)server.getConnectors()[0]).getLocalPort(); + int port = ((NetworkConnector)server.getConnectors()[0]).getLocalPort(); HttpClient client = new HttpClient(); try { client.start(); //Expect 2 responses - final AsyncResponseListener l = new AsyncResponseListener(2); + CountDownLatch resultsLatch = new CountDownLatch(2); + Integer[] results = new Integer[2]; + AsyncResponseListener l = new AsyncResponseListener(resultsLatch, results); - //req1 + //req1: should initialize servlet Request r1 = client.newRequest("http://localhost:" + port + "/r1"); r1.method(HttpMethod.GET).send(l); //Need to give 1st request a head start before request2 Thread.sleep(1000); - //req2 + //req2: should see servlet fully initialized by request1 Request r2 = client.newRequest("http://localhost:" + port + "/r2"); r2.method(HttpMethod.GET).send(l); l.awaitCompletion(); - assertThat(l.getResults(), is(array(equalTo(HttpStatus.OK_200), equalTo(HttpStatus.OK_200)))); + assertThat(results, is(array(equalTo(HttpStatus.OK_200), equalTo(HttpStatus.OK_200)))); } finally { From 5bc6593337893a6e78f56361ac029964e43a9b8c Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 26 Nov 2019 11:03:41 +1100 Subject: [PATCH 30/77] Issue #4351 Found simpler test Signed-off-by: Jan Bartel --- .../jetty/servlet/InitServletTest.java | 149 ------------------ .../jetty/servlet/ServletHolderTest.java | 89 +++++++++++ 2 files changed, 89 insertions(+), 149 deletions(-) delete mode 100644 jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java deleted file mode 100644 index 66362223a77..00000000000 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java +++ /dev/null @@ -1,149 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 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.servlet; - -import java.io.IOException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.client.api.Response; -import org.eclipse.jetty.client.api.Result; -import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.server.NetworkConnector; -import org.eclipse.jetty.server.Server; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.array; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class InitServletTest -{ - public static class DemoServlet extends HttpServlet - { - AtomicInteger initCount = new AtomicInteger(); - - @Override - public void init() throws ServletException - { - super.init(); - try - { - //Make the initialization last a little while so - //other request can run - Thread.sleep(5000); - } - catch (InterruptedException e) - { - throw new ServletException(e); - } - initCount.addAndGet(1); - } - - @Override - public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - //Check that the init() method has been totally finished (by another request) before - //the servlet service() method is called. - if (initCount.get() != 1) - { - resp.sendError(500, "Servlet not initialized!"); - } - } - } - - private static class AsyncResponseListener implements Response.CompleteListener - { - - private CountDownLatch resultsLatch; - private Integer[] results; - private AtomicInteger index = new AtomicInteger(); - - public AsyncResponseListener(CountDownLatch resultsLatch, Integer[] results) - { - this.resultsLatch = resultsLatch; - this.results = results; - } - - public void onComplete(Result result) - { - results[index.getAndAdd(1)] = result.getResponse().getStatus(); - resultsLatch.countDown(); - } - - public void awaitCompletion() throws InterruptedException - { - assertTrue(resultsLatch.await(60L, TimeUnit.SECONDS)); - } - } - - @Test - public void testServletInitialization() throws Exception - { - Server server = new Server(0); - ServletContextHandler context = new ServletContextHandler(server, "/"); - server.setHandler(context); - //add a lazily instantiated servlet - context.addServlet(new ServletHolder(DemoServlet.class), "/*"); - server.start(); - int port = ((NetworkConnector)server.getConnectors()[0]).getLocalPort(); - HttpClient client = new HttpClient(); - try - { - client.start(); - - //Expect 2 responses - CountDownLatch resultsLatch = new CountDownLatch(2); - Integer[] results = new Integer[2]; - AsyncResponseListener l = new AsyncResponseListener(resultsLatch, results); - - //req1: should initialize servlet - Request r1 = client.newRequest("http://localhost:" + port + "/r1"); - r1.method(HttpMethod.GET).send(l); - - //Need to give 1st request a head start before request2 - Thread.sleep(1000); - - //req2: should see servlet fully initialized by request1 - Request r2 = client.newRequest("http://localhost:" + port + "/r2"); - r2.method(HttpMethod.GET).send(l); - - l.awaitCompletion(); - - assertThat(results, is(array(equalTo(HttpStatus.OK_200), equalTo(HttpStatus.OK_200)))); - } - finally - { - client.stop(); - server.stop(); - } - } -} diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHolderTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHolderTest.java index c2c5b43dc6e..8b0abaec424 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHolderTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHolderTest.java @@ -20,10 +20,16 @@ package org.eclipse.jetty.servlet; import java.util.Collections; import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import javax.servlet.UnavailableException; import javax.servlet.http.HttpServlet; +import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.log.StacklessLogging; @@ -42,6 +48,89 @@ public class ServletHolderTest { public static class FakeServlet extends HttpServlet { + public AtomicInteger initCount = new AtomicInteger(); + + @Override + public void init() throws ServletException + { + super.init(); + try + { + //Make the initialization last a little while so + //other request can run + Thread.sleep(1000); + } + catch (InterruptedException e) + { + throw new ServletException(e); + } + initCount.addAndGet(1); + } + } + + @Test + public void testServletInitAtomic() throws Exception + { + Server server = new Server(); + ServletContextHandler context = new ServletContextHandler(); + final ServletHolder holder = new ServletHolder(Source.EMBEDDED); + holder.setHeldClass(FakeServlet.class); + holder.setName("Fake"); + context.addServlet(holder, "/fake/*"); + server.setHandler(context); + server.start(); + + final AtomicInteger t1Count = new AtomicInteger(); + final AtomicInteger t2Count = new AtomicInteger(); + final CountDownLatch t1Latch = new CountDownLatch(1); + final CountDownLatch t2Latch = new CountDownLatch(1); + + //Test that 2 calls to holder.getServlet are atomic - only + //one should call servlet.init() and the other should be + //held waiting until that fully finishes. + Thread t1 = new Thread() + { + public void run() + { + try + { + FakeServlet s = (FakeServlet)holder.getServlet(); + t1Count.set(s.initCount.get()); + t1Latch.countDown(); + } + catch (ServletException e) + { + fail(e); + } + } + }; + + Thread t2 = new Thread() + { + public void run() + { + try + { + FakeServlet s = (FakeServlet)holder.getServlet(); + t2Count.set(s.initCount.get()); + t2Latch.countDown(); + } + catch (ServletException e) + { + fail(e); + } + } + }; + + t1.start(); + Thread.sleep(500); + t2.start(); + + t1Latch.await(10L, TimeUnit.SECONDS); + t2Latch.await(10L, TimeUnit.SECONDS); + + assertEquals(1, t1Count.get()); + assertEquals(1, t2Count.get()); } @Test From efe76ff2e0816f79fdaf0bd0fb444f466625f40d Mon Sep 17 00:00:00 2001 From: Lachlan Date: Tue, 26 Nov 2019 14:51:40 +1100 Subject: [PATCH 31/77] Issue #4152 - fragment outgoing frames before the ExtensionStack (#4232) * Added FragmentingFlusher to abstract the fragmentation of frames. Signed-off-by: Lachlan Roberts * Handle failure case of Fragmenting Flusher Signed-off-by: Lachlan Roberts * Fragment outgoing frames before the ExtensionStack Signed-off-by: Lachlan Roberts * update javadoc Signed-off-by: Lachlan Roberts * separate frame size validation for incoming and outgoing frames Signed-off-by: Lachlan Roberts * fix test Signed-off-by: Lachlan Roberts * reimplement FragmentingFlusher with the new TransformingFlusher Signed-off-by: Lachlan Roberts --- .../core/internal/FragmentExtension.java | 170 ++---------------- .../core/internal/FragmentingFlusher.java | 109 +++++++++++ .../core/internal/WebSocketCoreSession.java | 102 ++++------- .../websocket/core/AutoFragmentTest.java | 45 ++++- .../core/ParsePayloadLengthTest.java | 1 + 5 files changed, 202 insertions(+), 225 deletions(-) create mode 100644 jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentExtension.java index cf2ed8cacbc..5f481d800d4 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentExtension.java @@ -18,18 +18,13 @@ package org.eclipse.jetty.websocket.core.internal; -import java.nio.ByteBuffer; -import java.util.ArrayDeque; -import java.util.Queue; - import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.IteratingCallback; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.AbstractExtension; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.Frame; -import org.eclipse.jetty.websocket.core.OpCode; +import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.WebSocketComponents; /** @@ -39,9 +34,20 @@ public class FragmentExtension extends AbstractExtension { private static final Logger LOG = Log.getLogger(FragmentExtension.class); - private final Queue entries = new ArrayDeque<>(); - private final IteratingCallback flusher = new Flusher(); - private int maxLength; + private final FragmentingFlusher flusher; + private final FrameHandler.Configuration configuration = new FrameHandler.ConfigurationHolder(); + + public FragmentExtension() + { + flusher = new FragmentingFlusher(configuration) + { + @Override + void forwardFrame(Frame frame, Callback callback, boolean batch) + { + nextOutgoingFrame(frame, callback, batch); + } + }; + } @Override public String getName() @@ -58,154 +64,14 @@ public class FragmentExtension extends AbstractExtension @Override public void sendFrame(Frame frame, Callback callback, boolean batch) { - ByteBuffer payload = frame.getPayload(); - int length = payload != null ? payload.remaining() : 0; - if (OpCode.isControlFrame(frame.getOpCode()) || maxLength <= 0 || length <= maxLength) - { - nextOutgoingFrame(frame, callback, batch); - return; - } - - FrameEntry entry = new FrameEntry(frame, callback, batch); - if (LOG.isDebugEnabled()) - LOG.debug("Queuing {}", entry); - offerEntry(entry); - flusher.iterate(); + flusher.sendFrame(frame, callback, batch); } @Override public void init(ExtensionConfig config, WebSocketComponents components) { super.init(config, components); - maxLength = config.getParameter("maxLength", -1); - } - - private void offerEntry(FrameEntry entry) - { - synchronized (this) - { - entries.offer(entry); - } - } - - private FrameEntry pollEntry() - { - synchronized (this) - { - return entries.poll(); - } - } - - private class Flusher extends IteratingCallback implements Callback - { - private FrameEntry current; - private boolean finished = true; - - @Override - protected Action process() throws Exception - { - if (finished) - { - current = pollEntry(); - LOG.debug("Processing {}", current); - if (current == null) - return Action.IDLE; - fragment(current, true); - } - else - { - fragment(current, false); - } - return Action.SCHEDULED; - } - - private void fragment(FrameEntry entry, boolean first) - { - Frame frame = entry.frame; - ByteBuffer payload = frame.getPayload(); - int remaining = payload.remaining(); - int length = Math.min(remaining, maxLength); - finished = length == remaining; - - boolean continuation = (frame.getOpCode() == OpCode.CONTINUATION) || !first; - Frame fragment = new Frame(continuation ? OpCode.CONTINUATION : frame.getOpCode()); - boolean fin = frame.isFin() && finished; - fragment.setFin(fin); - - int limit = payload.limit(); - int newLimit = payload.position() + length; - payload.limit(newLimit); - ByteBuffer payloadFragment = payload.slice(); - payload.limit(limit); - fragment.setPayload(payloadFragment); - if (LOG.isDebugEnabled()) - LOG.debug("Fragmented {}->{}", frame, fragment); - payload.position(newLimit); - - nextOutgoingFrame(fragment, this, entry.batch); - } - - @Override - protected void onCompleteSuccess() - { - // This IteratingCallback never completes. - } - - @Override - protected void onCompleteFailure(Throwable x) - { - // This IteratingCallback never fails. - // The callback are those provided by WriteCallback (implemented - // below) and even in case of writeFailed() we call succeeded(). - } - - @Override - public void succeeded() - { - // Notify first then call succeeded(), otherwise - // write callbacks may be invoked out of order. - notifyCallbackSuccess(current.callback); - super.succeeded(); - } - - @Override - public void failed(Throwable cause) - { - // Notify first, the call succeeded() to drain the queue. - // We don't want to call failed(x) because that will put - // this flusher into a final state that cannot be exited, - // and the failure of a frame may not mean that the whole - // connection is now invalid. - notifyCallbackFailure(current.callback, cause); - succeeded(); - } - - private void notifyCallbackSuccess(Callback callback) - { - try - { - if (callback != null) - callback.succeeded(); - } - catch (Throwable x) - { - if (LOG.isDebugEnabled()) - LOG.debug("Exception while notifying success of callback " + callback, x); - } - } - - private void notifyCallbackFailure(Callback callback, Throwable failure) - { - try - { - if (callback != null) - callback.failed(failure); - } - catch (Throwable x) - { - if (LOG.isDebugEnabled()) - LOG.debug("Exception while notifying failure of callback " + callback, x); - } - } + int maxLength = config.getParameter("maxLength", -1); + configuration.setMaxFrameSize(maxLength); } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java new file mode 100644 index 00000000000..a42745b318a --- /dev/null +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java @@ -0,0 +1,109 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.core.internal; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.core.Frame; +import org.eclipse.jetty.websocket.core.FrameHandler.Configuration; +import org.eclipse.jetty.websocket.core.OpCode; + +/** + * Used to split large data frames into multiple frames below the maxFrameSize. + * Control frames and dataFrames smaller than the maxFrameSize will be forwarded + * directly to {@link #forwardFrame(Frame, Callback, boolean)}. + */ +public abstract class FragmentingFlusher extends TransformingFlusher +{ + private static final Logger LOG = Log.getLogger(FragmentingFlusher.class); + private final Configuration configuration; + private FrameEntry current; + + public FragmentingFlusher(Configuration configuration) + { + this.configuration = configuration; + } + + abstract void forwardFrame(Frame frame, Callback callback, boolean batch); + + @Override + protected boolean onFrame(Frame frame, Callback callback, boolean batch) + { + long maxFrameSize = configuration.getMaxFrameSize(); + if (frame.isControlFrame() || maxFrameSize <= 0 || frame.getPayloadLength() <= maxFrameSize) + { + forwardFrame(frame, callback, batch); + return true; + } + + current = new FrameEntry(frame, callback, batch); + boolean finished = fragment(callback, true); + if (finished) + current = null; + return finished; + } + + @Override + protected boolean transform(Callback callback) + { + boolean finished = fragment(callback, false); + if (finished) + current = null; + return finished; + } + + private boolean fragment(Callback callback, boolean first) + { + Frame frame = current.frame; + ByteBuffer payload = frame.getPayload(); + int remaining = payload.remaining(); + long maxFrameSize = configuration.getMaxFrameSize(); + int fragmentSize = (int)Math.min(remaining, maxFrameSize); + + boolean continuation = (frame.getOpCode() == OpCode.CONTINUATION) || !first; + Frame fragment = new Frame(continuation ? OpCode.CONTINUATION : frame.getOpCode()); + boolean finished = (maxFrameSize <= 0 || remaining <= maxFrameSize); + fragment.setFin(frame.isFin() && finished); + + // If we don't need to fragment just forward with original payload. + if (finished) + { + fragment.setPayload(frame.getPayload()); + forwardFrame(fragment, callback, current.batch); + return true; + } + + // Slice the fragmented payload from the buffer. + int limit = payload.limit(); + int newLimit = payload.position() + fragmentSize; + payload.limit(newLimit); + ByteBuffer payloadFragment = payload.slice(); + payload.limit(limit); + fragment.setPayload(payloadFragment); + payload.position(newLimit); + if (LOG.isDebugEnabled()) + LOG.debug("Fragmented {}->{}", frame, fragment); + + forwardFrame(fragment, callback, current.batch); + return false; + } +} diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java index 0bf46245bb7..d10c3b3faab 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java @@ -23,16 +23,13 @@ import java.net.SocketAddress; import java.net.SocketTimeoutException; import java.net.URI; import java.time.Duration; -import java.util.ArrayDeque; import java.util.List; import java.util.Map; -import java.util.Queue; import java.util.concurrent.Executor; import java.util.concurrent.TimeoutException; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.IteratingCallback; import org.eclipse.jetty.util.Utf8Appendable; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.log.Log; @@ -44,6 +41,7 @@ import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.Frame; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.core.IncomingFrames; +import org.eclipse.jetty.websocket.core.MessageTooLargeException; import org.eclipse.jetty.websocket.core.OpCode; import org.eclipse.jetty.websocket.core.OutgoingFrames; import org.eclipse.jetty.websocket.core.ProtocolException; @@ -67,7 +65,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe private final FrameHandler handler; private final Negotiated negotiated; private final boolean demanding; - private final Flusher flusher = new Flusher(); + private final Flusher flusher = new Flusher(this); private WebSocketConnection connection; private boolean autoFragment = WebSocketConstants.DEFAULT_AUTO_FRAGMENT; @@ -100,6 +98,10 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe { assertValidFrame(frame); + // Validate frame size. + if (maxFrameSize > 0 && frame.getPayloadLength() > maxFrameSize) + throw new MessageTooLargeException("Cannot handle payload lengths larger than " + maxFrameSize); + // Assert Incoming Frame Behavior Required by RFC-6455 / Section 5.1 switch (behavior) { @@ -132,6 +134,10 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe { assertValidFrame(frame); + // Validate frame size (allowed to be over max frame size if autoFragment is true). + if (!autoFragment && maxFrameSize > 0 && frame.getPayloadLength() > maxFrameSize) + throw new MessageTooLargeException("Cannot handle payload lengths larger than " + maxFrameSize); + /* * RFC 6455 Section 5.5.1 * close frame payload is specially formatted which is checked in CloseStatus @@ -155,7 +161,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe if (!OpCode.isKnown(frame.getOpCode())) throw new ProtocolException("Unknown opcode: " + frame.getOpCode()); - int payloadLength = (frame.getPayload() == null) ? 0 : frame.getPayload().remaining(); + int payloadLength = frame.getPayloadLength(); if (frame.isControlFrame()) { if (!frame.isFin()) @@ -520,26 +526,22 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe try { - synchronized (flusher) + if (LOG.isDebugEnabled()) + LOG.debug("sendFrame({}, {}, {})", frame, callback, batch); + + boolean closeConnection = sessionState.onOutgoingFrame(frame); + if (closeConnection) { - if (LOG.isDebugEnabled()) - LOG.debug("sendFrame({}, {}, {})", frame, callback, batch); + Callback closeConnectionCallback = Callback.from( + () -> closeConnection(sessionState.getCloseStatus(), callback), + t -> closeConnection(sessionState.getCloseStatus(), Callback.from(callback, t))); - boolean closeConnection = sessionState.onOutgoingFrame(frame); - if (closeConnection) - { - Callback closeConnectionCallback = Callback.from( - () -> closeConnection(sessionState.getCloseStatus(), callback), - t -> closeConnection(sessionState.getCloseStatus(), Callback.from(callback, t))); - - flusher.queue.offer(new FrameEntry(frame, closeConnectionCallback, false)); - } - else - { - flusher.queue.offer(new FrameEntry(frame, callback, batch)); - } + flusher.sendFrame(frame, closeConnectionCallback, false); + } + else + { + flusher.sendFrame(frame, callback, batch); } - flusher.iterate(); } catch (Throwable t) { @@ -562,11 +564,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe @Override public void flush(Callback callback) { - synchronized (flusher) - { - flusher.queue.offer(new FrameEntry(FrameFlusher.FLUSH_FRAME, callback, false)); - } - flusher.iterate(); + flusher.sendFrame(FrameFlusher.FLUSH_FRAME, callback, false); } @Override @@ -791,57 +789,17 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe handler); } - private class Flusher extends IteratingCallback + private class Flusher extends FragmentingFlusher { - private final Queue queue = new ArrayDeque<>(); - FrameEntry entry; - - @Override - protected Action process() throws Throwable + public Flusher(FrameHandler.Configuration configuration) { - synchronized (this) - { - entry = queue.poll(); - } - if (entry == null) - return Action.IDLE; - - negotiated.getExtensions().sendFrame(entry.frame, this, entry.batch); - return Action.SCHEDULED; + super(configuration); } @Override - public void succeeded() + void forwardFrame(Frame frame, Callback callback, boolean batch) { - entry.callback.succeeded(); - super.succeeded(); - } - - @Override - protected void onCompleteFailure(Throwable cause) - { - entry.callback.failed(cause); - Queue entries; - synchronized (this) - { - entries = new ArrayDeque<>(queue); - queue.clear(); - } - entries.forEach(e -> failEntry(cause, e)); - } - - private void failEntry(Throwable cause, FrameEntry e) - { - try - { - e.callback.failed(cause); - } - catch (Throwable x) - { - if (cause != x) - cause.addSuppressed(x); - LOG.warn(cause); - } + negotiated.getExtensions().sendFrame(frame, callback, batch); } } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java index cc85606a94d..7356e4fed6f 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java @@ -71,7 +71,50 @@ public class AutoFragmentTest } @Test - public void testAutoFragmentToMaxFrameSize() throws Exception + public void testOutgoingAutoFragmentToMaxFrameSize() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture connect = client.connect(clientHandler, serverUri); + connect.get(5, TimeUnit.SECONDS); + + // Turn off fragmentation on the server. + assertTrue(serverHandler.open.await(5, TimeUnit.SECONDS)); + serverHandler.coreSession.setMaxFrameSize(0); + serverHandler.coreSession.setAutoFragment(false); + + // Set the client to fragment to the maxFrameSize. + int maxFrameSize = 30; + clientHandler.coreSession.setMaxFrameSize(maxFrameSize); + clientHandler.coreSession.setAutoFragment(true); + + // Send a message which is too large. + int size = maxFrameSize * 2; + byte[] message = new byte[size]; + Arrays.fill(message, 0, size, (byte)'X'); + clientHandler.coreSession.sendFrame(new Frame(OpCode.BINARY, BufferUtil.toBuffer(message)), Callback.NOOP, false); + + // We should not receive any frames larger than the max frame size. + // So our message should be split into two frames. + Frame frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); + assertNotNull(frame); + assertThat(frame.getOpCode(), is(OpCode.BINARY)); + assertThat(frame.getPayloadLength(), is(maxFrameSize)); + assertThat(frame.isFin(), is(false)); + + // Second frame should be final and contain rest of the data. + frame = serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS); + assertNotNull(frame); + assertThat(frame.getOpCode(), is(OpCode.CONTINUATION)); + assertThat(frame.getPayloadLength(), is(maxFrameSize)); + assertThat(frame.isFin(), is(true)); + + clientHandler.sendClose(); + assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + } + + @Test + public void testIncomingAutoFragmentToMaxFrameSize() throws Exception { TestFrameHandler clientHandler = new TestFrameHandler(); CompletableFuture connect = client.connect(clientHandler, serverUri); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParsePayloadLengthTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParsePayloadLengthTest.java index fd5693a4bee..2b85c9c1d68 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParsePayloadLengthTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParsePayloadLengthTest.java @@ -62,6 +62,7 @@ public class ParsePayloadLengthTest public void testPayloadLength(int size, String description) throws InterruptedException { ParserCapture capture = new ParserCapture(); + capture.getCoreSession().setMaxFrameSize(0); ByteBuffer raw = BufferUtil.allocate(size + Generator.MAX_HEADER_LENGTH); BufferUtil.clearToFill(raw); From 19e740451aae89781b8be330b2ff15d3f79c390c Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 26 Nov 2019 14:15:23 -0600 Subject: [PATCH 32/77] Bump up jetty-version-maven-plugin to version 2.6 Signed-off-by: Joakim Erdfelt --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4e1d34b8b94..823efffd7d0 100644 --- a/pom.xml +++ b/pom.xml @@ -666,7 +666,7 @@ org.eclipse.jetty.toolchain jetty-version-maven-plugin - 2.5 + 2.6 org.jacoco From c291df54631664336c176b8336b9e254fdbfffdf Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 27 Nov 2019 07:04:57 +1000 Subject: [PATCH 33/77] we do not want dependencies definied as range even for test transitive dependencies Signed-off-by: olivier lamy --- jetty-client/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index 7aaf7e28be3..0f9b142193f 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -124,6 +124,13 @@ 1.1.1 test + + + net.minidev + json-smart + 2.3 + test + org.slf4j slf4j-simple From dc1a3384b0b10480d69233f46aec7adb3c26f8d8 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 27 Nov 2019 07:18:59 +1000 Subject: [PATCH 34/77] ooops typo Signed-off-by: olivier lamy --- jetty-client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index 0f9b142193f..2ce37df4a5a 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -129,7 +129,7 @@ net.minidev json-smart 2.3 - test + test org.slf4j From 57e5cd8a4d1e5fe0eb77443139253a6878f9c3e7 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 26 Nov 2019 16:44:13 -0600 Subject: [PATCH 35/77] Updating to version 10.0.0.alpha1 --- VERSION.txt | 166 +++++++++++++++++- aggregates/jetty-all/pom.xml | 2 +- apache-jsp/pom.xml | 2 +- apache-jstl/pom.xml | 2 +- build-resources/pom.xml | 2 +- examples/async-rest/async-rest-jar/pom.xml | 2 +- examples/async-rest/async-rest-server/pom.xml | 2 +- examples/async-rest/async-rest-webapp/pom.xml | 2 +- examples/async-rest/pom.xml | 2 +- examples/embedded/pom.xml | 2 +- examples/pom.xml | 2 +- jetty-alpn/jetty-alpn-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-server/pom.xml | 2 +- jetty-alpn/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-ant/pom.xml | 2 +- jetty-bom/pom.xml | 136 +++++++------- jetty-cdi/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-documentation/pom.xml | 2 +- jetty-fcgi/fcgi-client/pom.xml | 2 +- jetty-fcgi/fcgi-server/pom.xml | 2 +- jetty-fcgi/pom.xml | 2 +- .../jetty-gcloud-session-manager/pom.xml | 2 +- jetty-gcloud/pom.xml | 2 +- jetty-hazelcast/pom.xml | 2 +- jetty-home/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-http2/http2-client/pom.xml | 2 +- jetty-http2/http2-common/pom.xml | 2 +- jetty-http2/http2-hpack/pom.xml | 2 +- .../http2-http-client-transport/pom.xml | 2 +- jetty-http2/http2-server/pom.xml | 2 +- jetty-http2/pom.xml | 2 +- jetty-infinispan/infinispan-common/pom.xml | 2 +- .../infinispan-embedded-query/pom.xml | 2 +- jetty-infinispan/infinispan-embedded/pom.xml | 2 +- .../infinispan-remote-query/pom.xml | 2 +- jetty-infinispan/infinispan-remote/pom.xml | 2 +- jetty-infinispan/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaas/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jspc-maven-plugin/pom.xml | 2 +- jetty-maven-plugin/pom.xml | 2 +- .../jetty-memcached-sessions/pom.xml | 2 +- jetty-memcached/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-openid/pom.xml | 2 +- jetty-osgi/jetty-osgi-alpn/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-context/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-fragment/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-server/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-webapp/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-proxy/pom.xml | 2 +- jetty-quickstart/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-runner/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spring/pom.xml | 2 +- jetty-start/pom.xml | 2 +- .../jetty-unixsocket-client/pom.xml | 2 +- .../jetty-unixsocket-common/pom.xml | 2 +- .../jetty-unixsocket-server/pom.xml | 2 +- jetty-unixsocket/pom.xml | 2 +- jetty-util-ajax/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- .../javax-websocket-client/pom.xml | 2 +- .../javax-websocket-common/pom.xml | 2 +- .../javax-websocket-server/pom.xml | 2 +- jetty-websocket/javax-websocket-tests/pom.xml | 2 +- jetty-websocket/jetty-websocket-api/pom.xml | 2 +- .../jetty-websocket-client/pom.xml | 2 +- .../jetty-websocket-common/pom.xml | 2 +- .../jetty-websocket-server/pom.xml | 2 +- jetty-websocket/jetty-websocket-tests/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-websocket/websocket-core/pom.xml | 2 +- jetty-websocket/websocket-servlet/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- tests/jetty-http-tools/pom.xml | 2 +- tests/jetty-jmh/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-distribution/pom.xml | 2 +- tests/test-http-client-transport/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-jmx/jmx-webapp-it/pom.xml | 2 +- tests/test-jmx/jmx-webapp/pom.xml | 2 +- tests/test-jmx/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-quickstart/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- .../test-sessions/test-file-sessions/pom.xml | 2 +- .../test-gcloud-sessions/pom.xml | 2 +- .../test-hazelcast-sessions/pom.xml | 2 +- .../test-infinispan-sessions/pom.xml | 2 +- .../test-sessions/test-jdbc-sessions/pom.xml | 2 +- .../test-memcached-sessions/pom.xml | 2 +- .../test-mongodb-sessions/pom.xml | 2 +- .../test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- .../test-cdi-common-webapp/pom.xml | 2 +- tests/test-webapps/test-felix-webapp/pom.xml | 2 +- tests/test-webapps/test-http2-webapp/pom.xml | 2 +- tests/test-webapps/test-jaas-webapp/pom.xml | 2 +- tests/test-webapps/test-jetty-webapp/pom.xml | 2 +- tests/test-webapps/test-jndi-webapp/pom.xml | 2 +- .../test-webapps/test-mock-resources/pom.xml | 2 +- .../test-webapps/test-owb-cdi-webapp/pom.xml | 2 +- tests/test-webapps/test-proxy-webapp/pom.xml | 2 +- tests/test-webapps/test-servlet-spec/pom.xml | 2 +- .../test-container-initializer/pom.xml | 2 +- .../test-spec-webapp/pom.xml | 2 +- .../test-web-fragment/pom.xml | 2 +- tests/test-webapps/test-simple-webapp/pom.xml | 2 +- .../test-webapps/test-webapp-rfc2616/pom.xml | 2 +- .../test-webapps/test-weld-cdi-webapp/pom.xml | 2 +- 138 files changed, 367 insertions(+), 207 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 10e46ad5b8d..546c444d602 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,7 +1,167 @@ -jetty-10.0.0-SNAPSHOT +jetty-10.0.0.alpha1 - 26 November 2019 + + 97 Permanent UnavailableException thrown during servlet request handling + should cause servlet destroy + + 137 Support OAuth + + 155 No way to set keystore for JSR 356 websocket clients, needed for SSL + client authentication + + 250 Implement HTTP CONNECT for HTTP/2 + + 995 UrlEncoded.encodeString should skip more characters + + 1036 Allow easy configuration of Scheduler-Threads and name them more + appropriate + + 1485 Add systemd service file + + 1743 Refactor jetty maven plugin goals to be more orthogonal + + 2266 Jetty maven plugin reload is triggered each time the + `scanIntervalSeconds` pass + + 2340 Remove raw ServletHandler usage examples from documentation + + 2429 Review HttpClient backpressure semantic + + 2578 Use addEventListener(EventListener listener) + + 2709 current default for headerCacheSize is not large enough for many + requests + + 2815 hpack fields are opaque octets + + 3040 Allow RFC6265 Cookies to include optional SameSite attribute. + + 3083 The ini-template for jetty.console-capture.dir does not match the + default value + + 3106 Websocket connection stats and request stats + + 3558 Error notifications can be received after a successful websocket close + + 3601 HTTP2 stall on reset streams + + 3705 Review ClientUpgradeRequest exception handling + + 3734 websocket suspend when input closed + + 3747 Make Jetty Demo work with JPMS + + 3787 Jetty client sometimes returns EOFException instead of + SSLHandshakeException on certificate errors. + + 3804 Weld/CDI XML backwards compat? + + 3806 Error Page handling Async race with ProxyServlet + + 3822 trustAll will not work on some servers + + 3829 Avoid sending empty trailer frames for http/2 responses + + 3840 Byte-range request performance problems with large files + + 3856 Different behaviour with maxFormContentSize=0 if Content-Length header + is present/missing + + 3863 Enforce use of SNI + + 3869 Update to ASM 7.2 for jdk 13 + + 3872 Review exposure of JavaxWebSocketServletContainerInitializer + + 3876 WebSocketPartialListener is only called for initial frames, not for + continuation frames + + 3884 @WebSocket without @OnWebSocketMessage handler fails when receiving a + continuation frame + + 3888 BufferUtil.toBuffer(Resource resource,boolean direct) does not like + large (4G+) Resources + + 3906 Fix for #3840 breaks Path encapsulation in PathResource + + 3913 Clustered HttpSession IllegalStateException: Invalid for read + + 3929 Deadlock between new HTTP2Connection() and Server.stop() + + 3936 Race condition when modifying session + sendRedirect() + + 3940 Double initialization of Log + + 3951 Consider adding demand API to HTTP/2 + + 3952 Server configuration for direct/heap ByteBuffers + + 3956 Remove and warn on use of illegal HTTP/2 response headers + + 3957 CustomRequestLog bad usage of MethodHandles.lookup() + + 3960 Fix HttpConfiguration copy constructor + + 3964 Improve efficiency of listeners + + 3968 WebSocket sporadic ReadPendingException using suspend/resume + + 3969 X-Forwarded-Port header customization isn't possible + + 3978 HTTP/2 fixes for robustly handling abnormal traffic and resource + exhaustion + + 3983 JarFileResource incorrectly lists the contents of directories with + spaces + + 3985 Improve lenient Cookie parsing + + 3989 Inform custom ManagedSelector of dead selector via optional + onFailedSelect() + + 4000 Add SameFileAliasChecker to help with FileSystem static file access + normalization on Mac and Windows + + 4003 Quickstart broken in jetty-10 + + 4007 Getting NullPointerException while trying to run jetty start.run on + Windows + + 4009 ServletContextHandler setSecurityHandler broke handler chain + + 4020 Revert WebSocket ExtensionFactory change to interface + + 4022 Servlet which is added by ServletRegistration can't be started + + 4025 Provide more write-through behaviours for DefaultSessionCache + + 4027 Ensure AbstractSessionDataStore cannot be used unless it is started + + 4033 Ignore bad percent encodings in paths during + URIUtil.equalsIgnoreEncodings() + + 4047 Gracefully stopped Jetty not flushing all response data + + 4048 Multiple values in X-Forwarded-Port throw NumberFormatException + + 4057 NullPointerException in o.e.j.h.HttpFields + + 4058 Review Locker + + 4064 java.lang.NullPointerException initializing embedded servlet + + 4075 Do not fail on servlet-mapping with url-pattern /On* + + 4076 Restarting quickstarted webapp throws IllegalStateException: + ServletContainerInitializersStarter already exists + + 4082 Debug logging causes NullPointerException in client + + 4084 Use of HttpConfiguration.setBlockingTimeout(long) in jetty.xml produces + warning on jetty-home startup + + 4096 Thread in ReservedThreadExecutor does not exit when stopped + + 4104 Frames are sent through ExtensionStack even if WebSocket Session is + closed + + 4105 QueuedThreadPool increased thread usage and no idle thread decay + + 4113 HttpClient fails with JDK 13 and TLS 1.3 + + 4115 Drop HTTP/2 pseudo headers + + 4121 QueuedThreadPool should support ThreadFactory behaviors + + 4122 QueuedThreadPool should reset thread interrupted on failed run + + 4124 Run websocket autobahn tests with jetty and javax apis instead of just + with core. + + 4128 OpenIdCredentials can't decode JWT ID token + + 4132 Should be possible to use OIDC without metadata + + 4138 OpenID module should use HttpClient instead of HttpURLConnection + + 4141 ClassCastException with non-async Servlet + async Filter + + HttpServletRequestWrapper + + 4142 Configurable HTTP/2 RateControl + + 4144 Naked cast to Request should be avoided + + 4150 Module org.eclipse.jetty.alpn.client not found, required by + org.eclipse.jetty.proxy + + 4152 WebSocket autoFragment does not fragment based on maxFrameSize + + 4156 IllegalStateException when forwarding to jsp with new session + + 4161 Regression: EofException: request lifecycle violation + + 4170 Client-side alias selection based on SSLEngine + + 4173 NullPointerException warning in log from WebInfConfiguration after + upgrade + + 4174 ConcurrentModificationException when stopping jetty:run-war + + 4176 Should not set header if sendError has been called + + 4177 Configure HTTP proxy with SslContextFactory + + 4179 Improve HttpChannel$SendCallback references for GC + + 4183 Jetty considers bootstrap injected class to be a "server class" + + 4188 Spin in HttpOutput.close + + 4190 Jetty hangs after thread blocked in SharedBlockingCallback.block() + called by HttpOutput.close + + 4191 Increase GzipHandler minGzipSize default value + + 4193 InetAccessHandler - new includeConnectors/excludeConnectors not quite + correct anymore + + 4201 Throw SSLHandshakeException in case of TLS handshake failures + + 4203 Some Transfer-Encoding and Content-Length combinations do not result in + expected 400 Bad Request + + 4204 Transfer-Encoding behavior does not follow RFC7230 + + 4208 304 response with Content-Length fails, not conform to RFC7230 + + 4209 Unused TLS connection is not closed in Java 11 + + 4217 SslConnection.DecryptedEnpoint.flush eternal busy loop + + 4222 Major/Minor Version wrong (jetty 10 is servlet 4) + + 4227 First authorization request produced by OIDC module fails due to + inclusion of sessionid + + 4236 clean up redirect code calculation for OpenIdAuthenticator + + 4237 simplify openid module configuration + + 4240 CGI form post results in 500 response if no character encoding + + 4243 ErrorHandler produces invalid json error response + + 4247 Cookie security attributes are going to mandated by Google Chrome + + 4248 Websocket client UpgradeListener never reports success + + 4251 Http 2.0 clients cannot upgrade protocol + + 4258 RateControl should be per-connection + + 4264 Spring Boot BasicErrorController no longer invoked + + 4265 HttpChannel SEND_ERROR should use ErrorHandler.doError() + + 4277 Reading streamed gzipped body never terminates + + 4279 Regression: ResponseWriter#close blocks indefinitely + + 4282 Review HttpParser handling in case of no content + + 4283 Wrong package for OpenJDK8ClientALPNProcessor + + 4284 Possible NullPointerException in Main.java when stopped from command + line + + 4287 Move getUriLastPathSegment(URI uri) to URIUtil + + 4296 Unable to create WebSocket connect if the query string of the URL has % + symbol. + + 4301 Demand beforeContent is not forwarded + + 4305 Jetty server ALPN shall alert fatal no_application_protocol if no + client application protocol is supported + + 4325 Deprecate SniX509ExtendedKeyManager constructor without + SslContextFactory$Server + + 4334 Better test ErrorHandler changes + + 4342 OpenID module cannot create HttpClient in Jetty 10 -jetty-10.0.0-alpha0 - 11 July - 2019 +jetty-10.0.0-alpha0 + 113 Add support for NCSA Extended Log File Format + 114 Bring back overlay deployer + 132 ClientConnector abstraction diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index dd6db29871e..69f48d4452a 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../../pom.xml 4.0.0 diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml index 4220f823685..4ed3de9b272 100644 --- a/apache-jsp/pom.xml +++ b/apache-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/apache-jstl/pom.xml b/apache-jstl/pom.xml index df81b031bca..e830ac9faaa 100644 --- a/apache-jstl/pom.xml +++ b/apache-jstl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 apache-jstl diff --git a/build-resources/pom.xml b/build-resources/pom.xml index 57d2d612ef4..3a35b4acad3 100644 --- a/build-resources/pom.xml +++ b/build-resources/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.eclipse.jetty build-resources - 10.0.0-SNAPSHOT + 10.0.0.alpha1 Jetty :: Build Resources diff --git a/examples/async-rest/async-rest-jar/pom.xml b/examples/async-rest/async-rest-jar/pom.xml index b9fedd3572c..7fc8f29fd50 100644 --- a/examples/async-rest/async-rest-jar/pom.xml +++ b/examples/async-rest/async-rest-jar/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/examples/async-rest/async-rest-server/pom.xml b/examples/async-rest/async-rest-server/pom.xml index 6e08928ad41..adab2fec8a5 100644 --- a/examples/async-rest/async-rest-server/pom.xml +++ b/examples/async-rest/async-rest-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/examples/async-rest/async-rest-webapp/pom.xml b/examples/async-rest/async-rest-webapp/pom.xml index fc23683060f..1238f508833 100644 --- a/examples/async-rest/async-rest-webapp/pom.xml +++ b/examples/async-rest/async-rest-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/examples/async-rest/pom.xml b/examples/async-rest/pom.xml index 062104027f5..c340f87ffdb 100644 --- a/examples/async-rest/pom.xml +++ b/examples/async-rest/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml index cd11566a15b..61a3d969dbb 100644 --- a/examples/embedded/pom.xml +++ b/examples/embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index 5d4660605ab..bc351f5e826 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-alpn/jetty-alpn-client/pom.xml b/jetty-alpn/jetty-alpn-client/pom.xml index db889380de8..f460b9a1de6 100644 --- a/jetty-alpn/jetty-alpn-client/pom.xml +++ b/jetty-alpn/jetty-alpn-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-alpn-client diff --git a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml index e2863c7231f..98a76976405 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml index b12dd062925..8d8a60783cd 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-client/pom.xml b/jetty-alpn/jetty-alpn-java-client/pom.xml index fb8b4a1bb2a..f9d8acd4891 100644 --- a/jetty-alpn/jetty-alpn-java-client/pom.xml +++ b/jetty-alpn/jetty-alpn-java-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-server/pom.xml b/jetty-alpn/jetty-alpn-java-server/pom.xml index 918725febde..0175e60f6f4 100644 --- a/jetty-alpn/jetty-alpn-java-server/pom.xml +++ b/jetty-alpn/jetty-alpn-java-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-alpn/jetty-alpn-server/pom.xml b/jetty-alpn/jetty-alpn-server/pom.xml index 0cf6794b9fa..3f0a6602647 100644 --- a/jetty-alpn/jetty-alpn-server/pom.xml +++ b/jetty-alpn/jetty-alpn-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-alpn-server diff --git a/jetty-alpn/pom.xml b/jetty-alpn/pom.xml index 7263f3de469..a3788d63cc4 100644 --- a/jetty-alpn/pom.xml +++ b/jetty-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-alpn-parent diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 8eadf27f3b3..eab8297a0c3 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml index b66fb07eaeb..dc2b477ddf2 100644 --- a/jetty-ant/pom.xml +++ b/jetty-ant/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-ant diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index fcdf3fe7d3d..7fdcaf59c45 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -9,7 +9,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 @@ -53,341 +53,341 @@ org.eclipse.jetty apache-jsp - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty apache-jstl - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-alpn-client - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-alpn-java-client - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-alpn-java-server - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-alpn-conscrypt-client - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-alpn-conscrypt-server - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-alpn-server - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-annotations - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-ant - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-client - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-deploy - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-distribution - 10.0.0-SNAPSHOT + 10.0.0.alpha1 zip org.eclipse.jetty jetty-distribution - 10.0.0-SNAPSHOT + 10.0.0.alpha1 tar.gz org.eclipse.jetty.fcgi fcgi-client - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.fcgi fcgi-server - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.gcloud jetty-gcloud-session-manager - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-home - 10.0.0-SNAPSHOT + 10.0.0.alpha1 zip org.eclipse.jetty jetty-home - 10.0.0-SNAPSHOT + 10.0.0.alpha1 tar.gz org.eclipse.jetty jetty-http - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.http2 http2-client - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.http2 http2-common - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.http2 http2-hpack - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.http2 http2-http-client-transport - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.http2 http2-server - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-http-spi - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty infinispan-common - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty infinispan-remote-query - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty infinispan-embedded-query - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-hazelcast - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-io - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-jaas - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-jaspi - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-jmx - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-jndi - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.memcached jetty-memcached-sessions - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-nosql - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.osgi jetty-osgi-boot - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.osgi jetty-osgi-boot-jsp - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.osgi jetty-osgi-boot-warurl - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.osgi jetty-httpservice - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-plus - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-proxy - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-quickstart - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-rewrite - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-security - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-openid - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-server - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-servlet - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-servlets - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-spring - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-unixsocket-common - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-unixsocket-client - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-unixsocket-server - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-util - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-util-ajax - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-webapp - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.websocket javax-websocket-client - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.websocket javax-websocket-server - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.websocket javax-websocket-common - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.websocket jetty-websocket-api - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.websocket jetty-websocket-client - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.websocket jetty-websocket-common - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.websocket jetty-websocket-server - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.websocket websocket-servlet - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty.websocket websocket-core - 10.0.0-SNAPSHOT + 10.0.0.alpha1 org.eclipse.jetty jetty-xml - 10.0.0-SNAPSHOT + 10.0.0.alpha1 diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index 21cd915ce5d..15016c20bf9 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 org.eclipse.jetty diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index 6947c91b5d7..d03ce067126 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index 45376093155..0889dc50fd7 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index f6b2843d79e..d1fd7f728b2 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-distribution diff --git a/jetty-documentation/pom.xml b/jetty-documentation/pom.xml index 5a0e52c7510..8e56f84948d 100644 --- a/jetty-documentation/pom.xml +++ b/jetty-documentation/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-fcgi/fcgi-client/pom.xml b/jetty-fcgi/fcgi-client/pom.xml index 9d4ec739d53..55f2a22ee8a 100644 --- a/jetty-fcgi/fcgi-client/pom.xml +++ b/jetty-fcgi/fcgi-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-fcgi/fcgi-server/pom.xml b/jetty-fcgi/fcgi-server/pom.xml index 742fcf5a9fe..bda551cef9f 100644 --- a/jetty-fcgi/fcgi-server/pom.xml +++ b/jetty-fcgi/fcgi-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-fcgi/pom.xml b/jetty-fcgi/pom.xml index 6ea9032ffb8..0cff4a925be 100644 --- a/jetty-fcgi/pom.xml +++ b/jetty-fcgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index 4e2c291d2b7..74da97c7e87 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-gcloud/pom.xml b/jetty-gcloud/pom.xml index 02487b97ac0..2e07b51b576 100644 --- a/jetty-gcloud/pom.xml +++ b/jetty-gcloud/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index 5ed59343949..2aa94444c4c 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index 08acbaa9a8b..bc62a1ab969 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-home diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index 2fb509cd685..dc34bb280d5 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index a5071238200..df62ae498a6 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-http2/http2-client/pom.xml b/jetty-http2/http2-client/pom.xml index e7753a1fc70..1857861b66a 100644 --- a/jetty-http2/http2-client/pom.xml +++ b/jetty-http2/http2-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-http2/http2-common/pom.xml b/jetty-http2/http2-common/pom.xml index 995a3b8d592..2a523e1e18e 100644 --- a/jetty-http2/http2-common/pom.xml +++ b/jetty-http2/http2-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-http2/http2-hpack/pom.xml b/jetty-http2/http2-hpack/pom.xml index 6f154432a16..d46574a56a5 100644 --- a/jetty-http2/http2-hpack/pom.xml +++ b/jetty-http2/http2-hpack/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-http2/http2-http-client-transport/pom.xml b/jetty-http2/http2-http-client-transport/pom.xml index da589baa10d..628ccc411e5 100644 --- a/jetty-http2/http2-http-client-transport/pom.xml +++ b/jetty-http2/http2-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index 702a6204ab0..1e811d8b06e 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-http2/pom.xml b/jetty-http2/pom.xml index 7a32c9046ab..000a9a9ca6f 100644 --- a/jetty-http2/pom.xml +++ b/jetty-http2/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-infinispan/infinispan-common/pom.xml b/jetty-infinispan/infinispan-common/pom.xml index 751d63b19e2..c5b1f7356a1 100644 --- a/jetty-infinispan/infinispan-common/pom.xml +++ b/jetty-infinispan/infinispan-common/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 infinispan-common diff --git a/jetty-infinispan/infinispan-embedded-query/pom.xml b/jetty-infinispan/infinispan-embedded-query/pom.xml index 87964ce79ce..83b2c7397b7 100644 --- a/jetty-infinispan/infinispan-embedded-query/pom.xml +++ b/jetty-infinispan/infinispan-embedded-query/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 infinispan-embedded-query diff --git a/jetty-infinispan/infinispan-embedded/pom.xml b/jetty-infinispan/infinispan-embedded/pom.xml index 04349f164a6..cab7f4fe067 100644 --- a/jetty-infinispan/infinispan-embedded/pom.xml +++ b/jetty-infinispan/infinispan-embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 infinispan-embedded diff --git a/jetty-infinispan/infinispan-remote-query/pom.xml b/jetty-infinispan/infinispan-remote-query/pom.xml index fb3ecfcb25d..fa06f6b1136 100644 --- a/jetty-infinispan/infinispan-remote-query/pom.xml +++ b/jetty-infinispan/infinispan-remote-query/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 infinispan-remote-query diff --git a/jetty-infinispan/infinispan-remote/pom.xml b/jetty-infinispan/infinispan-remote/pom.xml index 6d20c59c0be..58052f05dc9 100644 --- a/jetty-infinispan/infinispan-remote/pom.xml +++ b/jetty-infinispan/infinispan-remote/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 infinispan-remote diff --git a/jetty-infinispan/pom.xml b/jetty-infinispan/pom.xml index d693cbf4819..61f05888c80 100644 --- a/jetty-infinispan/pom.xml +++ b/jetty-infinispan/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index ef53deabed6..dce0dfe85d7 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-io diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index 6662377bb20..c055bbc9349 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index 0d16ccb6974..0071ab176d7 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index 639ef6aaa5f..d89fa37c385 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 2442dd6f097..a1c2af2e943 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 2e260fffbe6..5ba80741c22 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-jspc-maven-plugin diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index d6b9d10d0d9..a7258240c99 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-maven-plugin diff --git a/jetty-memcached/jetty-memcached-sessions/pom.xml b/jetty-memcached/jetty-memcached-sessions/pom.xml index ca218096903..84d659aa252 100644 --- a/jetty-memcached/jetty-memcached-sessions/pom.xml +++ b/jetty-memcached/jetty-memcached-sessions/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.memcached memcached-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-memcached/pom.xml b/jetty-memcached/pom.xml index a672294c41a..f290be436d7 100644 --- a/jetty-memcached/pom.xml +++ b/jetty-memcached/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 1d3f099c606..1241eda6e3f 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-nosql diff --git a/jetty-openid/pom.xml b/jetty-openid/pom.xml index ac1cb6bebb6..6e49c279d7c 100644 --- a/jetty-openid/pom.xml +++ b/jetty-openid/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-osgi/jetty-osgi-alpn/pom.xml b/jetty-osgi/jetty-osgi-alpn/pom.xml index 0d18a508cd8..43224298b68 100644 --- a/jetty-osgi/jetty-osgi-alpn/pom.xml +++ b/jetty-osgi/jetty-osgi-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index b8ebe520cab..b830e751ea3 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-osgi-boot-jsp diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index 025d737ea11..b99bcb5f158 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index 443fe24c095..2e95e601d62 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-osgi-boot diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index 7bc6e744093..0621cabd69b 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-httpservice diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index ecc03573a34..d7dd17e561f 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index 9deafe864a6..54d8918b3ea 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 test-jetty-osgi-context diff --git a/jetty-osgi/test-jetty-osgi-fragment/pom.xml b/jetty-osgi/test-jetty-osgi-fragment/pom.xml index e43a76e22a4..5487a3d2889 100644 --- a/jetty-osgi/test-jetty-osgi-fragment/pom.xml +++ b/jetty-osgi/test-jetty-osgi-fragment/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-server/pom.xml b/jetty-osgi/test-jetty-osgi-server/pom.xml index a213793c34f..7ac9263b37d 100644 --- a/jetty-osgi/test-jetty-osgi-server/pom.xml +++ b/jetty-osgi/test-jetty-osgi-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 test-jetty-osgi-server diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index cb9ff9bc9a6..2e670746de2 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 4dd970f92dd..cafcb5f85bb 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml 4.0.0 diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index 045a9e76671..14d8688856f 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml index d8964411ccd..450a391b775 100644 --- a/jetty-proxy/pom.xml +++ b/jetty-proxy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml index 1134d4ff73e..ae13d4cf228 100644 --- a/jetty-quickstart/pom.xml +++ b/jetty-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 76b9b905bc1..d0c8e8060ad 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml index 03dac2de706..598c3b969f8 100644 --- a/jetty-runner/pom.xml +++ b/jetty-runner/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-runner diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index ed204799803..770bfecedb9 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index af6e5b32e47..ab4a4abb31a 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index c705a9f382c..f4bd7efdce0 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 6854e8c3eb8..4e671e64872 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml index 459c4b98159..9cae4348e19 100644 --- a/jetty-spring/pom.xml +++ b/jetty-spring/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index 062db44d4f3..59a84138828 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-start diff --git a/jetty-unixsocket/jetty-unixsocket-client/pom.xml b/jetty-unixsocket/jetty-unixsocket-client/pom.xml index fc66c9e5dcc..0fbd7fc10e1 100644 --- a/jetty-unixsocket/jetty-unixsocket-client/pom.xml +++ b/jetty-unixsocket/jetty-unixsocket-client/pom.xml @@ -3,7 +3,7 @@ jetty-unixsocket org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-unixsocket/jetty-unixsocket-common/pom.xml b/jetty-unixsocket/jetty-unixsocket-common/pom.xml index 1667195b810..13858c810c2 100644 --- a/jetty-unixsocket/jetty-unixsocket-common/pom.xml +++ b/jetty-unixsocket/jetty-unixsocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-unixsocket - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-unixsocket/jetty-unixsocket-server/pom.xml b/jetty-unixsocket/jetty-unixsocket-server/pom.xml index 0ba25d24bbc..9822b132fc6 100644 --- a/jetty-unixsocket/jetty-unixsocket-server/pom.xml +++ b/jetty-unixsocket/jetty-unixsocket-server/pom.xml @@ -3,7 +3,7 @@ jetty-unixsocket org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-unixsocket/pom.xml b/jetty-unixsocket/pom.xml index b4e4c4d2b16..c543ff407b6 100644 --- a/jetty-unixsocket/pom.xml +++ b/jetty-unixsocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-util-ajax/pom.xml b/jetty-util-ajax/pom.xml index 6fcf4b1e14f..914d2add266 100644 --- a/jetty-util-ajax/pom.xml +++ b/jetty-util-ajax/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-util-ajax diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index a0188a09aab..55ed068b72e 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index 350b35c7d73..92f21417989 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/javax-websocket-client/pom.xml b/jetty-websocket/javax-websocket-client/pom.xml index bdbaea8cb23..371621cb314 100644 --- a/jetty-websocket/javax-websocket-client/pom.xml +++ b/jetty-websocket/javax-websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/javax-websocket-common/pom.xml b/jetty-websocket/javax-websocket-common/pom.xml index 9fd8f573acd..c3f940e0674 100644 --- a/jetty-websocket/javax-websocket-common/pom.xml +++ b/jetty-websocket/javax-websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/javax-websocket-server/pom.xml b/jetty-websocket/javax-websocket-server/pom.xml index c4d3ee0e98d..ffb0060ac8b 100644 --- a/jetty-websocket/javax-websocket-server/pom.xml +++ b/jetty-websocket/javax-websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/javax-websocket-tests/pom.xml b/jetty-websocket/javax-websocket-tests/pom.xml index 0976122edee..d90b0af2a2c 100644 --- a/jetty-websocket/javax-websocket-tests/pom.xml +++ b/jetty-websocket/javax-websocket-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/jetty-websocket-api/pom.xml b/jetty-websocket/jetty-websocket-api/pom.xml index a2486c5739b..901ceb6ef89 100644 --- a/jetty-websocket/jetty-websocket-api/pom.xml +++ b/jetty-websocket/jetty-websocket-api/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/jetty-websocket-client/pom.xml b/jetty-websocket/jetty-websocket-client/pom.xml index caeae04bc80..d14de68e6cf 100644 --- a/jetty-websocket/jetty-websocket-client/pom.xml +++ b/jetty-websocket/jetty-websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/jetty-websocket-common/pom.xml b/jetty-websocket/jetty-websocket-common/pom.xml index bd6c711d235..bcdc2b0fc35 100644 --- a/jetty-websocket/jetty-websocket-common/pom.xml +++ b/jetty-websocket/jetty-websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/jetty-websocket-server/pom.xml b/jetty-websocket/jetty-websocket-server/pom.xml index 80303e8640b..c99720136c3 100644 --- a/jetty-websocket/jetty-websocket-server/pom.xml +++ b/jetty-websocket/jetty-websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/jetty-websocket-tests/pom.xml b/jetty-websocket/jetty-websocket-tests/pom.xml index bfd1689a5d7..6896a584c41 100644 --- a/jetty-websocket/jetty-websocket-tests/pom.xml +++ b/jetty-websocket/jetty-websocket-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index e4c5bbe5837..0620ef3c17f 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/websocket-core/pom.xml b/jetty-websocket/websocket-core/pom.xml index 60879dcaa46..ddc1c10d7b7 100644 --- a/jetty-websocket/websocket-core/pom.xml +++ b/jetty-websocket/websocket-core/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml index f803f732e80..ad00e9255cf 100644 --- a/jetty-websocket/websocket-servlet/pom.xml +++ b/jetty-websocket/websocket-servlet/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index be891ef3f1b..60f3d184096 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index 3622e377ec1..9657b446973 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 Jetty :: Project The Eclipse Jetty Project pom diff --git a/tests/jetty-http-tools/pom.xml b/tests/jetty-http-tools/pom.xml index 47e7cd69a86..dab57aaf1e7 100644 --- a/tests/jetty-http-tools/pom.xml +++ b/tests/jetty-http-tools/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/tests/jetty-jmh/pom.xml b/tests/jetty-jmh/pom.xml index bc4827112ef..320355a75c1 100644 --- a/tests/jetty-jmh/pom.xml +++ b/tests/jetty-jmh/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/tests/pom.xml b/tests/pom.xml index 75cd4504512..b34ca7666d8 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml org.eclipse.jetty.tests diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml index 27fcd0dab1e..9833c8fa008 100644 --- a/tests/test-distribution/pom.xml +++ b/tests/test-distribution/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/tests/test-http-client-transport/pom.xml b/tests/test-http-client-transport/pom.xml index 84d9d7de5b9..35bc10a3930 100644 --- a/tests/test-http-client-transport/pom.xml +++ b/tests/test-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index 4168685fe5e..110edf217b9 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 test-integration diff --git a/tests/test-jmx/jmx-webapp-it/pom.xml b/tests/test-jmx/jmx-webapp-it/pom.xml index 6543bcc1d1e..00b6a0a7437 100644 --- a/tests/test-jmx/jmx-webapp-it/pom.xml +++ b/tests/test-jmx/jmx-webapp-it/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-jmx-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 jmx-webapp-it diff --git a/tests/test-jmx/jmx-webapp/pom.xml b/tests/test-jmx/jmx-webapp/pom.xml index 38445f8c86f..501ba1cb387 100644 --- a/tests/test-jmx/jmx-webapp/pom.xml +++ b/tests/test-jmx/jmx-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-jmx-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 jmx-webapp war diff --git a/tests/test-jmx/pom.xml b/tests/test-jmx/pom.xml index d64b3e8ef45..8b95a50f9e8 100644 --- a/tests/test-jmx/pom.xml +++ b/tests/test-jmx/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 test-jmx-parent diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index 9c521147677..31c9c3d7c0a 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index 8e52029caac..1ae87bb8441 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml 4.0.0 diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 25a0746b134..6066ada2e05 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-file-sessions/pom.xml b/tests/test-sessions/test-file-sessions/pom.xml index d79168404c6..16519039a35 100644 --- a/tests/test-sessions/test-file-sessions/pom.xml +++ b/tests/test-sessions/test-file-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-file-sessions Jetty Tests :: Sessions :: File diff --git a/tests/test-sessions/test-gcloud-sessions/pom.xml b/tests/test-sessions/test-gcloud-sessions/pom.xml index 6b5ae8f14da..ac1ce3887ab 100644 --- a/tests/test-sessions/test-gcloud-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-gcloud-sessions Jetty Tests :: Sessions :: GCloud diff --git a/tests/test-sessions/test-hazelcast-sessions/pom.xml b/tests/test-sessions/test-hazelcast-sessions/pom.xml index fa96894adad..e1579369076 100644 --- a/tests/test-sessions/test-hazelcast-sessions/pom.xml +++ b/tests/test-sessions/test-hazelcast-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-hazelcast-sessions Jetty Tests :: Sessions :: Hazelcast diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index c414f7f5848..f192067383a 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-infinispan-sessions Jetty Tests :: Sessions :: Infinispan diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index ae24d2bd6b1..0c42830037c 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-memcached-sessions/pom.xml b/tests/test-sessions/test-memcached-sessions/pom.xml index 60ac2f524da..8bce98c18c1 100644 --- a/tests/test-sessions/test-memcached-sessions/pom.xml +++ b/tests/test-sessions/test-memcached-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-memcached-sessions Jetty Tests :: Sessions :: Memcached diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index 1c1f7718f8e..abda788df35 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index a423ae8630a..018c9fe7844 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index cf05e8a0007..3e48a7f60d2 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml test-webapps-parent diff --git a/tests/test-webapps/test-cdi-common-webapp/pom.xml b/tests/test-webapps/test-cdi-common-webapp/pom.xml index ab8cff68cdc..ef2d4c4c358 100644 --- a/tests/test-webapps/test-cdi-common-webapp/pom.xml +++ b/tests/test-webapps/test-cdi-common-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/tests/test-webapps/test-felix-webapp/pom.xml b/tests/test-webapps/test-felix-webapp/pom.xml index 1b1e57e46a2..9ea42404f91 100644 --- a/tests/test-webapps/test-felix-webapp/pom.xml +++ b/tests/test-webapps/test-felix-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/tests/test-webapps/test-http2-webapp/pom.xml b/tests/test-webapps/test-http2-webapp/pom.xml index 7db6283bc92..638769a7452 100644 --- a/tests/test-webapps/test-http2-webapp/pom.xml +++ b/tests/test-webapps/test-http2-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml index 563dc6b029b..4259e8dec31 100644 --- a/tests/test-webapps/test-jaas-webapp/pom.xml +++ b/tests/test-webapps/test-jaas-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-jaas-webapp Jetty Tests :: WebApp :: JAAS diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index 76eff45b4f9..b775a857c8e 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml index 08fce22680d..a8f067f093b 100644 --- a/tests/test-webapps/test-jndi-webapp/pom.xml +++ b/tests/test-webapps/test-jndi-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-jndi-webapp Jetty Tests :: WebApp :: JNDI diff --git a/tests/test-webapps/test-mock-resources/pom.xml b/tests/test-webapps/test-mock-resources/pom.xml index aa30708c191..6f5e6ce5799 100644 --- a/tests/test-webapps/test-mock-resources/pom.xml +++ b/tests/test-webapps/test-mock-resources/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 Jetty Tests :: WebApp :: Mock Resources test-mock-resources diff --git a/tests/test-webapps/test-owb-cdi-webapp/pom.xml b/tests/test-webapps/test-owb-cdi-webapp/pom.xml index 95a25c5a629..7da90fab653 100644 --- a/tests/test-webapps/test-owb-cdi-webapp/pom.xml +++ b/tests/test-webapps/test-owb-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml index efd499fa3d0..1aba855b5f3 100644 --- a/tests/test-webapps/test-proxy-webapp/pom.xml +++ b/tests/test-webapps/test-proxy-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-servlet-spec/pom.xml b/tests/test-webapps/test-servlet-spec/pom.xml index e1baa56d470..a6ba7d798c4 100644 --- a/tests/test-webapps/test-servlet-spec/pom.xml +++ b/tests/test-webapps/test-servlet-spec/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-servlet-spec-parent Jetty Tests :: Spec Test WebApp :: Parent diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml index 8beeaf3a468..e5c2e69a690 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-container-initializer jar diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml index bada431d66d..87efaca4834 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 Jetty Tests :: Webapps :: Spec Webapp test-spec-webapp diff --git a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml index 8a0fed27d72..0ba3c010711 100644 --- a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar diff --git a/tests/test-webapps/test-simple-webapp/pom.xml b/tests/test-webapps/test-simple-webapp/pom.xml index 9c31f9dcde5..bb9d9829fd8 100644 --- a/tests/test-webapps/test-simple-webapp/pom.xml +++ b/tests/test-webapps/test-simple-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index ddec187e699..9241c8a0b58 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 diff --git a/tests/test-webapps/test-weld-cdi-webapp/pom.xml b/tests/test-webapps/test-weld-cdi-webapp/pom.xml index 1c00b20c05f..41a9e01208d 100644 --- a/tests/test-webapps/test-weld-cdi-webapp/pom.xml +++ b/tests/test-webapps/test-weld-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0-SNAPSHOT + 10.0.0.alpha1 4.0.0 From a7fbe7a6bb8862d81991f756279c04ae8d692486 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 26 Nov 2019 17:22:06 -0600 Subject: [PATCH 36/77] Updating to version 10.0.0-SNAPSHOT --- VERSION.txt | 2 + aggregates/jetty-all/pom.xml | 2 +- apache-jsp/pom.xml | 2 +- apache-jstl/pom.xml | 2 +- build-resources/pom.xml | 2 +- examples/async-rest/async-rest-jar/pom.xml | 2 +- examples/async-rest/async-rest-server/pom.xml | 2 +- examples/async-rest/async-rest-webapp/pom.xml | 2 +- examples/async-rest/pom.xml | 2 +- examples/embedded/pom.xml | 2 +- examples/pom.xml | 2 +- jetty-alpn/jetty-alpn-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-server/pom.xml | 2 +- jetty-alpn/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-ant/pom.xml | 2 +- jetty-bom/pom.xml | 136 +++++++++--------- jetty-cdi/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-documentation/pom.xml | 2 +- jetty-fcgi/fcgi-client/pom.xml | 2 +- jetty-fcgi/fcgi-server/pom.xml | 2 +- jetty-fcgi/pom.xml | 2 +- .../jetty-gcloud-session-manager/pom.xml | 2 +- jetty-gcloud/pom.xml | 2 +- jetty-hazelcast/pom.xml | 2 +- jetty-home/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-http2/http2-client/pom.xml | 2 +- jetty-http2/http2-common/pom.xml | 2 +- jetty-http2/http2-hpack/pom.xml | 2 +- .../http2-http-client-transport/pom.xml | 2 +- jetty-http2/http2-server/pom.xml | 2 +- jetty-http2/pom.xml | 2 +- jetty-infinispan/infinispan-common/pom.xml | 2 +- .../infinispan-embedded-query/pom.xml | 2 +- jetty-infinispan/infinispan-embedded/pom.xml | 2 +- .../infinispan-remote-query/pom.xml | 2 +- jetty-infinispan/infinispan-remote/pom.xml | 2 +- jetty-infinispan/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaas/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jspc-maven-plugin/pom.xml | 2 +- jetty-maven-plugin/pom.xml | 2 +- .../jetty-memcached-sessions/pom.xml | 2 +- jetty-memcached/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-openid/pom.xml | 2 +- jetty-osgi/jetty-osgi-alpn/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-context/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-fragment/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-server/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-webapp/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-proxy/pom.xml | 2 +- jetty-quickstart/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-runner/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spring/pom.xml | 2 +- jetty-start/pom.xml | 2 +- .../jetty-unixsocket-client/pom.xml | 2 +- .../jetty-unixsocket-common/pom.xml | 2 +- .../jetty-unixsocket-server/pom.xml | 2 +- jetty-unixsocket/pom.xml | 2 +- jetty-util-ajax/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- .../javax-websocket-client/pom.xml | 2 +- .../javax-websocket-common/pom.xml | 2 +- .../javax-websocket-server/pom.xml | 2 +- jetty-websocket/javax-websocket-tests/pom.xml | 2 +- jetty-websocket/jetty-websocket-api/pom.xml | 2 +- .../jetty-websocket-client/pom.xml | 2 +- .../jetty-websocket-common/pom.xml | 2 +- .../jetty-websocket-server/pom.xml | 2 +- jetty-websocket/jetty-websocket-tests/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-websocket/websocket-core/pom.xml | 2 +- jetty-websocket/websocket-servlet/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- tests/jetty-http-tools/pom.xml | 2 +- tests/jetty-jmh/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-distribution/pom.xml | 2 +- tests/test-http-client-transport/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-jmx/jmx-webapp-it/pom.xml | 2 +- tests/test-jmx/jmx-webapp/pom.xml | 2 +- tests/test-jmx/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-quickstart/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- .../test-sessions/test-file-sessions/pom.xml | 2 +- .../test-gcloud-sessions/pom.xml | 2 +- .../test-hazelcast-sessions/pom.xml | 2 +- .../test-infinispan-sessions/pom.xml | 2 +- .../test-sessions/test-jdbc-sessions/pom.xml | 2 +- .../test-memcached-sessions/pom.xml | 2 +- .../test-mongodb-sessions/pom.xml | 2 +- .../test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- .../test-cdi-common-webapp/pom.xml | 2 +- tests/test-webapps/test-felix-webapp/pom.xml | 2 +- tests/test-webapps/test-http2-webapp/pom.xml | 2 +- tests/test-webapps/test-jaas-webapp/pom.xml | 2 +- tests/test-webapps/test-jetty-webapp/pom.xml | 2 +- tests/test-webapps/test-jndi-webapp/pom.xml | 2 +- .../test-webapps/test-mock-resources/pom.xml | 2 +- .../test-webapps/test-owb-cdi-webapp/pom.xml | 2 +- tests/test-webapps/test-proxy-webapp/pom.xml | 2 +- tests/test-webapps/test-servlet-spec/pom.xml | 2 +- .../test-container-initializer/pom.xml | 2 +- .../test-spec-webapp/pom.xml | 2 +- .../test-web-fragment/pom.xml | 2 +- tests/test-webapps/test-simple-webapp/pom.xml | 2 +- .../test-webapps/test-webapp-rfc2616/pom.xml | 2 +- .../test-webapps/test-weld-cdi-webapp/pom.xml | 2 +- 138 files changed, 206 insertions(+), 204 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 546c444d602..a081f756bf9 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,3 +1,5 @@ +jetty-10.0.0-SNAPSHOT + jetty-10.0.0.alpha1 - 26 November 2019 + 97 Permanent UnavailableException thrown during servlet request handling should cause servlet destroy diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index 69f48d4452a..dd6db29871e 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml index 4ed3de9b272..4220f823685 100644 --- a/apache-jsp/pom.xml +++ b/apache-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/apache-jstl/pom.xml b/apache-jstl/pom.xml index e830ac9faaa..df81b031bca 100644 --- a/apache-jstl/pom.xml +++ b/apache-jstl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 apache-jstl diff --git a/build-resources/pom.xml b/build-resources/pom.xml index 3a35b4acad3..57d2d612ef4 100644 --- a/build-resources/pom.xml +++ b/build-resources/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.eclipse.jetty build-resources - 10.0.0.alpha1 + 10.0.0-SNAPSHOT Jetty :: Build Resources diff --git a/examples/async-rest/async-rest-jar/pom.xml b/examples/async-rest/async-rest-jar/pom.xml index 7fc8f29fd50..b9fedd3572c 100644 --- a/examples/async-rest/async-rest-jar/pom.xml +++ b/examples/async-rest/async-rest-jar/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/examples/async-rest/async-rest-server/pom.xml b/examples/async-rest/async-rest-server/pom.xml index adab2fec8a5..6e08928ad41 100644 --- a/examples/async-rest/async-rest-server/pom.xml +++ b/examples/async-rest/async-rest-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/examples/async-rest/async-rest-webapp/pom.xml b/examples/async-rest/async-rest-webapp/pom.xml index 1238f508833..fc23683060f 100644 --- a/examples/async-rest/async-rest-webapp/pom.xml +++ b/examples/async-rest/async-rest-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/examples/async-rest/pom.xml b/examples/async-rest/pom.xml index c340f87ffdb..062104027f5 100644 --- a/examples/async-rest/pom.xml +++ b/examples/async-rest/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml index 61a3d969dbb..cd11566a15b 100644 --- a/examples/embedded/pom.xml +++ b/examples/embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index bc351f5e826..5d4660605ab 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-client/pom.xml b/jetty-alpn/jetty-alpn-client/pom.xml index f460b9a1de6..db889380de8 100644 --- a/jetty-alpn/jetty-alpn-client/pom.xml +++ b/jetty-alpn/jetty-alpn-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-alpn-client diff --git a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml index 98a76976405..e2863c7231f 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml index 8d8a60783cd..b12dd062925 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-client/pom.xml b/jetty-alpn/jetty-alpn-java-client/pom.xml index f9d8acd4891..fb8b4a1bb2a 100644 --- a/jetty-alpn/jetty-alpn-java-client/pom.xml +++ b/jetty-alpn/jetty-alpn-java-client/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-server/pom.xml b/jetty-alpn/jetty-alpn-java-server/pom.xml index 0175e60f6f4..918725febde 100644 --- a/jetty-alpn/jetty-alpn-java-server/pom.xml +++ b/jetty-alpn/jetty-alpn-java-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-server/pom.xml b/jetty-alpn/jetty-alpn-server/pom.xml index 3f0a6602647..0cf6794b9fa 100644 --- a/jetty-alpn/jetty-alpn-server/pom.xml +++ b/jetty-alpn/jetty-alpn-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-alpn-server diff --git a/jetty-alpn/pom.xml b/jetty-alpn/pom.xml index a3788d63cc4..7263f3de469 100644 --- a/jetty-alpn/pom.xml +++ b/jetty-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-alpn-parent diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index eab8297a0c3..8eadf27f3b3 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml index dc2b477ddf2..b66fb07eaeb 100644 --- a/jetty-ant/pom.xml +++ b/jetty-ant/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-ant diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index 7fdcaf59c45..fcdf3fe7d3d 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -9,7 +9,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT @@ -53,341 +53,341 @@ org.eclipse.jetty apache-jsp - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty apache-jstl - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-alpn-client - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-alpn-java-client - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-alpn-java-server - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-alpn-conscrypt-client - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-alpn-conscrypt-server - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-alpn-server - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-annotations - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-ant - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-client - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-deploy - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-distribution - 10.0.0.alpha1 + 10.0.0-SNAPSHOT zip org.eclipse.jetty jetty-distribution - 10.0.0.alpha1 + 10.0.0-SNAPSHOT tar.gz org.eclipse.jetty.fcgi fcgi-client - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.fcgi fcgi-server - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.gcloud jetty-gcloud-session-manager - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-home - 10.0.0.alpha1 + 10.0.0-SNAPSHOT zip org.eclipse.jetty jetty-home - 10.0.0.alpha1 + 10.0.0-SNAPSHOT tar.gz org.eclipse.jetty jetty-http - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.http2 http2-client - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.http2 http2-common - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.http2 http2-hpack - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.http2 http2-http-client-transport - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.http2 http2-server - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-http-spi - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty infinispan-common - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty infinispan-remote-query - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty infinispan-embedded-query - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-hazelcast - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-io - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-jaas - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-jaspi - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-jmx - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-jndi - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.memcached jetty-memcached-sessions - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-nosql - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.osgi jetty-osgi-boot - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.osgi jetty-osgi-boot-jsp - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.osgi jetty-osgi-boot-warurl - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.osgi jetty-httpservice - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-plus - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-proxy - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-quickstart - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-rewrite - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-security - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-openid - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-server - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-servlet - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-servlets - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-spring - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-unixsocket-common - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-unixsocket-client - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-unixsocket-server - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-util - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-util-ajax - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-webapp - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.websocket javax-websocket-client - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.websocket javax-websocket-server - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.websocket javax-websocket-common - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.websocket jetty-websocket-api - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.websocket jetty-websocket-client - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.websocket jetty-websocket-common - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.websocket jetty-websocket-server - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.websocket websocket-servlet - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty.websocket websocket-core - 10.0.0.alpha1 + 10.0.0-SNAPSHOT org.eclipse.jetty jetty-xml - 10.0.0.alpha1 + 10.0.0-SNAPSHOT diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index 15016c20bf9..21cd915ce5d 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 org.eclipse.jetty diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index d03ce067126..6947c91b5d7 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index 0889dc50fd7..45376093155 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index d1fd7f728b2..f6b2843d79e 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-distribution diff --git a/jetty-documentation/pom.xml b/jetty-documentation/pom.xml index 8e56f84948d..5a0e52c7510 100644 --- a/jetty-documentation/pom.xml +++ b/jetty-documentation/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-fcgi/fcgi-client/pom.xml b/jetty-fcgi/fcgi-client/pom.xml index 55f2a22ee8a..9d4ec739d53 100644 --- a/jetty-fcgi/fcgi-client/pom.xml +++ b/jetty-fcgi/fcgi-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-fcgi/fcgi-server/pom.xml b/jetty-fcgi/fcgi-server/pom.xml index bda551cef9f..742fcf5a9fe 100644 --- a/jetty-fcgi/fcgi-server/pom.xml +++ b/jetty-fcgi/fcgi-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-fcgi/pom.xml b/jetty-fcgi/pom.xml index 0cff4a925be..6ea9032ffb8 100644 --- a/jetty-fcgi/pom.xml +++ b/jetty-fcgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index 74da97c7e87..4e2c291d2b7 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-gcloud/pom.xml b/jetty-gcloud/pom.xml index 2e07b51b576..02487b97ac0 100644 --- a/jetty-gcloud/pom.xml +++ b/jetty-gcloud/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index 2aa94444c4c..5ed59343949 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index bc62a1ab969..08acbaa9a8b 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-home diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index dc34bb280d5..2fb509cd685 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index df62ae498a6..a5071238200 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-client/pom.xml b/jetty-http2/http2-client/pom.xml index 1857861b66a..e7753a1fc70 100644 --- a/jetty-http2/http2-client/pom.xml +++ b/jetty-http2/http2-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-common/pom.xml b/jetty-http2/http2-common/pom.xml index 2a523e1e18e..995a3b8d592 100644 --- a/jetty-http2/http2-common/pom.xml +++ b/jetty-http2/http2-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-hpack/pom.xml b/jetty-http2/http2-hpack/pom.xml index d46574a56a5..6f154432a16 100644 --- a/jetty-http2/http2-hpack/pom.xml +++ b/jetty-http2/http2-hpack/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-http-client-transport/pom.xml b/jetty-http2/http2-http-client-transport/pom.xml index 628ccc411e5..da589baa10d 100644 --- a/jetty-http2/http2-http-client-transport/pom.xml +++ b/jetty-http2/http2-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index 1e811d8b06e..702a6204ab0 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-http2/pom.xml b/jetty-http2/pom.xml index 000a9a9ca6f..7a32c9046ab 100644 --- a/jetty-http2/pom.xml +++ b/jetty-http2/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-infinispan/infinispan-common/pom.xml b/jetty-infinispan/infinispan-common/pom.xml index c5b1f7356a1..751d63b19e2 100644 --- a/jetty-infinispan/infinispan-common/pom.xml +++ b/jetty-infinispan/infinispan-common/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 infinispan-common diff --git a/jetty-infinispan/infinispan-embedded-query/pom.xml b/jetty-infinispan/infinispan-embedded-query/pom.xml index 83b2c7397b7..87964ce79ce 100644 --- a/jetty-infinispan/infinispan-embedded-query/pom.xml +++ b/jetty-infinispan/infinispan-embedded-query/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 infinispan-embedded-query diff --git a/jetty-infinispan/infinispan-embedded/pom.xml b/jetty-infinispan/infinispan-embedded/pom.xml index cab7f4fe067..04349f164a6 100644 --- a/jetty-infinispan/infinispan-embedded/pom.xml +++ b/jetty-infinispan/infinispan-embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 infinispan-embedded diff --git a/jetty-infinispan/infinispan-remote-query/pom.xml b/jetty-infinispan/infinispan-remote-query/pom.xml index fa06f6b1136..fb3ecfcb25d 100644 --- a/jetty-infinispan/infinispan-remote-query/pom.xml +++ b/jetty-infinispan/infinispan-remote-query/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 infinispan-remote-query diff --git a/jetty-infinispan/infinispan-remote/pom.xml b/jetty-infinispan/infinispan-remote/pom.xml index 58052f05dc9..6d20c59c0be 100644 --- a/jetty-infinispan/infinispan-remote/pom.xml +++ b/jetty-infinispan/infinispan-remote/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty infinispan-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 infinispan-remote diff --git a/jetty-infinispan/pom.xml b/jetty-infinispan/pom.xml index 61f05888c80..d693cbf4819 100644 --- a/jetty-infinispan/pom.xml +++ b/jetty-infinispan/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index dce0dfe85d7..ef53deabed6 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-io diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index c055bbc9349..6662377bb20 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index 0071ab176d7..0d16ccb6974 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index d89fa37c385..639ef6aaa5f 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index a1c2af2e943..2442dd6f097 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 5ba80741c22..2e260fffbe6 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-jspc-maven-plugin diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index a7258240c99..d6b9d10d0d9 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-maven-plugin diff --git a/jetty-memcached/jetty-memcached-sessions/pom.xml b/jetty-memcached/jetty-memcached-sessions/pom.xml index 84d659aa252..ca218096903 100644 --- a/jetty-memcached/jetty-memcached-sessions/pom.xml +++ b/jetty-memcached/jetty-memcached-sessions/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.memcached memcached-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-memcached/pom.xml b/jetty-memcached/pom.xml index f290be436d7..a672294c41a 100644 --- a/jetty-memcached/pom.xml +++ b/jetty-memcached/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 1241eda6e3f..1d3f099c606 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-nosql diff --git a/jetty-openid/pom.xml b/jetty-openid/pom.xml index 6e49c279d7c..ac1cb6bebb6 100644 --- a/jetty-openid/pom.xml +++ b/jetty-openid/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-osgi/jetty-osgi-alpn/pom.xml b/jetty-osgi/jetty-osgi-alpn/pom.xml index 43224298b68..0d18a508cd8 100644 --- a/jetty-osgi/jetty-osgi-alpn/pom.xml +++ b/jetty-osgi/jetty-osgi-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index b830e751ea3..b8ebe520cab 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-osgi-boot-jsp diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index b99bcb5f158..025d737ea11 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index 2e95e601d62..443fe24c095 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-osgi-boot diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index 0621cabd69b..7bc6e744093 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-httpservice diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index d7dd17e561f..ecc03573a34 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index 54d8918b3ea..9deafe864a6 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 test-jetty-osgi-context diff --git a/jetty-osgi/test-jetty-osgi-fragment/pom.xml b/jetty-osgi/test-jetty-osgi-fragment/pom.xml index 5487a3d2889..e43a76e22a4 100644 --- a/jetty-osgi/test-jetty-osgi-fragment/pom.xml +++ b/jetty-osgi/test-jetty-osgi-fragment/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-server/pom.xml b/jetty-osgi/test-jetty-osgi-server/pom.xml index 7ac9263b37d..a213793c34f 100644 --- a/jetty-osgi/test-jetty-osgi-server/pom.xml +++ b/jetty-osgi/test-jetty-osgi-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 test-jetty-osgi-server diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index 2e670746de2..cb9ff9bc9a6 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index cafcb5f85bb..4dd970f92dd 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index 14d8688856f..045a9e76671 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml index 450a391b775..d8964411ccd 100644 --- a/jetty-proxy/pom.xml +++ b/jetty-proxy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml index ae13d4cf228..1134d4ff73e 100644 --- a/jetty-quickstart/pom.xml +++ b/jetty-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index d0c8e8060ad..76b9b905bc1 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml index 598c3b969f8..03dac2de706 100644 --- a/jetty-runner/pom.xml +++ b/jetty-runner/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-runner diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index 770bfecedb9..ed204799803 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index ab4a4abb31a..af6e5b32e47 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index f4bd7efdce0..c705a9f382c 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 4e671e64872..6854e8c3eb8 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml index 9cae4348e19..459c4b98159 100644 --- a/jetty-spring/pom.xml +++ b/jetty-spring/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index 59a84138828..062db44d4f3 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-start diff --git a/jetty-unixsocket/jetty-unixsocket-client/pom.xml b/jetty-unixsocket/jetty-unixsocket-client/pom.xml index 0fbd7fc10e1..fc66c9e5dcc 100644 --- a/jetty-unixsocket/jetty-unixsocket-client/pom.xml +++ b/jetty-unixsocket/jetty-unixsocket-client/pom.xml @@ -3,7 +3,7 @@ jetty-unixsocket org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-unixsocket/jetty-unixsocket-common/pom.xml b/jetty-unixsocket/jetty-unixsocket-common/pom.xml index 13858c810c2..1667195b810 100644 --- a/jetty-unixsocket/jetty-unixsocket-common/pom.xml +++ b/jetty-unixsocket/jetty-unixsocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-unixsocket - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-unixsocket/jetty-unixsocket-server/pom.xml b/jetty-unixsocket/jetty-unixsocket-server/pom.xml index 9822b132fc6..0ba25d24bbc 100644 --- a/jetty-unixsocket/jetty-unixsocket-server/pom.xml +++ b/jetty-unixsocket/jetty-unixsocket-server/pom.xml @@ -3,7 +3,7 @@ jetty-unixsocket org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-unixsocket/pom.xml b/jetty-unixsocket/pom.xml index c543ff407b6..b4e4c4d2b16 100644 --- a/jetty-unixsocket/pom.xml +++ b/jetty-unixsocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-util-ajax/pom.xml b/jetty-util-ajax/pom.xml index 914d2add266..6fcf4b1e14f 100644 --- a/jetty-util-ajax/pom.xml +++ b/jetty-util-ajax/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-util-ajax diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index 55ed068b72e..a0188a09aab 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index 92f21417989..350b35c7d73 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/javax-websocket-client/pom.xml b/jetty-websocket/javax-websocket-client/pom.xml index 371621cb314..bdbaea8cb23 100644 --- a/jetty-websocket/javax-websocket-client/pom.xml +++ b/jetty-websocket/javax-websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/javax-websocket-common/pom.xml b/jetty-websocket/javax-websocket-common/pom.xml index c3f940e0674..9fd8f573acd 100644 --- a/jetty-websocket/javax-websocket-common/pom.xml +++ b/jetty-websocket/javax-websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/javax-websocket-server/pom.xml b/jetty-websocket/javax-websocket-server/pom.xml index ffb0060ac8b..c4d3ee0e98d 100644 --- a/jetty-websocket/javax-websocket-server/pom.xml +++ b/jetty-websocket/javax-websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/javax-websocket-tests/pom.xml b/jetty-websocket/javax-websocket-tests/pom.xml index d90b0af2a2c..0976122edee 100644 --- a/jetty-websocket/javax-websocket-tests/pom.xml +++ b/jetty-websocket/javax-websocket-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/jetty-websocket-api/pom.xml b/jetty-websocket/jetty-websocket-api/pom.xml index 901ceb6ef89..a2486c5739b 100644 --- a/jetty-websocket/jetty-websocket-api/pom.xml +++ b/jetty-websocket/jetty-websocket-api/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/jetty-websocket-client/pom.xml b/jetty-websocket/jetty-websocket-client/pom.xml index d14de68e6cf..caeae04bc80 100644 --- a/jetty-websocket/jetty-websocket-client/pom.xml +++ b/jetty-websocket/jetty-websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/jetty-websocket-common/pom.xml b/jetty-websocket/jetty-websocket-common/pom.xml index bcdc2b0fc35..bd6c711d235 100644 --- a/jetty-websocket/jetty-websocket-common/pom.xml +++ b/jetty-websocket/jetty-websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/jetty-websocket-server/pom.xml b/jetty-websocket/jetty-websocket-server/pom.xml index c99720136c3..80303e8640b 100644 --- a/jetty-websocket/jetty-websocket-server/pom.xml +++ b/jetty-websocket/jetty-websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/jetty-websocket-tests/pom.xml b/jetty-websocket/jetty-websocket-tests/pom.xml index 6896a584c41..bfd1689a5d7 100644 --- a/jetty-websocket/jetty-websocket-tests/pom.xml +++ b/jetty-websocket/jetty-websocket-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index 0620ef3c17f..e4c5bbe5837 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-core/pom.xml b/jetty-websocket/websocket-core/pom.xml index ddc1c10d7b7..60879dcaa46 100644 --- a/jetty-websocket/websocket-core/pom.xml +++ b/jetty-websocket/websocket-core/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml index ad00e9255cf..f803f732e80 100644 --- a/jetty-websocket/websocket-servlet/pom.xml +++ b/jetty-websocket/websocket-servlet/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index 60f3d184096..be891ef3f1b 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index 9657b446973..3622e377ec1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT Jetty :: Project The Eclipse Jetty Project pom diff --git a/tests/jetty-http-tools/pom.xml b/tests/jetty-http-tools/pom.xml index dab57aaf1e7..47e7cd69a86 100644 --- a/tests/jetty-http-tools/pom.xml +++ b/tests/jetty-http-tools/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/tests/jetty-jmh/pom.xml b/tests/jetty-jmh/pom.xml index 320355a75c1..bc4827112ef 100644 --- a/tests/jetty-jmh/pom.xml +++ b/tests/jetty-jmh/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/tests/pom.xml b/tests/pom.xml index b34ca7666d8..75cd4504512 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml org.eclipse.jetty.tests diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml index 9833c8fa008..27fcd0dab1e 100644 --- a/tests/test-distribution/pom.xml +++ b/tests/test-distribution/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/tests/test-http-client-transport/pom.xml b/tests/test-http-client-transport/pom.xml index 35bc10a3930..84d9d7de5b9 100644 --- a/tests/test-http-client-transport/pom.xml +++ b/tests/test-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index 110edf217b9..4168685fe5e 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 test-integration diff --git a/tests/test-jmx/jmx-webapp-it/pom.xml b/tests/test-jmx/jmx-webapp-it/pom.xml index 00b6a0a7437..6543bcc1d1e 100644 --- a/tests/test-jmx/jmx-webapp-it/pom.xml +++ b/tests/test-jmx/jmx-webapp-it/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-jmx-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 jmx-webapp-it diff --git a/tests/test-jmx/jmx-webapp/pom.xml b/tests/test-jmx/jmx-webapp/pom.xml index 501ba1cb387..38445f8c86f 100644 --- a/tests/test-jmx/jmx-webapp/pom.xml +++ b/tests/test-jmx/jmx-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-jmx-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT jmx-webapp war diff --git a/tests/test-jmx/pom.xml b/tests/test-jmx/pom.xml index 8b95a50f9e8..d64b3e8ef45 100644 --- a/tests/test-jmx/pom.xml +++ b/tests/test-jmx/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 test-jmx-parent diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index 31c9c3d7c0a..9c521147677 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index 1ae87bb8441..8e52029caac 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 6066ada2e05..25a0746b134 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-file-sessions/pom.xml b/tests/test-sessions/test-file-sessions/pom.xml index 16519039a35..d79168404c6 100644 --- a/tests/test-sessions/test-file-sessions/pom.xml +++ b/tests/test-sessions/test-file-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-file-sessions Jetty Tests :: Sessions :: File diff --git a/tests/test-sessions/test-gcloud-sessions/pom.xml b/tests/test-sessions/test-gcloud-sessions/pom.xml index ac1ce3887ab..6b5ae8f14da 100644 --- a/tests/test-sessions/test-gcloud-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-gcloud-sessions Jetty Tests :: Sessions :: GCloud diff --git a/tests/test-sessions/test-hazelcast-sessions/pom.xml b/tests/test-sessions/test-hazelcast-sessions/pom.xml index e1579369076..fa96894adad 100644 --- a/tests/test-sessions/test-hazelcast-sessions/pom.xml +++ b/tests/test-sessions/test-hazelcast-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-hazelcast-sessions Jetty Tests :: Sessions :: Hazelcast diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index f192067383a..c414f7f5848 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-infinispan-sessions Jetty Tests :: Sessions :: Infinispan diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index 0c42830037c..ae24d2bd6b1 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-memcached-sessions/pom.xml b/tests/test-sessions/test-memcached-sessions/pom.xml index 8bce98c18c1..60ac2f524da 100644 --- a/tests/test-sessions/test-memcached-sessions/pom.xml +++ b/tests/test-sessions/test-memcached-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-memcached-sessions Jetty Tests :: Sessions :: Memcached diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index abda788df35..1c1f7718f8e 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index 018c9fe7844..a423ae8630a 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index 3e48a7f60d2..cf05e8a0007 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml test-webapps-parent diff --git a/tests/test-webapps/test-cdi-common-webapp/pom.xml b/tests/test-webapps/test-cdi-common-webapp/pom.xml index ef2d4c4c358..ab8cff68cdc 100644 --- a/tests/test-webapps/test-cdi-common-webapp/pom.xml +++ b/tests/test-webapps/test-cdi-common-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-felix-webapp/pom.xml b/tests/test-webapps/test-felix-webapp/pom.xml index 9ea42404f91..1b1e57e46a2 100644 --- a/tests/test-webapps/test-felix-webapp/pom.xml +++ b/tests/test-webapps/test-felix-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-http2-webapp/pom.xml b/tests/test-webapps/test-http2-webapp/pom.xml index 638769a7452..7db6283bc92 100644 --- a/tests/test-webapps/test-http2-webapp/pom.xml +++ b/tests/test-webapps/test-http2-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml index 4259e8dec31..563dc6b029b 100644 --- a/tests/test-webapps/test-jaas-webapp/pom.xml +++ b/tests/test-webapps/test-jaas-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-jaas-webapp Jetty Tests :: WebApp :: JAAS diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index b775a857c8e..76eff45b4f9 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml index a8f067f093b..08fce22680d 100644 --- a/tests/test-webapps/test-jndi-webapp/pom.xml +++ b/tests/test-webapps/test-jndi-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-jndi-webapp Jetty Tests :: WebApp :: JNDI diff --git a/tests/test-webapps/test-mock-resources/pom.xml b/tests/test-webapps/test-mock-resources/pom.xml index 6f5e6ce5799..aa30708c191 100644 --- a/tests/test-webapps/test-mock-resources/pom.xml +++ b/tests/test-webapps/test-mock-resources/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT Jetty Tests :: WebApp :: Mock Resources test-mock-resources diff --git a/tests/test-webapps/test-owb-cdi-webapp/pom.xml b/tests/test-webapps/test-owb-cdi-webapp/pom.xml index 7da90fab653..95a25c5a629 100644 --- a/tests/test-webapps/test-owb-cdi-webapp/pom.xml +++ b/tests/test-webapps/test-owb-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml index 1aba855b5f3..efd499fa3d0 100644 --- a/tests/test-webapps/test-proxy-webapp/pom.xml +++ b/tests/test-webapps/test-proxy-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-servlet-spec/pom.xml b/tests/test-webapps/test-servlet-spec/pom.xml index a6ba7d798c4..e1baa56d470 100644 --- a/tests/test-webapps/test-servlet-spec/pom.xml +++ b/tests/test-webapps/test-servlet-spec/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-servlet-spec-parent Jetty Tests :: Spec Test WebApp :: Parent diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml index e5c2e69a690..8beeaf3a468 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-container-initializer jar diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml index 87efaca4834..bada431d66d 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT Jetty Tests :: Webapps :: Spec Webapp test-spec-webapp diff --git a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml index 0ba3c010711..8a0fed27d72 100644 --- a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar diff --git a/tests/test-webapps/test-simple-webapp/pom.xml b/tests/test-webapps/test-simple-webapp/pom.xml index bb9d9829fd8..9c31f9dcde5 100644 --- a/tests/test-webapps/test-simple-webapp/pom.xml +++ b/tests/test-webapps/test-simple-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index 9241c8a0b58..ddec187e699 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 diff --git a/tests/test-webapps/test-weld-cdi-webapp/pom.xml b/tests/test-webapps/test-weld-cdi-webapp/pom.xml index 41a9e01208d..1c00b20c05f 100644 --- a/tests/test-webapps/test-weld-cdi-webapp/pom.xml +++ b/tests/test-webapps/test-weld-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 10.0.0.alpha1 + 10.0.0-SNAPSHOT 4.0.0 From cfd21864cf2c4bb5a3c0a3c3ec8dce76ac8da263 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 27 Nov 2019 11:45:33 +1100 Subject: [PATCH 37/77] Issue #4350 Remove exclude of MultiInputStreamParser from jetty-util osgi (#4356) Signed-off-by: Jan Bartel --- .../jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java | 8 ++++++++ jetty-util/pom.xml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java index 47cbf1182fd..37ea7f0d5e6 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.osgi.test; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; @@ -25,6 +26,8 @@ import javax.inject.Inject; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.util.MultiPartContentProvider; +import org.eclipse.jetty.client.util.StringContentProvider; import org.eclipse.jetty.http.HttpStatus; import org.junit.Test; import org.junit.runner.RunWith; @@ -126,6 +129,11 @@ public class TestJettyOSGiBootWithAnnotations response = client.GET("http://127.0.0.1:" + port + "/frag.html"); content = response.getContentAsString(); assertTrue(content.contains("

FRAGMENT

")); + MultiPartContentProvider multiPart = new MultiPartContentProvider(); + multiPart.addFieldPart("field", new StringContentProvider("foo"), null); + response = client.newRequest("http://127.0.0.1:" + port + "/multi").method("POST") + .content(multiPart).send(); + assertEquals(HttpStatus.OK_200, response.getStatus()); } finally { diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index 482b947511e..a4fdca91d56 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -50,7 +50,7 @@ true - org.eclipse.jetty.util;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}";exclude:="MultiPartInputStreamParser";uses:="org.eclipse.jetty.util.annotation,org.eclipse.jetty.util.component,org.eclipse.jetty.util.log,org.eclipse.jetty.util.resource,org.eclipse.jetty.util.thread";-noimport:=true,* + org.eclipse.jetty.util;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}";uses:="org.eclipse.jetty.util.annotation,org.eclipse.jetty.util.component,org.eclipse.jetty.util.log,org.eclipse.jetty.util.resource,org.eclipse.jetty.util.thread";-noimport:=true,* osgi.serviceloader; filter:="(osgi.serviceloader=org.eclipse.jetty.util.security.CredentialProvider)";resolution:=optional;cardinality:=multiple, osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)";resolution:=optional From 2410f9d6c45a3a71fd724e559bb5659fd9919f3f Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 27 Nov 2019 13:51:14 +1100 Subject: [PATCH 38/77] Issue #4315 - Jetty and Javax WebSocketSessions are no longer LifeCycles Signed-off-by: Lachlan Roberts --- .../javax/common/JavaxWebSocketSession.java | 24 +------------------ .../javax/common/SessionTracker.java | 8 ++++--- .../javax/common/AbstractSessionTest.java | 1 - .../client/AbstractClientSessionTest.java | 1 - .../client/SessionAddMessageHandlerTest.java | 2 -- .../websocket/common/SessionTracker.java | 3 --- .../websocket/common/WebSocketSession.java | 3 +-- .../tests/ConcurrentConnectTest.java | 5 ---- 8 files changed, 7 insertions(+), 40 deletions(-) diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java index af9aa1a6bc9..6ab4809d912 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java +++ b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java @@ -38,12 +38,9 @@ import javax.websocket.RemoteEndpoint.Basic; import javax.websocket.Session; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.SharedBlockingCallback; -import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.core.CloseStatus; import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.eclipse.jetty.websocket.core.FrameHandler; import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders; @@ -53,7 +50,7 @@ import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils; /** * Client Session for the JSR. */ -public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.websocket.Session +public class JavaxWebSocketSession implements javax.websocket.Session { private static final Logger LOG = Log.getLogger(JavaxWebSocketSession.class); @@ -547,25 +544,6 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we return coreSession.isSecure(); } - @Override - protected void doStop() - { - coreSession.close(CloseStatus.SHUTDOWN, "Container being shut down", new Callback() - { - @Override - public void succeeded() - { - coreSession.abort(); - } - - @Override - public void failed(Throwable x) - { - coreSession.abort(); - } - }); - } - @Override public synchronized void removeMessageHandler(MessageHandler handler) { diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java index 3af932dac42..ebfd697dbad 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java +++ b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/SessionTracker.java @@ -21,10 +21,10 @@ package org.eclipse.jetty.websocket.javax.common; import java.util.Collections; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; +import javax.websocket.CloseReason; import javax.websocket.Session; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.component.LifeCycle; public class SessionTracker extends AbstractLifeCycle implements JavaxWebSocketSessionListener { @@ -50,10 +50,12 @@ public class SessionTracker extends AbstractLifeCycle implements JavaxWebSocketS @Override protected void doStop() throws Exception { - for (JavaxWebSocketSession session : sessions) + for (Session session : sessions) { - LifeCycle.stop(session); + // GOING_AWAY is abnormal close status so it will hard close connection after sent. + session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, "Container being shut down")); } + super.doStop(); } } diff --git a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java index b7dc6d895ad..123387a57a0 100644 --- a/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java +++ b/jetty-websocket/javax-websocket-common/src/test/java/org/eclipse/jetty/websocket/javax/common/AbstractSessionTest.java @@ -41,7 +41,6 @@ public abstract class AbstractSessionTest JavaxWebSocketFrameHandler frameHandler = container.newFrameHandler(websocketPojo, upgradeRequest); FrameHandler.CoreSession coreSession = new FrameHandler.CoreSession.Empty(); session = new JavaxWebSocketSession(container, coreSession, frameHandler, null); - container.addManaged(session); } @AfterAll diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java index ac8074a647a..ba3a11f824b 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java +++ b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/AbstractClientSessionTest.java @@ -44,7 +44,6 @@ public abstract class AbstractClientSessionTest JavaxWebSocketFrameHandler frameHandler = container.newFrameHandler(websocketPojo, upgradeRequest); FrameHandler.CoreSession coreSession = new FrameHandler.CoreSession.Empty(); session = new JavaxWebSocketSession(container, coreSession, frameHandler, null); - container.addManaged(session); } @AfterAll diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java index 3bd87fe4d6f..cfe5dc74165 100644 --- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java +++ b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/SessionAddMessageHandlerTest.java @@ -82,13 +82,11 @@ public class SessionAddMessageHandlerTest // Session session = frameHandler.getSession(); - session.start(); } @AfterEach public void stopSession() throws Exception { - session.stop(); container.stop(); } diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java index 554667c3c1f..f1f7d68524f 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java +++ b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/SessionTracker.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketSessionListener; @@ -40,7 +39,6 @@ public class SessionTracker extends AbstractLifeCycle implements WebSocketSessio @Override public void onWebSocketSessionOpened(Session session) { - LifeCycle.start(session); sessions.add(session); } @@ -48,7 +46,6 @@ public class SessionTracker extends AbstractLifeCycle implements WebSocketSessio public void onWebSocketSessionClosed(Session session) { sessions.remove(session); - LifeCycle.stop(session); } @Override diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java index 1f08a22542a..cdbeacf38ea 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java +++ b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java @@ -23,7 +23,6 @@ import java.net.SocketAddress; import java.time.Duration; import java.util.Objects; -import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -35,7 +34,7 @@ import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.api.WebSocketBehavior; import org.eclipse.jetty.websocket.core.FrameHandler; -public class WebSocketSession extends AbstractLifeCycle implements Session, SuspendToken, Dumpable +public class WebSocketSession implements Session, SuspendToken, Dumpable { private static final Logger LOG = Log.getLogger(WebSocketSession.class); private final FrameHandler.CoreSession coreSession; diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java index bbec94336c6..a6807a8722c 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/ConcurrentConnectTest.java @@ -134,11 +134,6 @@ public class ConcurrentConnectTest } closeListener.closeLatch.await(5, TimeUnit.SECONDS); - for (EventSocket l : listeners) - { - assertTrue(((WebSocketSession)l.session).isStopped()); - } - assertTrue(client.getOpenSessions().isEmpty()); assertTrue(client.getContainedBeans(WebSocketSession.class).isEmpty()); } From c440a3f9727c2129a4412e82ad3fffd43a872b1f Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 27 Nov 2019 14:56:59 +1100 Subject: [PATCH 39/77] Issue #4363 Restore contextXml config for jetty maven plugin (#4367) Signed-off-by: Jan Bartel --- .../jetty-simple-webapp/pom.xml | 2 ++ .../src/config/context.xml | 7 ++++++ .../jetty/maven/plugin/AbstractJettyMojo.java | 5 +++-- .../jetty/maven/plugin/it/TestGetContent.java | 22 +++++++++++++------ 4 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/context.xml diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml index d17cc126f78..7dcdcb59c1d 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml @@ -88,6 +88,7 @@ ${jetty.port.file} + /setbycontextxml true true true @@ -117,6 +118,7 @@ true ${basedir}/src/config/jetty.xml + ${basedir}/src/config/context.xml true diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/context.xml b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/context.xml new file mode 100644 index 00000000000..3eb5570a37d --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/context.xml @@ -0,0 +1,7 @@ + + + + + /setbycontextxml + + diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java index 1977a35a590..c7c1f525f28 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java @@ -539,9 +539,10 @@ public abstract class AbstractJettyMojo extends AbstractMojo path = workDir.resolve(path); contextXml = path.toFile().getAbsolutePath(); } - - XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(path.toFile())); + getLog().info("Applying context xml file " + contextXml); + XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(path.toFile())); + xmlConfiguration.configure(webApp); } //If no contextPath was specified, go with default of project artifactid diff --git a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java index 1e3f34f8f80..691b52a498a 100644 --- a/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java +++ b/jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/it/TestGetContent.java @@ -33,7 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** - * + * */ public class TestGetContent { @@ -42,6 +42,9 @@ public class TestGetContent throws Exception { int port = getPort(); + String contextPath = getContextPath(); + if (contextPath.endsWith("/")) + contextPath = contextPath.substring(0, contextPath.lastIndexOf('/')); assertTrue(port > 0); HttpClient httpClient = new HttpClient(); try @@ -50,16 +53,16 @@ public class TestGetContent if (Boolean.getBoolean("helloServlet")) { - String response = httpClient.GET("http://localhost:" + port + "/hello?name=beer").getContentAsString(); + String response = httpClient.GET("http://localhost:" + port + contextPath + "/hello?name=beer").getContentAsString(); assertEquals("Hello beer", response.trim(), "it test " + System.getProperty("maven.it.name")); - response = httpClient.GET("http://localhost:" + port + "/hello?name=foo").getContentAsString(); + response = httpClient.GET("http://localhost:" + port + contextPath + "/hello?name=foo").getContentAsString(); assertEquals("Hello foo", response.trim(), "it test " + System.getProperty("maven.it.name")); System.out.println("helloServlet"); } if (Boolean.getBoolean("pingServlet")) { System.out.println("pingServlet"); - String response = httpClient.GET("http://localhost:" + port + "/ping?name=beer").getContentAsString(); + String response = httpClient.GET("http://localhost:" + port + contextPath + "/ping?name=beer").getContentAsString(); assertEquals("pong beer", response.trim(), "it test " + System.getProperty("maven.it.name")); System.out.println("pingServlet ok"); } @@ -67,7 +70,7 @@ public class TestGetContent String pathToCheck = System.getProperty("pathToCheck"); if (StringUtils.isNotBlank(contentCheck)) { - String url = "http://localhost:" + port; + String url = "http://localhost:" + port + contextPath; if (pathToCheck != null) { url += pathToCheck; @@ -79,9 +82,9 @@ public class TestGetContent } if (Boolean.getBoolean("helloTestServlet")) { - String response = httpClient.GET("http://localhost:" + port + "/testhello?name=beer").getContentAsString(); + String response = httpClient.GET("http://localhost:" + port + contextPath + "/testhello?name=beer").getContentAsString(); assertEquals("Hello from test beer", response.trim(), "it test " + System.getProperty("maven.it.name")); - response = httpClient.GET("http://localhost:" + port + "/testhello?name=foo").getContentAsString(); + response = httpClient.GET("http://localhost:" + port + contextPath + "/testhello?name=foo").getContentAsString(); assertEquals("Hello from test foo", response.trim(), "it test " + System.getProperty("maven.it.name")); System.out.println("helloServlet"); } @@ -92,6 +95,11 @@ public class TestGetContent } } + public static String getContextPath() + { + return System.getProperty("context.path", "/"); + } + public static int getPort() throws Exception { From 6988c4feaad761f58d0d9022d1566b554367cc8b Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 27 Nov 2019 15:32:38 +1100 Subject: [PATCH 40/77] Issue #4368 - make MultiParts a class instead of interface Signed-off-by: Lachlan Roberts --- .../org/eclipse/jetty/server/MultiParts.java | 69 ++++++++----------- .../org/eclipse/jetty/server/Request.java | 2 +- 2 files changed, 28 insertions(+), 43 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java index 71a42d725f4..b6deb13c132 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java @@ -30,55 +30,40 @@ import org.eclipse.jetty.http.MultiPartFormInputStream; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler.Context; -public interface MultiParts extends Closeable +public class MultiParts implements Closeable { - Collection getParts() throws IOException; + private final MultiPartFormInputStream _httpParser; + private final ContextHandler.Context _context; - Part getPart(String name) throws IOException; - - boolean isEmpty(); - - ContextHandler.Context getContext(); - - class MultiPartsHttpParser implements MultiParts + public MultiParts(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request) { - private final MultiPartFormInputStream _httpParser; - private final ContextHandler.Context _context; + _httpParser = new MultiPartFormInputStream(in, contentType, config, contextTmpDir); + _context = request.getContext(); + } - public MultiPartsHttpParser(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request) throws IOException - { - _httpParser = new MultiPartFormInputStream(in, contentType, config, contextTmpDir); - _context = request.getContext(); - } + public Collection getParts() throws IOException + { + return _httpParser.getParts(); + } - @Override - public Collection getParts() throws IOException - { - return _httpParser.getParts(); - } + public Part getPart(String name) throws IOException + { + return _httpParser.getPart(name); + } - @Override - public Part getPart(String name) throws IOException - { - return _httpParser.getPart(name); - } + @Override + public void close() + { + _httpParser.deleteParts(); + } - @Override - public void close() - { - _httpParser.deleteParts(); - } + public boolean isEmpty() + { + return _httpParser.isEmpty(); + } - @Override - public boolean isEmpty() - { - return _httpParser.isEmpty(); - } - - @Override - public Context getContext() - { - return _context; - } + public Context getContext() + { + return _context; } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 5ffe4c04645..bf198f95791 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -2379,7 +2379,7 @@ public class Request implements HttpServletRequest private MultiParts newMultiParts(MultipartConfigElement config) throws IOException { - return new MultiParts.MultiPartsHttpParser(getInputStream(), getContentType(), config, + return new MultiParts(getInputStream(), getContentType(), config, (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this); } From 76bb8d2327a449d910ec31f0199155a4d7043183 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 27 Nov 2019 17:20:01 +1100 Subject: [PATCH 41/77] Issue #4368 directly use MultiPartFormInputStream instead of MultiParts MultiPart cleanup is now done in Request.onCompleted() Signed-off-by: Lachlan Roberts --- .../server/MultiPartCleanerListener.java | 63 ---------- .../org/eclipse/jetty/server/MultiParts.java | 69 ----------- .../org/eclipse/jetty/server/Request.java | 27 ++-- .../org/eclipse/jetty/server/RequestTest.java | 116 ++++++------------ .../eclipse/jetty/servlet/ServletHolder.java | 26 ---- 5 files changed, 55 insertions(+), 246 deletions(-) delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartCleanerListener.java delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartCleanerListener.java b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartCleanerListener.java deleted file mode 100644 index 4340ffbc842..00000000000 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiPartCleanerListener.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 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.server; - -import javax.servlet.ServletRequestEvent; -import javax.servlet.ServletRequestListener; - -import org.eclipse.jetty.server.handler.ContextHandler; - -public class MultiPartCleanerListener implements ServletRequestListener -{ - public static final MultiPartCleanerListener INSTANCE = new MultiPartCleanerListener(); - - protected MultiPartCleanerListener() - { - } - - @Override - public void requestDestroyed(ServletRequestEvent sre) - { - //Clean up any tmp files created by MultiPartInputStream - MultiParts parts = (MultiParts)sre.getServletRequest().getAttribute(Request.__MULTIPARTS); - if (parts != null) - { - ContextHandler.Context context = parts.getContext(); - - //Only do the cleanup if we are exiting from the context in which a servlet parsed the multipart files - if (context == sre.getServletContext()) - { - try - { - parts.close(); - } - catch (Throwable e) - { - sre.getServletContext().log("Errors deleting multipart tmp files", e); - } - } - } - } - - @Override - public void requestInitialized(ServletRequestEvent sre) - { - //nothing to do, multipart config set up by ServletHolder.handle() - } -} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java b/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java deleted file mode 100644 index b6deb13c132..00000000000 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/MultiParts.java +++ /dev/null @@ -1,69 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2019 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.server; - -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import javax.servlet.MultipartConfigElement; -import javax.servlet.http.Part; - -import org.eclipse.jetty.http.MultiPartFormInputStream; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.ContextHandler.Context; - -public class MultiParts implements Closeable -{ - private final MultiPartFormInputStream _httpParser; - private final ContextHandler.Context _context; - - public MultiParts(InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir, Request request) - { - _httpParser = new MultiPartFormInputStream(in, contentType, config, contextTmpDir); - _context = request.getContext(); - } - - public Collection getParts() throws IOException - { - return _httpParser.getParts(); - } - - public Part getPart(String name) throws IOException - { - return _httpParser.getPart(name); - } - - @Override - public void close() - { - _httpParser.deleteParts(); - } - - public boolean isEmpty() - { - return _httpParser.isEmpty(); - } - - public Context getContext() - { - return _context; - } -} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index bf198f95791..21d5339184e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -81,6 +81,7 @@ import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.http.MultiPartFormInputStream; import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.http.pathmap.ServletPathSpec; import org.eclipse.jetty.io.RuntimeIOException; @@ -141,7 +142,6 @@ import org.eclipse.jetty.util.log.Logger; public class Request implements HttpServletRequest { public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.jetty.multipartConfig"; - public static final String __MULTIPARTS = "org.eclipse.jetty.multiParts"; private static final Logger LOG = Log.getLogger(Request.class); private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault()); @@ -228,7 +228,7 @@ public class Request implements HttpServletRequest private HttpSession _session; private SessionHandler _sessionHandler; private long _timeStamp; - private MultiParts _multiParts; //if the request is a multi-part mime + private MultiPartFormInputStream _multiParts; //if the request is a multi-part mime private AsyncContextState _async; private List _sessions; //list of sessions used during lifetime of request @@ -1504,6 +1504,19 @@ public class Request implements HttpServletRequest for (Session s:_sessions) leaveSession(s); } + + //Clean up any tmp files created by MultiPartInputStream + if (_multiParts != null) + { + try + { + _multiParts.deleteParts(); + } + catch (Throwable e) + { + LOG.warn("Errors deleting multipart tmp files", e); + } + } } /** @@ -2305,9 +2318,6 @@ public class Request implements HttpServletRequest private Collection getParts(MultiMap params) throws IOException { - if (_multiParts == null) - _multiParts = (MultiParts)getAttribute(__MULTIPARTS); - if (_multiParts == null) { MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT); @@ -2315,7 +2325,6 @@ public class Request implements HttpServletRequest throw new IllegalStateException("No multipart config for servlet"); _multiParts = newMultiParts(config); - setAttribute(__MULTIPARTS, _multiParts); Collection parts = _multiParts.getParts(); String formCharset = null; @@ -2377,10 +2386,10 @@ public class Request implements HttpServletRequest return _multiParts.getParts(); } - private MultiParts newMultiParts(MultipartConfigElement config) throws IOException + private MultiPartFormInputStream newMultiParts(MultipartConfigElement config) throws IOException { - return new MultiParts(getInputStream(), getContentType(), config, - (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null), this); + return new MultiPartFormInputStream(getInputStream(), getContentType(), config, + (_context != null ? (File)_context.getAttribute("javax.servlet.context.tempdir") : null)); } @Override diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java index 88e3225bf14..841360cc397 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java @@ -38,7 +38,6 @@ import javax.servlet.DispatcherType; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequestEvent; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -341,28 +340,13 @@ public class RequestTest testTmpDir.deleteOnExit(); assertTrue(testTmpDir.list().length == 0); + // We should have two tmp files after parsing the multipart form. + RequestTester tester = (request, response) -> testTmpDir.list().length == 2; + ContextHandler contextHandler = new ContextHandler(); contextHandler.setContextPath("/foo"); contextHandler.setResourceBase("."); - contextHandler.setHandler(new MultiPartRequestHandler(testTmpDir)); - contextHandler.addEventListener(new MultiPartCleanerListener() - { - - @Override - public void requestDestroyed(ServletRequestEvent sre) - { - MultiParts m = (MultiParts)sre.getServletRequest().getAttribute(Request.__MULTIPARTS); - assertNotNull(m); - ContextHandler.Context c = m.getContext(); - assertNotNull(c); - assertTrue(c == sre.getServletContext()); - assertTrue(!m.isEmpty()); - assertTrue(testTmpDir.list().length == 2); - super.requestDestroyed(sre); - String[] files = testTmpDir.list(); - assertTrue(files.length == 0); - } - }); + contextHandler.setHandler(new MultiPartRequestHandler(testTmpDir, tester)); _server.stop(); _server.setHandler(contextHandler); _server.start(); @@ -387,51 +371,16 @@ public class RequestTest multipart; String responses = _connector.getResponse(request); - //System.err.println(responses); assertTrue(responses.startsWith("HTTP/1.1 200")); - } - @Test - public void testHttpMultiPart() throws Exception - { - final File testTmpDir = File.createTempFile("reqtest", null); - if (testTmpDir.exists()) - testTmpDir.delete(); - testTmpDir.mkdir(); - testTmpDir.deleteOnExit(); - assertTrue(testTmpDir.list().length == 0); - - ContextHandler contextHandler = new ContextHandler(); - contextHandler.setContextPath("/foo"); - contextHandler.setResourceBase("."); - contextHandler.setHandler(new MultiPartRequestHandler(testTmpDir)); - - _server.stop(); - _server.setHandler(contextHandler); - _server.start(); - - String multipart = " --AaB03x\r" + - "content-disposition: form-data; name=\"field1\"\r" + - "\r" + - "Joe Blow\r" + - "--AaB03x\r" + - "content-disposition: form-data; name=\"stuff\"; filename=\"foo.upload\"\r" + - "Content-Type: text/plain;charset=ISO-8859-1\r" + - "\r" + - "000000000000000000000000000000000000000000000000000\r" + - "--AaB03x--\r"; - - String request = "GET /foo/x.html HTTP/1.1\r\n" + + // We know the previous request has completed if another request can be processed. + String cleanupRequest = "GET /foo/cleanup HTTP/1.1\r\n" + "Host: whatever\r\n" + - "Content-Type: multipart/form-data; boundary=\"AaB03x\"\r\n" + - "Content-Length: " + multipart.getBytes().length + "\r\n" + "Connection: close\r\n" + - "\r\n" + - multipart; - - String responses = _connector.getResponse(request); - //System.err.println(responses); - assertThat(responses, Matchers.startsWith("HTTP/1.1 500")); + "\r\n"; + String cleanupResponse = _connector.getResponse(cleanupRequest); + assertTrue(cleanupResponse.startsWith("HTTP/1.1 200")); + assertThat(testTmpDir.list().length, is(0)); } @Test @@ -449,22 +398,6 @@ public class RequestTest contextHandler.setContextPath("/foo"); contextHandler.setResourceBase("."); contextHandler.setHandler(new BadMultiPartRequestHandler(testTmpDir)); - contextHandler.addEventListener(new MultiPartCleanerListener() - { - - @Override - public void requestDestroyed(ServletRequestEvent sre) - { - MultiParts m = (MultiParts)sre.getServletRequest().getAttribute(Request.__MULTIPARTS); - assertNotNull(m); - ContextHandler.Context c = m.getContext(); - assertNotNull(c); - assertTrue(c == sre.getServletContext()); - super.requestDestroyed(sre); - String[] files = testTmpDir.list(); - assertTrue(files.length == 0); - } - }); _server.stop(); _server.setHandler(contextHandler); _server.start(); @@ -494,6 +427,15 @@ public class RequestTest //System.err.println(responses); assertTrue(responses.startsWith("HTTP/1.1 500")); } + + // We know the previous request has completed if another request can be processed. + String cleanupRequest = "GET /foo/cleanup HTTP/1.1\r\n" + + "Host: whatever\r\n" + + "Connection: close\r\n" + + "\r\n"; + String cleanupResponse = _connector.getResponse(cleanupRequest); + assertTrue(cleanupResponse.startsWith("HTTP/1.1 200")); + assertThat(testTmpDir.list().length, is(0)); } @Test @@ -1818,20 +1760,27 @@ public class RequestTest private class MultiPartRequestHandler extends AbstractHandler { + RequestTester checker; File tmpDir; - public MultiPartRequestHandler(File tmpDir) + public MultiPartRequestHandler(File tmpDir, RequestTester checker) { this.tmpDir = tmpDir; + this.checker = checker; } @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ((Request)request).setHandled(true); + if ("/cleanup".equals(target)) + { + response.setStatus(200); + return; + } + try { - MultipartConfigElement mpce = new MultipartConfigElement(tmpDir.getAbsolutePath(), -1, -1, 2); request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce); @@ -1850,6 +1799,9 @@ public class RequestTest response.addHeader("Violation", v); } } + + if (checker != null && !checker.check(request, response)) + response.sendError(500); } catch (IllegalStateException e) { @@ -1877,6 +1829,12 @@ public class RequestTest public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ((Request)request).setHandled(true); + if ("/cleanup".equals(target)) + { + response.setStatus(200); + return; + } + try { diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java index 2fe67f75b12..b3b4ae9b07f 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java @@ -49,7 +49,6 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.RunAsToken; -import org.eclipse.jetty.server.MultiPartCleanerListener; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.handler.ContextHandler; @@ -592,8 +591,6 @@ public class ServletHolder extends Holder implements UserIdentity.Scope else if (_forcedPath != null) detectJspContainer(); - initMultiPart(); - if (LOG.isDebugEnabled()) LOG.debug("Servlet.init {} for {}", _servlet, getName()); _servlet.init(_config); @@ -652,29 +649,6 @@ public class ServletHolder extends Holder implements UserIdentity.Scope scratch.mkdir(); } - /** - * Register a ServletRequestListener that will ensure tmp multipart - * files are deleted when the request goes out of scope. - * - * @throws Exception if unable to init the multipart - */ - protected void initMultiPart() throws Exception - { - //if this servlet can handle multipart requests, ensure tmp files will be - //cleaned up correctly - if (((Registration)getRegistration()).getMultipartConfig() != null) - { - if (LOG.isDebugEnabled()) - LOG.debug("multipart cleanup listener added for {}", this); - - //Register a listener to delete tmp files that are created as a result of this - //servlet calling Request.getPart() or Request.getParts() - ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext()); - if (!ch.getEventListeners().contains(MultiPartCleanerListener.INSTANCE)) - ch.addEventListener(MultiPartCleanerListener.INSTANCE); - } - } - @Override public ContextHandler getContextHandler() { From 15c9f0bfc2c5ff03ec84c16b90df028a09520c82 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 27 Nov 2019 05:51:39 -0600 Subject: [PATCH 42/77] Issue #4329 - Cleaning up SessionDump Signed-off-by: Joakim Erdfelt --- .../src/main/java/com/acme/SessionDump.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java index 8cc74ab0d60..ed06dc812bd 100644 --- a/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java +++ b/tests/test-webapps/test-jetty-webapp/src/main/java/com/acme/SessionDump.java @@ -41,7 +41,7 @@ public class SessionDump extends HttpServlet /** * Simple object attribute to test serialization */ - public class ObjectAttributeValue implements java.io.Serializable + public static class ObjectAttributeValue implements java.io.Serializable { long l; @@ -58,8 +58,6 @@ public class SessionDump extends HttpServlet int redirectCount = 0; - String pageType; - @Override public void init(ServletConfig config) throws ServletException @@ -67,8 +65,7 @@ public class SessionDump extends HttpServlet super.init(config); } - protected void handleForm(HttpServletRequest request, - HttpServletResponse response) + protected void handleForm(HttpServletRequest request) { HttpSession session = request.getSession(false); String action = request.getParameter("Action"); @@ -99,9 +96,9 @@ public class SessionDump extends HttpServlet @Override public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException + throws IOException { - handleForm(request, response); + handleForm(request); String nextUrl = getURI(request) + "?R=" + redirectCount++; String encodedUrl = response.encodeRedirectURL(nextUrl); response.sendRedirect(encodedUrl); @@ -110,9 +107,9 @@ public class SessionDump extends HttpServlet @Override public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException + throws IOException { - handleForm(request, response); + handleForm(request); response.setContentType("text/html"); @@ -124,7 +121,7 @@ public class SessionDump extends HttpServlet } catch (IllegalStateException e) { - e.printStackTrace(System.err); + log("Session already invalidated", e); session = null; } From a6cdec548ceae6924c24882c0001c44cf2547aac Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 28 Nov 2019 09:16:14 +1100 Subject: [PATCH 43/77] Revert "Issue #4351 Found simpler test" This reverts commit 5bc6593337893a6e78f56361ac029964e43a9b8c. --- .../jetty/servlet/InitServletTest.java | 149 ++++++++++++++++++ .../jetty/servlet/ServletHolderTest.java | 89 ----------- 2 files changed, 149 insertions(+), 89 deletions(-) create mode 100644 jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java new file mode 100644 index 00000000000..66362223a77 --- /dev/null +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java @@ -0,0 +1,149 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.servlet; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.client.api.Result; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.NetworkConnector; +import org.eclipse.jetty.server.Server; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.array; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class InitServletTest +{ + public static class DemoServlet extends HttpServlet + { + AtomicInteger initCount = new AtomicInteger(); + + @Override + public void init() throws ServletException + { + super.init(); + try + { + //Make the initialization last a little while so + //other request can run + Thread.sleep(5000); + } + catch (InterruptedException e) + { + throw new ServletException(e); + } + initCount.addAndGet(1); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + //Check that the init() method has been totally finished (by another request) before + //the servlet service() method is called. + if (initCount.get() != 1) + { + resp.sendError(500, "Servlet not initialized!"); + } + } + } + + private static class AsyncResponseListener implements Response.CompleteListener + { + + private CountDownLatch resultsLatch; + private Integer[] results; + private AtomicInteger index = new AtomicInteger(); + + public AsyncResponseListener(CountDownLatch resultsLatch, Integer[] results) + { + this.resultsLatch = resultsLatch; + this.results = results; + } + + public void onComplete(Result result) + { + results[index.getAndAdd(1)] = result.getResponse().getStatus(); + resultsLatch.countDown(); + } + + public void awaitCompletion() throws InterruptedException + { + assertTrue(resultsLatch.await(60L, TimeUnit.SECONDS)); + } + } + + @Test + public void testServletInitialization() throws Exception + { + Server server = new Server(0); + ServletContextHandler context = new ServletContextHandler(server, "/"); + server.setHandler(context); + //add a lazily instantiated servlet + context.addServlet(new ServletHolder(DemoServlet.class), "/*"); + server.start(); + int port = ((NetworkConnector)server.getConnectors()[0]).getLocalPort(); + HttpClient client = new HttpClient(); + try + { + client.start(); + + //Expect 2 responses + CountDownLatch resultsLatch = new CountDownLatch(2); + Integer[] results = new Integer[2]; + AsyncResponseListener l = new AsyncResponseListener(resultsLatch, results); + + //req1: should initialize servlet + Request r1 = client.newRequest("http://localhost:" + port + "/r1"); + r1.method(HttpMethod.GET).send(l); + + //Need to give 1st request a head start before request2 + Thread.sleep(1000); + + //req2: should see servlet fully initialized by request1 + Request r2 = client.newRequest("http://localhost:" + port + "/r2"); + r2.method(HttpMethod.GET).send(l); + + l.awaitCompletion(); + + assertThat(results, is(array(equalTo(HttpStatus.OK_200), equalTo(HttpStatus.OK_200)))); + } + finally + { + client.stop(); + server.stop(); + } + } +} diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHolderTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHolderTest.java index 8b0abaec424..c2c5b43dc6e 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHolderTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHolderTest.java @@ -20,16 +20,10 @@ package org.eclipse.jetty.servlet; import java.util.Collections; import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import javax.servlet.UnavailableException; import javax.servlet.http.HttpServlet; -import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.log.StacklessLogging; @@ -48,89 +42,6 @@ public class ServletHolderTest { public static class FakeServlet extends HttpServlet { - public AtomicInteger initCount = new AtomicInteger(); - - @Override - public void init() throws ServletException - { - super.init(); - try - { - //Make the initialization last a little while so - //other request can run - Thread.sleep(1000); - } - catch (InterruptedException e) - { - throw new ServletException(e); - } - initCount.addAndGet(1); - } - } - - @Test - public void testServletInitAtomic() throws Exception - { - Server server = new Server(); - ServletContextHandler context = new ServletContextHandler(); - final ServletHolder holder = new ServletHolder(Source.EMBEDDED); - holder.setHeldClass(FakeServlet.class); - holder.setName("Fake"); - context.addServlet(holder, "/fake/*"); - server.setHandler(context); - server.start(); - - final AtomicInteger t1Count = new AtomicInteger(); - final AtomicInteger t2Count = new AtomicInteger(); - final CountDownLatch t1Latch = new CountDownLatch(1); - final CountDownLatch t2Latch = new CountDownLatch(1); - - //Test that 2 calls to holder.getServlet are atomic - only - //one should call servlet.init() and the other should be - //held waiting until that fully finishes. - Thread t1 = new Thread() - { - public void run() - { - try - { - FakeServlet s = (FakeServlet)holder.getServlet(); - t1Count.set(s.initCount.get()); - t1Latch.countDown(); - } - catch (ServletException e) - { - fail(e); - } - } - }; - - Thread t2 = new Thread() - { - public void run() - { - try - { - FakeServlet s = (FakeServlet)holder.getServlet(); - t2Count.set(s.initCount.get()); - t2Latch.countDown(); - } - catch (ServletException e) - { - fail(e); - } - } - }; - - t1.start(); - Thread.sleep(500); - t2.start(); - - t1Latch.await(10L, TimeUnit.SECONDS); - t2Latch.await(10L, TimeUnit.SECONDS); - - assertEquals(1, t1Count.get()); - assertEquals(1, t2Count.get()); } @Test From 07efbb728d47b8030481cce317e299187a137333 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 28 Nov 2019 09:34:39 +1100 Subject: [PATCH 44/77] Issue #4351 Lessen wait times. Signed-off-by: Jan Bartel --- .../test/java/org/eclipse/jetty/servlet/InitServletTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java index 66362223a77..70935978a15 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java @@ -59,7 +59,7 @@ public class InitServletTest { //Make the initialization last a little while so //other request can run - Thread.sleep(5000); + Thread.sleep(2000); } catch (InterruptedException e) { @@ -76,6 +76,7 @@ public class InitServletTest if (initCount.get() != 1) { resp.sendError(500, "Servlet not initialized!"); + System.err.println("NOT INIT"); } } } @@ -130,7 +131,7 @@ public class InitServletTest r1.method(HttpMethod.GET).send(l); //Need to give 1st request a head start before request2 - Thread.sleep(1000); + Thread.sleep(500); //req2: should see servlet fully initialized by request1 Request r2 = client.newRequest("http://localhost:" + port + "/r2"); From 7ebf673ad35924f94edb06231746538e8e5a479e Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 28 Nov 2019 10:37:54 +1100 Subject: [PATCH 45/77] fix merge for DemoBaseTests.testSessionDump() to Jetty 10 Signed-off-by: Lachlan Roberts --- .../org/eclipse/jetty/tests/distribution/DemoBaseTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java index a866a22438f..9b9af1bdc35 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoBaseTests.java @@ -193,7 +193,7 @@ public class DemoBaseTests extends AbstractDistributionTest }; try (DistributionTester.Run run = distribution.start(args)) { - assertTrue(run.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS)); + assertTrue(run.awaitConsoleLogsFor("Started ", 10, TimeUnit.SECONDS)); startHttpClient(); client.setFollowRedirects(true); From e9c3eb0d733beea8f4b66fce835b4132c0037892 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 28 Nov 2019 14:27:00 +1100 Subject: [PATCH 46/77] remove duplicate TestFrameHandler from websocket core tests Signed-off-by: Lachlan Roberts --- .../websocket/core/TestAsyncFrameHandler.java | 2 + .../websocket/core/TestFrameHandler.java | 2 + .../websocket/core/WebSocketOpenTest.java | 110 +++--------------- 3 files changed, 22 insertions(+), 92 deletions(-) diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestAsyncFrameHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestAsyncFrameHandler.java index 97a83b1b070..ba4402f157f 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestAsyncFrameHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestAsyncFrameHandler.java @@ -33,6 +33,7 @@ public class TestAsyncFrameHandler implements FrameHandler public CoreSession coreSession; public BlockingQueue receivedFrames = new BlockingArrayQueue<>(); + public CloseStatus closeStatus; public volatile Throwable error; public CountDownLatch openLatch = new CountDownLatch(1); public CountDownLatch errorLatch = new CountDownLatch(1); @@ -72,6 +73,7 @@ public class TestAsyncFrameHandler implements FrameHandler { if (LOG.isDebugEnabled()) LOG.debug("[{}] onClosed {}", name, closeStatus); + this.closeStatus = closeStatus; closeLatch.countDown(); callback.succeeded(); } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestFrameHandler.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestFrameHandler.java index 4d5f7dc303d..c6069942955 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestFrameHandler.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/TestFrameHandler.java @@ -33,6 +33,7 @@ public class TestFrameHandler implements SynchronousFrameHandler protected CoreSession coreSession; public BlockingQueue receivedFrames = new BlockingArrayQueue<>(); + protected CloseStatus closeStatus; protected Throwable failure; public CountDownLatch open = new CountDownLatch(1); @@ -76,6 +77,7 @@ public class TestFrameHandler implements SynchronousFrameHandler { if (LOG.isDebugEnabled()) LOG.debug("onClosed {}", closeStatus); + this.closeStatus = closeStatus; closed.countDown(); } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketOpenTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketOpenTest.java index 7d42b3e2a51..a55d389c2c9 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketOpenTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketOpenTest.java @@ -19,12 +19,10 @@ package org.eclipse.jetty.websocket.core; import java.net.Socket; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.Exchanger; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; -import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -51,7 +49,7 @@ public class WebSocketOpenTest extends WebSocketTester private static Logger LOG = Log.getLogger(WebSocketOpenTest.class); private WebSocketServer server; - private TestFrameHandler serverHandler; + private DemandingAsyncFrameHandler serverHandler; private Socket client; @AfterEach @@ -63,7 +61,7 @@ public class WebSocketOpenTest extends WebSocketTester public void setup(BiFunction onOpen) throws Exception { - serverHandler = new TestFrameHandler(onOpen); + serverHandler = new DemandingAsyncFrameHandler(onOpen); server = new WebSocketServer(serverHandler); server.start(); client = newClient(server.getLocalPort()); @@ -75,7 +73,7 @@ public class WebSocketOpenTest extends WebSocketTester setup((s, c) -> { assertThat(s.toString(), containsString("CONNECTED")); - WebSocketOpenTest.TestFrameHandler.sendText(s, "Hello", Callback.NOOP); + s.sendFrame(new Frame(OpCode.TEXT, "Hello"), NOOP, false); c.succeeded(); s.demand(1); return null; @@ -84,7 +82,7 @@ public class WebSocketOpenTest extends WebSocketTester assertThat(frame.getPayloadAsUTF8(), is("Hello")); client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.closeStatus.getCode(), is(CloseStatus.NORMAL)); frame = receiveFrame(client.getInputStream()); @@ -104,10 +102,10 @@ public class WebSocketOpenTest extends WebSocketTester return null; }); - assertTrue(serverHandler.onError.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.error, notNullValue()); - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.closeStatus.getCode(), is(CloseStatus.SERVER_ERROR)); Parser.ParsedFrame frame = receiveFrame(client.getInputStream()); @@ -131,7 +129,7 @@ public class WebSocketOpenTest extends WebSocketTester assertThat(new CloseStatus(frame).getCode(), is(CloseStatus.SHUTDOWN)); client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.closeStatus.getCode(), is(CloseStatus.SHUTDOWN)); } @@ -160,18 +158,18 @@ public class WebSocketOpenTest extends WebSocketTester Thread.sleep(100); // Can send while onOpen is active - WebSocketOpenTest.TestFrameHandler.sendText(coreSession, "Hello", NOOP); + coreSession.sendFrame(new Frame(OpCode.TEXT, "Hello"), NOOP, false); Parser.ParsedFrame frame = receiveFrame(client.getInputStream()); assertThat(frame.getPayloadAsUTF8(), is("Hello")); // But cannot receive client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertFalse(serverHandler.onClosed.await(1, TimeUnit.SECONDS)); + assertFalse(serverHandler.closeLatch.await(1, TimeUnit.SECONDS)); // Can't demand until open assertThrows(Throwable.class, () -> coreSession.demand(1)); client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertFalse(serverHandler.onClosed.await(1, TimeUnit.SECONDS)); + assertFalse(serverHandler.closeLatch.await(1, TimeUnit.SECONDS)); // Succeeded moves to OPEN state and still does not read CLOSE frame onOpenCallback.succeeded(); @@ -180,36 +178,21 @@ public class WebSocketOpenTest extends WebSocketTester // Demand start receiving frames coreSession.demand(1); client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true)); - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); // Closed handled normally - assertTrue(serverHandler.onClosed.await(5, TimeUnit.SECONDS)); + assertTrue(serverHandler.closeLatch.await(5, TimeUnit.SECONDS)); assertThat(serverHandler.closeStatus.getCode(), is(CloseStatus.NORMAL)); frame = receiveFrame(client.getInputStream()); assertThat(frame.getOpCode(), is(OpCode.CLOSE)); assertThat(new CloseStatus(frame).getCode(), is(CloseStatus.NORMAL)); } - static class TestFrameHandler implements SynchronousFrameHandler + static class DemandingAsyncFrameHandler extends TestAsyncFrameHandler { - private CoreSession coreSession; private BiFunction onOpen; - private CloseStatus closeStatus; - private CountDownLatch onClosed = new CountDownLatch(1); - private Throwable error; - private CountDownLatch onError = new CountDownLatch(1); - private Frame frame; - private CountDownLatch onFrame = new CountDownLatch(1); - public CoreSession getCoreSession() - { - synchronized (this) - { - return coreSession; - } - } - - TestFrameHandler(BiFunction onOpen) + DemandingAsyncFrameHandler(BiFunction onOpen) { this.onOpen = onOpen; } @@ -217,44 +200,11 @@ public class WebSocketOpenTest extends WebSocketTester @Override public void onOpen(CoreSession coreSession, Callback callback) { - LOG.info("onOpen {}", coreSession); - synchronized (this) - { - this.coreSession = coreSession; - } + if (LOG.isDebugEnabled()) + LOG.debug("[{}] onOpen {}", name, coreSession); + this.coreSession = coreSession; onOpen.apply(coreSession, callback); - } - - @Override - public void onFrame(Frame frame, Callback callback) - { - LOG.info("onFrame: " + BufferUtil.toDetailString(frame.getPayload())); - callback.succeeded(); - if (onFrame.getCount() == 1) - { - this.frame = frame; - onFrame.countDown(); - } - } - - @Override - public void onError(Throwable cause) - { - LOG.info("onError {} ", cause == null ? null : cause.toString()); - if (onError.getCount() != 1) - throw new IllegalStateException(); - error = cause; - onError.countDown(); - } - - @Override - public void onClosed(CloseStatus closeStatus) - { - LOG.info("onClosed {}", closeStatus); - if (onClosed.getCount() != 1) - throw new IllegalStateException(); - this.closeStatus = closeStatus; - onClosed.countDown(); + openLatch.countDown(); } @Override @@ -262,29 +212,5 @@ public class WebSocketOpenTest extends WebSocketTester { return true; } - - public void sendText(String text) - { - sendText(coreSession, text); - } - - public void sendText(String text, Callback callback) - { - sendText(coreSession, text, callback); - } - - static void sendText(FrameHandler.CoreSession coreSession, String text) - { - sendText(coreSession, text, NOOP); - } - - static void sendText(FrameHandler.CoreSession coreSession, String text, Callback callback) - { - Frame frame = new Frame(OpCode.TEXT); - frame.setFin(true); - frame.setPayload(text); - - coreSession.sendFrame(frame, callback, false); - } } } From dc0fac5806040d5ac63d4db5ca623c2a859720c5 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 28 Nov 2019 11:07:24 +0100 Subject: [PATCH 47/77] Issue #4351 - Lazy servlet init is not atomic. Code cleanup. Signed-off-by: Simone Bordet --- .../jetty/servlet/InitServletTest.java | 88 ++++++++----------- 1 file changed, 35 insertions(+), 53 deletions(-) diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java index 70935978a15..cd780b6b4c6 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InitServletTest.java @@ -22,34 +22,28 @@ import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; - import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; -import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.array; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; public class InitServletTest { public static class DemoServlet extends HttpServlet { - AtomicInteger initCount = new AtomicInteger(); + private static final long INIT_SLEEP = 2000; + private final AtomicInteger initCount = new AtomicInteger(); @Override public void init() throws ServletException @@ -57,53 +51,44 @@ public class InitServletTest super.init(); try { - //Make the initialization last a little while so - //other request can run - Thread.sleep(2000); + // Make the initialization last a little while. + // Other requests must wait. + Thread.sleep(INIT_SLEEP); } catch (InterruptedException e) { throw new ServletException(e); } - initCount.addAndGet(1); + initCount.incrementAndGet(); } @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - //Check that the init() method has been totally finished (by another request) before - //the servlet service() method is called. + // Check that the init() method has been totally finished (by another request) + // before the servlet service() method is called. if (initCount.get() != 1) - { resp.sendError(500, "Servlet not initialized!"); - System.err.println("NOT INIT"); - } } } - + private static class AsyncResponseListener implements Response.CompleteListener { + private final AtomicInteger index = new AtomicInteger(); + private final CountDownLatch resultsLatch; + private final int[] results; - private CountDownLatch resultsLatch; - private Integer[] results; - private AtomicInteger index = new AtomicInteger(); - - public AsyncResponseListener(CountDownLatch resultsLatch, Integer[] results) + public AsyncResponseListener(CountDownLatch resultsLatch, int[] results) { - this.resultsLatch = resultsLatch; - this.results = results; + this.resultsLatch = resultsLatch; + this.results = results; } - + public void onComplete(Result result) { - results[index.getAndAdd(1)] = result.getResponse().getStatus(); + results[index.getAndIncrement()] = result.getResponse().getStatus(); resultsLatch.countDown(); } - - public void awaitCompletion() throws InterruptedException - { - assertTrue(resultsLatch.await(60L, TimeUnit.SECONDS)); - } } @Test @@ -112,38 +97,35 @@ public class InitServletTest Server server = new Server(0); ServletContextHandler context = new ServletContextHandler(server, "/"); server.setHandler(context); - //add a lazily instantiated servlet + // Add a lazily instantiated servlet. context.addServlet(new ServletHolder(DemoServlet.class), "/*"); - server.start(); - int port = ((NetworkConnector)server.getConnectors()[0]).getLocalPort(); HttpClient client = new HttpClient(); + server.addBean(client); + server.start(); try { - client.start(); + int port = ((NetworkConnector)server.getConnectors()[0]).getLocalPort(); - //Expect 2 responses + // Expect 2 responses CountDownLatch resultsLatch = new CountDownLatch(2); - Integer[] results = new Integer[2]; + int[] results = new int[2]; AsyncResponseListener l = new AsyncResponseListener(resultsLatch, results); - - //req1: should initialize servlet - Request r1 = client.newRequest("http://localhost:" + port + "/r1"); - r1.method(HttpMethod.GET).send(l); - //Need to give 1st request a head start before request2 - Thread.sleep(500); - - //req2: should see servlet fully initialized by request1 - Request r2 = client.newRequest("http://localhost:" + port + "/r2"); - r2.method(HttpMethod.GET).send(l); + // Req1: should initialize servlet. + client.newRequest("http://localhost:" + port + "/r1").send(l); - l.awaitCompletion(); - - assertThat(results, is(array(equalTo(HttpStatus.OK_200), equalTo(HttpStatus.OK_200)))); + // Need to give 1st request a head start before request2. + Thread.sleep(DemoServlet.INIT_SLEEP / 4); + + // Req2: should see servlet fully initialized by request1. + client.newRequest("http://localhost:" + port + "/r2").send(l); + + assertTrue(resultsLatch.await(DemoServlet.INIT_SLEEP * 2, TimeUnit.MILLISECONDS)); + assertEquals(HttpStatus.OK_200, results[0]); + assertEquals(HttpStatus.OK_200, results[1]); } finally { - client.stop(); server.stop(); } } From acbc87a5daabce613b83a6f9190adae788de4c36 Mon Sep 17 00:00:00 2001 From: Lachlan Date: Fri, 29 Nov 2019 08:41:20 +1100 Subject: [PATCH 48/77] Issue #4341 - do not modify payload ByteBuffer sending WebSocket frames (#4359) - test that Frame buffer is unchanged after sending - Generator and FrameFlusher no longer modify frame payload - permessage-deflate no longer modify frame payload - remove Buffer allocation from Generator - outgoing autoFragment no longer modifies buffer - minor cleanups and optimizations from review Signed-off-by: Lachlan Roberts --- .../common/messages/MessageOutputStream.java | 5 +- .../websocket/javax/tests/NetworkFuzzer.java | 3 +- .../websocket/javax/tests/UnitGenerator.java | 2 - .../websocket/tests/WebSocketStatsTest.java | 12 +- .../core/internal/FragmentingFlusher.java | 12 +- .../core/internal/FrameCaptureExtension.java | 7 +- .../websocket/core/internal/FrameFlusher.java | 95 +++++----- .../websocket/core/internal/Generator.java | 162 +++++++----------- .../internal/PerMessageDeflateExtension.java | 4 +- .../core/internal/WebSocketConnection.java | 2 +- .../websocket/core/AutoFragmentTest.java | 15 +- .../jetty/websocket/core/FrameBufferTest.java | 116 +++++++++++++ .../core/GeneratorFrameFlagsTest.java | 5 +- ...java => GeneratorParserRoundTripTest.java} | 23 +-- .../jetty/websocket/core/GeneratorTest.java | 24 ++- .../core/OutgoingNetworkBytesCapture.java | 3 +- .../websocket/core/ParserReservedBitTest.java | 8 +- .../jetty/websocket/core/ParserTest.java | 48 +++--- .../websocket/core/WebSocketFrameTest.java | 43 +---- .../core/internal/FrameFlusherTest.java | 8 +- 20 files changed, 322 insertions(+), 275 deletions(-) create mode 100644 jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FrameBufferTest.java rename jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/{GeneratorParserRoundtripTest.java => GeneratorParserRoundTripTest.java} (81%) diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageOutputStream.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageOutputStream.java index 08399e92420..0e868f158ed 100644 --- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageOutputStream.java +++ b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/messages/MessageOutputStream.java @@ -117,6 +117,7 @@ public class MessageOutputStream extends OutputStream frame.setPayload(buffer); frame.setFin(fin); + int initialBufferSize = buffer.remaining(); try (SharedBlockingCallback.Blocker b = blocker.acquire()) { coreSession.sendFrame(frame, b, false); @@ -127,8 +128,8 @@ public class MessageOutputStream extends OutputStream // Any flush after the first will be a CONTINUATION frame. frame = new Frame(OpCode.CONTINUATION); - // Buffer has been sent, buffer should have been consumed - assert buffer.remaining() == 0; + // Buffer has been sent, but buffer should not have been consumed. + assert buffer.remaining() == initialBufferSize; BufferUtil.clearToFill(buffer); } diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java index 346a46503c2..4a9b7a14db1 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java +++ b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/NetworkFuzzer.java @@ -91,12 +91,11 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab public ByteBuffer asNetworkBuffer(List frames) { int bufferLength = frames.stream().mapToInt((f) -> f.getPayloadLength() + Generator.MAX_HEADER_LENGTH).sum(); - ByteBuffer buffer = ByteBuffer.allocate(bufferLength); + ByteBuffer buffer = BufferUtil.allocate(bufferLength); for (Frame f : frames) { generator.generate(buffer, f); } - BufferUtil.flipToFlush(buffer, 0); return buffer; } diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java index 10a4af1a6a8..f5554b23341 100644 --- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java +++ b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/UnitGenerator.java @@ -23,7 +23,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.core.Behavior; import org.eclipse.jetty.websocket.core.Frame; @@ -40,7 +39,6 @@ public class UnitGenerator extends Generator public UnitGenerator(Behavior behavior) { - super(new MappedByteBufferPool()); applyMask = (behavior == Behavior.CLIENT); } diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java index 2baa46a4f2f..0f12e3e754b 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketStatsTest.java @@ -24,10 +24,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.ConnectionStatistics; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.server.HttpConnection; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -112,12 +110,10 @@ public class WebSocketStatsTest long getFrameByteSize(Frame frame) { - ByteBufferPool bufferPool = new MappedByteBufferPool(); - Generator generator = new Generator(bufferPool); - ByteBuffer buffer = bufferPool.acquire(frame.getPayloadLength() + 10, true); - int pos = BufferUtil.flipToFill(buffer); - generator.generateWholeFrame(frame, buffer); - return buffer.position() - pos; + Generator generator = new Generator(); + ByteBuffer headerBuffer = BufferUtil.allocate(Generator.MAX_HEADER_LENGTH); + generator.generateHeader(frame, headerBuffer); + return headerBuffer.remaining() + frame.getPayloadLength(); } @Test diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java index a42745b318a..520b4c508fb 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java @@ -37,6 +37,7 @@ public abstract class FragmentingFlusher extends TransformingFlusher private static final Logger LOG = Log.getLogger(FragmentingFlusher.class); private final Configuration configuration; private FrameEntry current; + private ByteBuffer payload; public FragmentingFlusher(Configuration configuration) { @@ -56,9 +57,14 @@ public abstract class FragmentingFlusher extends TransformingFlusher } current = new FrameEntry(frame, callback, batch); + payload = frame.getPayload().slice(); + boolean finished = fragment(callback, true); if (finished) + { current = null; + payload = null; + } return finished; } @@ -67,14 +73,16 @@ public abstract class FragmentingFlusher extends TransformingFlusher { boolean finished = fragment(callback, false); if (finished) + { current = null; + payload = null; + } return finished; } private boolean fragment(Callback callback, boolean first) { Frame frame = current.frame; - ByteBuffer payload = frame.getPayload(); int remaining = payload.remaining(); long maxFrameSize = configuration.getMaxFrameSize(); int fragmentSize = (int)Math.min(remaining, maxFrameSize); @@ -87,7 +95,7 @@ public abstract class FragmentingFlusher extends TransformingFlusher // If we don't need to fragment just forward with original payload. if (finished) { - fragment.setPayload(frame.getPayload()); + fragment.setPayload(payload); forwardFrame(fragment, callback, current.batch); return true; } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameCaptureExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameCaptureExtension.java index 99b51b5b06c..c221e6f734b 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameCaptureExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameCaptureExtension.java @@ -27,7 +27,6 @@ import java.nio.file.Path; import java.util.Calendar; import java.util.concurrent.atomic.AtomicInteger; -import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; @@ -112,14 +111,12 @@ public class FrameCaptureExtension extends AbstractExtension } ByteBuffer buf = getBufferPool().acquire(BUFSIZE, false); - BufferUtil.flipToFill(buf); try { Frame f = Frame.copy(frame); f.setMask(null); // TODO is this needed? - generator.generateHeaderBytes(f, buf); - BufferUtil.flipToFlush(buf, 0); + generator.generateHeader(f, buf); channel.write(buf); if (frame.hasPayload()) { @@ -178,7 +175,7 @@ public class FrameCaptureExtension extends AbstractExtension incomingChannel = Files.newByteChannel(incomingFramesPath, CREATE, WRITE); outgoingChannel = Files.newByteChannel(outgoingFramesPath, CREATE, WRITE); - this.generator = new Generator(getBufferPool(), true); + this.generator = new Generator(); } catch (IOException e) { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java index a99e193d78f..d9538973363 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java @@ -64,6 +64,7 @@ public class FrameFlusher extends IteratingCallback private final List previousEntries; private final List failedEntries; + private List releasableBuffers = new ArrayList<>(); private ByteBuffer batchBuffer; private boolean canEnqueue = true; private boolean flushed = true; @@ -200,6 +201,7 @@ public class FrameFlusher extends IteratingCallback LOG.debug("Flushing {}", this); boolean flush = false; + Callback releasingCallback = this; synchronized (this) { if (closedCause != null) @@ -233,45 +235,64 @@ public class FrameFlusher extends IteratingCallback if (batch) { - // Acquire a batchBuffer if we don't have one + // Acquire a batchBuffer if we don't have one. if (batchBuffer == null) { batchBuffer = acquireBuffer(bufferSize); buffers.add(batchBuffer); } - // generate the frame into the batchBuffer - entry.generateHeaderBytes(batchBuffer); - ByteBuffer payload = entry.frame.getPayload(); - if (BufferUtil.hasContent(payload)) - BufferUtil.append(batchBuffer, payload); - } - else if (batchBuffer != null && batchSpace >= Generator.MAX_HEADER_LENGTH) - { - // Use the batch space for our header - entry.generateHeaderBytes(batchBuffer); - flush = true; - - // Add the payload to the list of buffers - ByteBuffer payload = entry.frame.getPayload(); - if (BufferUtil.hasContent(payload)) - buffers.add(payload); + // Generate the frame into the batchBuffer. + generator.generateWholeFrame(entry.frame, batchBuffer); } else { - // Add headers and payload to the list of buffers - // TODO: release this buffer. - ByteBuffer buffer = acquireBuffer(Generator.MAX_HEADER_LENGTH); - buffers.add(buffer); - entry.generateHeaderBytes(buffer); - flush = true; + if (batchBuffer != null && batchSpace >= Generator.MAX_HEADER_LENGTH) + { + // Use the batch space for our header. + generator.generateHeader(entry.frame, batchBuffer); + } + else + { + // Add headers to the list of buffers. + ByteBuffer headerBuffer = acquireBuffer(Generator.MAX_HEADER_LENGTH); + releasableBuffers.add(headerBuffer); + generator.generateHeader(entry.frame, headerBuffer); + buffers.add(headerBuffer); + } + + // Add the payload to the list of buffers. ByteBuffer payload = entry.frame.getPayload(); if (BufferUtil.hasContent(payload)) - buffers.add(payload); + { + if (entry.frame.isMasked()) + { + payload = acquireBuffer(entry.frame.getPayloadLength()); + releasableBuffers.add(payload); + generator.generatePayload(entry.frame, payload); + } + + buffers.add(payload.slice()); + } + flush = true; } flushed = flush; } + + // If we are going to flush we should release any buffers we have allocated after the callback completes. + if (flush) + { + final List callbackBuffers = releasableBuffers; + releasableBuffers = new ArrayList<>(); + releasingCallback = Callback.from(releasingCallback, () -> + { + for (ByteBuffer buffer : callbackBuffers) + { + bufferPool.release(buffer); + } + }); + } } if (LOG.isDebugEnabled()) @@ -288,7 +309,6 @@ public class FrameFlusher extends IteratingCallback if (entry.frame.getOpCode() == OpCode.CLOSE) endPoint.shutdownOutput(); notifyCallbackSuccess(entry.callback); - entry.release(); } previousEntries.clear(); @@ -310,7 +330,7 @@ public class FrameFlusher extends IteratingCallback bufferArray[i++] = bb; } bytesOut.add(bytes); - endPoint.write(this, bufferArray); + endPoint.write(releasingCallback, bufferArray); buffers.clear(); } else @@ -397,6 +417,12 @@ public class FrameFlusher extends IteratingCallback failedEntries.addAll(entries); entries.clear(); + for (ByteBuffer buffer : releasableBuffers) + { + bufferPool.release(buffer); + } + releasableBuffers.clear(); + if (closedCause == null) closedCause = failure; else if (closedCause != failure) @@ -406,7 +432,6 @@ public class FrameFlusher extends IteratingCallback for (Entry entry : failedEntries) { notifyCallbackFailure(entry.callback, failure); - entry.release(); } failedEntries.clear(); @@ -493,22 +518,6 @@ public class FrameFlusher extends IteratingCallback super(frame, callback, batch); } - private void generateHeaderBytes(ByteBuffer buffer) - { - int pos = BufferUtil.flipToFill(buffer); - generator.generateHeaderBytes(frame, buffer); - BufferUtil.flipToFlush(buffer, pos); - } - - private void release() - { - if (headerBuffer != null) - { - generator.getBufferPool().release(headerBuffer); - headerBuffer = null; - } - } - private long getTimeOfCreation() { return timeOfCreation; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Generator.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Generator.java index d2571bdeeb5..6eda2c16f5b 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Generator.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/Generator.java @@ -20,7 +20,6 @@ package org.eclipse.jetty.websocket.core.internal; import java.nio.ByteBuffer; -import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.core.Frame; @@ -54,57 +53,27 @@ public class Generator * The overhead (maximum) for a framing header. Assuming a maximum sized payload with masking key. */ public static final int MAX_HEADER_LENGTH = 28; - private static byte[] mask = {0x00, (byte)0xF0, 0x0F, (byte)0xFF}; - - public static void putMask(ByteBuffer buffer) - { - buffer.put(mask, 0, mask.length); - } - - public static void putPayload(ByteBuffer buffer, byte[] payload) - { - int len = payload.length; - for (int i = 0; i < len; i++) - { - buffer.put((byte)(payload[i] ^ mask[i % 4])); - } - } - - private final ByteBufferPool bufferPool; - private final boolean readOnly; /** - * Construct Generator with provided policy and bufferPool - * - * @param bufferPool the buffer pool to use + * Generate the whole frame (header + payload copy) into a single ByteBuffer. + * @param frame the frame to generate. + * @param buffer the buffer to output the generated frame to. */ - public Generator(ByteBufferPool bufferPool) + public void generateWholeFrame(Frame frame, ByteBuffer buffer) { - this(bufferPool, false); + generateHeader(frame, buffer); + generatePayload(frame, buffer); } /** - * Construct Generator with provided policy and bufferPool - * - * @param bufferPool the buffer pool to use + * Generate the header bytes of a frame into a single ByteBuffer. + * @param frame the frame to generate. + * @param buffer the buffer to output the generated frame to. */ - public Generator(ByteBufferPool bufferPool, boolean readOnly) + public void generateHeader(Frame frame, ByteBuffer buffer) { - this.bufferPool = bufferPool; - this.readOnly = readOnly; - } + int pos = BufferUtil.flipToFill(buffer); - public ByteBuffer generateHeaderBytes(Frame frame) - { - ByteBuffer buffer = bufferPool.acquire(MAX_HEADER_LENGTH, false); - BufferUtil.clearToFill(buffer); - generateHeaderBytes(frame, buffer); - BufferUtil.flipToFlush(buffer, 0); - return buffer; - } - - public void generateHeaderBytes(Frame frame, ByteBuffer buffer) - { /* * start the generation process */ @@ -177,68 +146,63 @@ public class Generator } // masking key - if (frame.isMasked() && !readOnly) - { - byte[] mask = frame.getMask(); - buffer.put(mask); - int maskInt = 0; - for (byte maskByte : mask) - { - maskInt = (maskInt << 8) + (maskByte & 0xFF); - } + if (frame.isMasked()) + buffer.put(frame.getMask()); - // perform data masking here - ByteBuffer payload = frame.getPayload(); - if ((payload != null) && (payload.remaining() > 0)) + BufferUtil.flipToFlush(buffer, pos); + } + + /** + * Generate the payload of a frame into a single ByteBuffer, if the frame has a mask the payload + * will be masked as it is copied to the output buffer. + * @param frame the frame to generate. + * @param buffer the buffer to output the generated frame to. + */ + public void generatePayload(Frame frame, ByteBuffer buffer) + { + ByteBuffer payload = frame.getPayload(); + if (!BufferUtil.hasContent(payload)) + return; + + int pos = BufferUtil.flipToFill(buffer); + if (frame.isMasked()) + maskPayload(buffer, frame); + else + buffer.put(payload.slice()); + BufferUtil.flipToFlush(buffer, pos); + } + + private void maskPayload(ByteBuffer buffer, Frame frame) + { + byte[] mask = frame.getMask(); + int maskInt = 0; + for (byte maskByte : mask) + { + maskInt = (maskInt << 8) + (maskByte & 0xFF); + } + + // perform data masking here + ByteBuffer payload = frame.getPayload(); + if ((payload != null) && (payload.remaining() > 0)) + { + int maskOffset = 0; + int start = payload.position(); + int end = payload.limit(); + int remaining; + while ((remaining = end - start) > 0) { - int maskOffset = 0; - int start = payload.position(); - int end = payload.limit(); - int remaining; - while ((remaining = end - start) > 0) + if (remaining >= 4) { - if (remaining >= 4) - { - payload.putInt(start, payload.getInt(start) ^ maskInt); - start += 4; - } - else - { - payload.put(start, (byte)(payload.get(start) ^ mask[maskOffset & 3])); - ++start; - ++maskOffset; - } + buffer.putInt(payload.getInt(start) ^ maskInt); + start += 4; + } + else + { + buffer.put((byte)(payload.get(start) ^ mask[maskOffset & 3])); + ++start; + ++maskOffset; } } } } - - /** - * Generate the whole frame (header + payload copy) into a single ByteBuffer. - *

- * Note: This is slow, moves lots of memory around. Only use this if you must (such as in unit testing). - * - * @param frame the frame to generate - * @param buf the buffer to output the generated frame to - */ - public void generateWholeFrame(Frame frame, ByteBuffer buf) - { - generateHeaderBytes(frame, buf); - if (frame.hasPayload()) - { - if (readOnly) - { - buf.put(frame.getPayload().slice()); - } - else - { - buf.put(frame.getPayload()); - } - } - } - - public ByteBufferPool getBufferPool() - { - return bufferPool; - } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/PerMessageDeflateExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/PerMessageDeflateExtension.java index 09cf17ac09c..3e79d933285 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/PerMessageDeflateExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/PerMessageDeflateExtension.java @@ -253,7 +253,7 @@ public class PerMessageDeflateExtension extends AbstractExtension _batch = batch; // Provide the frames payload as input to the Deflater. - getDeflater().setInput(frame.getPayload()); + getDeflater().setInput(frame.getPayload().slice()); callback.succeeded(); return false; } @@ -379,7 +379,7 @@ public class PerMessageDeflateExtension extends AbstractExtension incomingCompressed = false; // Provide the frames payload as input to the Inflater. - getInflater().setInput(_frame.getPayload()); + getInflater().setInput(_frame.getPayload().slice()); callback.succeeded(); return false; } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java index d0a7706c049..9b7d6766788 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java @@ -95,7 +95,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio this.coreSession = coreSession; - this.generator = new Generator(bufferPool); + this.generator = new Generator(); this.parser = new Parser(bufferPool, coreSession); this.flusher = new Flusher(scheduler, coreSession.getOutputBufferSize(), generator, endp); this.setInputBufferSize(coreSession.getInputBufferSize()); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java index 7356e4fed6f..db05b7180b5 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java @@ -89,9 +89,11 @@ public class AutoFragmentTest // Send a message which is too large. int size = maxFrameSize * 2; - byte[] message = new byte[size]; - Arrays.fill(message, 0, size, (byte)'X'); - clientHandler.coreSession.sendFrame(new Frame(OpCode.BINARY, BufferUtil.toBuffer(message)), Callback.NOOP, false); + byte[] array = new byte[size]; + Arrays.fill(array, 0, size, (byte)'X'); + ByteBuffer message = BufferUtil.toBuffer(array); + Frame sentFrame = new Frame(OpCode.BINARY, BufferUtil.copy(message)); + clientHandler.coreSession.sendFrame(sentFrame, Callback.NOOP, false); // We should not receive any frames larger than the max frame size. // So our message should be split into two frames. @@ -108,6 +110,9 @@ public class AutoFragmentTest assertThat(frame.getPayloadLength(), is(maxFrameSize)); assertThat(frame.isFin(), is(true)); + // Original frame payload should not have been changed. + assertThat(sentFrame.getPayload(), is(message)); + clientHandler.sendClose(); assertTrue(serverHandler.closed.await(5, TimeUnit.SECONDS)); assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); @@ -290,7 +295,8 @@ public class AutoFragmentTest serverHandler.coreSession.setAutoFragment(true); // Send the payload which should be fragmented by the server permessage-deflate. - serverHandler.sendFrame(new Frame(OpCode.BINARY, BufferUtil.copy(payload)), Callback.NOOP, false); + ByteBuffer sendPayload = BufferUtil.copy(payload); + serverHandler.sendFrame(new Frame(OpCode.BINARY, sendPayload), Callback.NOOP, false); // Assemble the message from the fragmented frames. ByteBuffer message = BufferUtil.allocate(payload.remaining()*2); @@ -309,6 +315,7 @@ public class AutoFragmentTest // We received correct payload in 2 frames. assertThat(message, is(payload)); + assertThat(message, is(sendPayload)); assertThat(numFrames, is(2)); clientHandler.sendClose(); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FrameBufferTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FrameBufferTest.java new file mode 100644 index 00000000000..19e440f8dd0 --- /dev/null +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/FrameBufferTest.java @@ -0,0 +1,116 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 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.websocket.core; + +import java.nio.ByteBuffer; +import java.util.Objects; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.core.FrameHandler.CoreSession; +import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class FrameBufferTest extends WebSocketTester +{ + private WebSocketServer server; + private TestFrameHandler serverHandler = new TestFrameHandler(); + private WebSocketCoreClient client; + private WebSocketComponents components = new WebSocketComponents(); + + @BeforeEach + public void startup() throws Exception + { + WebSocketNegotiator negotiator = WebSocketNegotiator.from((negotiation) -> serverHandler); + server = new WebSocketServer(negotiator); + client = new WebSocketCoreClient(null, components); + + server.start(); + client.start(); + } + + @AfterEach + public void shutdown() throws Exception + { + server.start(); + client.start(); + } + + @Test + public void testSingleFrame() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture connect = client.connect(clientHandler, server.getUri()); + connect.get(5, TimeUnit.SECONDS); + + ByteBuffer message = BufferUtil.toBuffer("hello world"); + ByteBuffer sendPayload = BufferUtil.copy(message); + clientHandler.sendFrame(new Frame(OpCode.BINARY, sendPayload), Callback.NOOP, false); + + Frame frame = Objects.requireNonNull(serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS)); + + assertThat(frame.getOpCode(), is(OpCode.BINARY)); + assertThat(frame.getPayload(), is(message)); + assertThat(sendPayload, is(message)); + + clientHandler.sendClose(); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + } + + @Test + public void testSendSameFrameMultipleTimes() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + client.connect(clientHandler, server.getUri()).get(5, TimeUnit.SECONDS); + serverHandler.open.await(5, TimeUnit.SECONDS); + clientHandler.coreSession.setAutoFragment(false); + serverHandler.coreSession.setAutoFragment(false); + + int payloadLen = 32 * 1024; + byte[] array = new byte[payloadLen]; + new Random().nextBytes(array); + ByteBuffer message = ByteBuffer.wrap(array); + + Frame frame = new Frame(OpCode.BINARY, BufferUtil.copy(message)); + for (int i = 0; i < 200; i++) + { + clientHandler.sendFrame(frame, Callback.NOOP, false); + Frame recvFrame = Objects.requireNonNull(serverHandler.receivedFrames.poll(5, TimeUnit.SECONDS)); + assertThat(recvFrame.getOpCode(), is(OpCode.BINARY)); + assertThat(recvFrame.getPayload(), is(message)); + assertThat(frame.getPayload(), is(message)); + } + + clientHandler.sendClose(); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + } +} \ No newline at end of file diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorFrameFlagsTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorFrameFlagsTest.java index 93aba40780d..e21ce49fefe 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorFrameFlagsTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorFrameFlagsTest.java @@ -22,6 +22,7 @@ import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.stream.Stream; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.core.internal.ExtensionStack; import org.eclipse.jetty.websocket.core.internal.Generator; import org.eclipse.jetty.websocket.core.internal.Negotiated; @@ -71,8 +72,8 @@ public class GeneratorFrameFlagsTest { setup(invalidFrame); - ByteBuffer buffer = ByteBuffer.allocate(100); - new Generator(components.getBufferPool()).generateWholeFrame(invalidFrame, buffer); + ByteBuffer buffer = BufferUtil.allocate(100); + new Generator().generateWholeFrame(invalidFrame, buffer); assertThrows(ProtocolException.class, () -> coreSession.assertValidOutgoing(invalidFrame)); } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundtripTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundTripTest.java similarity index 81% rename from jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundtripTest.java rename to jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundTripTest.java index 49177bf6db6..6a6dfda76ef 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundtripTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundTripTest.java @@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.core.internal.Generator; import org.junit.jupiter.api.Test; @@ -32,14 +31,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertTrue; -public class GeneratorParserRoundtripTest +public class GeneratorParserRoundTripTest { private ByteBufferPool bufferPool = new MappedByteBufferPool(); @Test public void testParserAndGenerator() throws Exception { - Generator gen = new Generator(bufferPool); + Generator gen = new Generator(); ParserCapture capture = new ParserCapture(); String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"; @@ -48,15 +47,11 @@ public class GeneratorParserRoundtripTest try { // Generate Buffer - BufferUtil.flipToFill(out); Frame frame = new Frame(OpCode.TEXT).setPayload(message); - ByteBuffer header = gen.generateHeaderBytes(frame); - ByteBuffer payload = frame.getPayload(); - out.put(header); - out.put(payload); + gen.generateHeader(frame, out); + gen.generatePayload(frame, out); // Parse Buffer - BufferUtil.flipToFlush(out, 0); capture.parse(out); } finally @@ -72,13 +67,12 @@ public class GeneratorParserRoundtripTest @Test public void testParserAndGeneratorMasked() throws Exception { - Generator gen = new Generator(bufferPool); + Generator gen = new Generator(); ParserCapture capture = new ParserCapture(true, Behavior.SERVER); String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"; ByteBuffer out = bufferPool.acquire(8192, false); - BufferUtil.flipToFill(out); try { // Setup Frame @@ -90,13 +84,10 @@ public class GeneratorParserRoundtripTest frame.setMask(mask); // Generate Buffer - ByteBuffer header = gen.generateHeaderBytes(frame); - ByteBuffer payload = frame.getPayload(); - out.put(header); - out.put(payload); + gen.generateHeader(frame, out); + gen.generatePayload(frame, out); // Parse Buffer - BufferUtil.flipToFlush(out, 0); capture.parse(out); } finally diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorTest.java index fec7167ae8f..28d8c8364dd 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/GeneratorTest.java @@ -24,7 +24,6 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.toolchain.test.ByteBufferAssert; import org.eclipse.jetty.toolchain.test.Hex; import org.eclipse.jetty.util.BufferUtil; @@ -46,7 +45,7 @@ public class GeneratorTest { private static final Logger LOG = Log.getLogger(Helper.class); - private static Generator generator = new Generator(new MappedByteBufferPool()); + private static Generator generator = new Generator(); private static WebSocketCoreSession coreSession = newWebSocketCoreSession(Behavior.SERVER); private static WebSocketCoreSession newWebSocketCoreSession(Behavior behavior) @@ -1270,26 +1269,26 @@ public class GeneratorTest completeBufSize += Generator.MAX_HEADER_LENGTH + f.getPayloadLength(); } - ByteBuffer completeBuf = ByteBuffer.allocate(completeBufSize); - BufferUtil.clearToFill(completeBuf); + ByteBuffer completeBuf = BufferUtil.allocate(completeBufSize); // Generate from all frames for (Frame f : frames) { - ByteBuffer header = generator.generateHeaderBytes(f); - totalBytes += BufferUtil.put(header, completeBuf); + int remaining = completeBuf.remaining(); + generator.generateHeader(f, completeBuf); + totalBytes += completeBuf.remaining() - remaining; - if (f.hasPayload()) + remaining = completeBuf.remaining(); + generator.generatePayload(f, completeBuf); + + if (completeBuf.remaining() - remaining > 0) { - ByteBuffer payload = f.getPayload(); - totalBytes += payload.remaining(); + totalBytes += completeBuf.remaining() - remaining; totalParts++; - completeBuf.put(payload.slice()); } } // Return results - BufferUtil.flipToFlush(completeBuf, 0); return completeBuf; } } @@ -1323,9 +1322,8 @@ public class GeneratorTest private static ByteBuffer generate(Frame... frames) { int length = Arrays.stream(frames).mapToInt(frame -> frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH).sum(); - ByteBuffer buffer = ByteBuffer.allocate(length); + ByteBuffer buffer = BufferUtil.allocate(length); Arrays.stream(frames).forEach(frame -> generator.generateWholeFrame(frame, buffer)); - BufferUtil.flipToFlush(buffer, 0); return buffer; } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingNetworkBytesCapture.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingNetworkBytesCapture.java index dd7759ace9b..6129bce6397 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingNetworkBytesCapture.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/OutgoingNetworkBytesCapture.java @@ -62,9 +62,8 @@ public class OutgoingNetworkBytesCapture implements OutgoingFrames @Override public void sendFrame(Frame frame, Callback callback, boolean batch) { - ByteBuffer buf = ByteBuffer.allocate(Generator.MAX_HEADER_LENGTH + frame.getPayloadLength()); + ByteBuffer buf = BufferUtil.allocate(Generator.MAX_HEADER_LENGTH + frame.getPayloadLength()); generator.generateWholeFrame(frame, buf); - BufferUtil.flipToFlush(buf, 0); captured.add(buf); if (callback != null) { diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserReservedBitTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserReservedBitTest.java index 119250d3378..6cd16a093a6 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserReservedBitTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserReservedBitTest.java @@ -23,8 +23,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.core.internal.Generator; @@ -40,19 +38,15 @@ import static org.junit.jupiter.api.Assertions.assertThrows; */ public class ParserReservedBitTest { - private ByteBufferPool bufferPool = new MappedByteBufferPool(); - private void expectProtocolException(List frames) { ParserCapture parserCapture = new ParserCapture(); // generate raw bytebuffer of provided frames int size = frames.stream().mapToInt(frame -> frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH).sum(); + Generator generator = new Generator(); ByteBuffer raw = BufferUtil.allocate(size); - BufferUtil.clearToFill(raw); - Generator generator = new Generator(bufferPool); frames.forEach(frame -> generator.generateWholeFrame(frame, raw)); - BufferUtil.flipToFlush(raw, 0); // parse buffer try (StacklessLogging ignore = new StacklessLogging(Parser.class)) diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserTest.java index d3aa8f058ef..f7dee5b749b 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/ParserTest.java @@ -25,7 +25,6 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.toolchain.test.Hex; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; @@ -50,6 +49,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class ParserTest { private static final int MAX_ALLOWED_FRAME_SIZE = 4 * 1024 * 1024; + private static final byte[] mask = {0x00, (byte)0xF0, 0x0F, (byte)0xFF}; + + public static void putPayload(ByteBuffer buffer, byte[] payload) + { + int len = payload.length; + for (int i = 0; i < len; i++) + { + buffer.put((byte)(payload[i] ^ mask[i % 4])); + } + } private ParserCapture parse(Behavior behavior, int maxAllowedFrameSize, ByteBuffer buffer) { @@ -83,8 +92,8 @@ public class ParserTest buffer.put(b); if (masked) { - Generator.putMask(buffer); - Generator.putPayload(buffer, messageBytes); + buffer.put(mask); + putPayload(buffer, messageBytes); } else { @@ -1296,8 +1305,8 @@ public class ParserTest buf.put((byte)0x81); // text frame, fin = true buf.put((byte)(0x80 | 0x7E)); // 0x7E == 126 (a 2 byte payload length) buf.putShort((short)utf.length); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = new ParserCapture(true, Behavior.SERVER); @@ -1325,8 +1334,8 @@ public class ParserTest buf.put((byte)0x81); // text frame, fin = true buf.put((byte)(0x80 | 0x7F)); // 0x7F == 127 (a 8 byte payload length) buf.putLong(utf.length); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = parse(Behavior.SERVER, 100000, buf, true); @@ -1397,8 +1406,8 @@ public class ParserTest buf.put((byte)0x81); buf.put((byte)(0x80 | 0x7E)); // 0x7E == 126 (a 2 byte payload length) buf.putShort((short)utf.length); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = parse(Behavior.SERVER, MAX_ALLOWED_FRAME_SIZE, buf, true); @@ -1417,8 +1426,8 @@ public class ParserTest ByteBuffer buf = ByteBuffer.allocate(24); buf.put((byte)0x81); buf.put((byte)(0x80 | utf.length)); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = parse(Behavior.SERVER, MAX_ALLOWED_FRAME_SIZE, buf, true); @@ -1442,14 +1451,14 @@ public class ParserTest // part 1 buf.put((byte)0x01); // no fin + text buf.put((byte)(0x80 | b1.length)); - Generator.putMask(buf); - Generator.putPayload(buf, b1); + buf.put(mask); + putPayload(buf, b1); // part 2 buf.put((byte)0x80); // fin + continuation buf.put((byte)(0x80 | b2.length)); - Generator.putMask(buf); - Generator.putPayload(buf, b2); + buf.put(mask); + putPayload(buf, b2); buf.flip(); @@ -1473,8 +1482,8 @@ public class ParserTest ByteBuffer buf = ByteBuffer.allocate(24); buf.put((byte)0x81); buf.put((byte)(0x80 | utf.length)); - Generator.putMask(buf); - Generator.putPayload(buf, utf); + buf.put(mask); + putPayload(buf, utf); buf.flip(); ParserCapture capture = parse(Behavior.SERVER, MAX_ALLOWED_FRAME_SIZE, buf, true); @@ -1650,13 +1659,12 @@ public class ParserTest private ByteBuffer generate(Behavior behavior, List frames) { - Generator generator = new Generator(new MappedByteBufferPool()); + Generator generator = new Generator(); int length = frames.stream().mapToInt(frame -> frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH).sum(); - ByteBuffer buffer = ByteBuffer.allocate(length); + ByteBuffer buffer = BufferUtil.allocate(length); frames.stream() .peek(frame -> maskIfClient(behavior, frame)) .forEach(frame -> generator.generateWholeFrame(frame, buffer)); - BufferUtil.flipToFlush(buffer, 0); return buffer; } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketFrameTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketFrameTest.java index 13f0f3b5daf..2bce17a25f2 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketFrameTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketFrameTest.java @@ -20,14 +20,10 @@ package org.eclipse.jetty.websocket.core; import java.nio.ByteBuffer; -import org.eclipse.jetty.io.LeakTrackingByteBufferPool; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.toolchain.test.Hex; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.websocket.core.internal.Generator; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -36,50 +32,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class WebSocketFrameTest { - public LeakTrackingByteBufferPool bufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged()); - - @AfterEach - public void afterEach() - { - String id = WebSocketFrameTest.class.getSimpleName(); - assertThat("Leaked Acquires Count for [" + id + "]", bufferPool.getLeakedAcquires(), is(0L)); - assertThat("Leaked Releases Count for [" + id + "]", bufferPool.getLeakedReleases(), is(0L)); - assertThat("Leaked Resource Count for [" + id + "]", bufferPool.getLeakedResources(), is(0L)); - } - - private Generator generator; + private Generator generator = new Generator(); private ByteBuffer generateWholeFrame(Generator generator, Frame frame) { - ByteBuffer buf = ByteBuffer.allocate(frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH); + ByteBuffer buf = BufferUtil.allocate(frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH); generator.generateWholeFrame(frame, buf); - BufferUtil.flipToFlush(buf, 0); return buf; } - @BeforeEach - public void initGenerator() - { - generator = new Generator(bufferPool); - } - - @AfterEach - public void verifyNoLeaks() - { - //TODO is this right and should it be other way around - bufferPool.clearTracking(); - assertNoLeaks(bufferPool); - } - - public void assertNoLeaks(LeakTrackingByteBufferPool pool) - { - String id = this.getClass().getName(); - - assertThat("Leaked Acquires Count for [" + id + "]", pool.getLeakedAcquires(), is(0L)); - assertThat("Leaked Releases Count for [" + id + "]", pool.getLeakedReleases(), is(0L)); - assertThat("Leaked Resource Count for [" + id + "]", pool.getLeakedResources(), is(0L)); - } - private void assertFrameHex(String message, String expectedHex, ByteBuffer actual) { String actualHex = Hex.asHex(actual); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/FrameFlusherTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/FrameFlusherTest.java index 56379ce94a8..25fb27171b1 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/FrameFlusherTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/internal/FrameFlusherTest.java @@ -79,7 +79,7 @@ public class FrameFlusherTest @Test public void testPostCloseFrameCallbacks() throws ExecutionException, InterruptedException, TimeoutException { - Generator generator = new Generator(bufferPool); + Generator generator = new Generator(); CapturingEndPoint endPoint = new CapturingEndPoint(bufferPool); int bufferSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; int maxGather = 1; @@ -110,7 +110,7 @@ public class FrameFlusherTest @Test public void testLargeSmallText() throws ExecutionException, InterruptedException { - Generator generator = new Generator(bufferPool); + Generator generator = new Generator(); CapturingEndPoint endPoint = new CapturingEndPoint(bufferPool); int bufferSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; int maxGather = 8; @@ -161,7 +161,7 @@ public class FrameFlusherTest @Test public void testWriteTimeout() throws Exception { - Generator generator = new Generator(bufferPool); + Generator generator = new Generator(); BlockingEndpoint endPoint = new BlockingEndpoint(bufferPool); int bufferSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; int maxGather = 8; @@ -193,7 +193,7 @@ public class FrameFlusherTest @Test public void testErrorClose() throws Exception { - Generator generator = new Generator(bufferPool); + Generator generator = new Generator(); BlockingEndpoint endPoint = new BlockingEndpoint(bufferPool); endPoint.setBlockTime(100); int bufferSize = WebSocketConstants.DEFAULT_MAX_TEXT_MESSAGE_SIZE; From afb81ed7389051fe418c81cce93c1619b75e3a61 Mon Sep 17 00:00:00 2001 From: Lachlan Date: Mon, 2 Dec 2019 08:45:32 +1100 Subject: [PATCH 49/77] Issue #4349 - test client negotiation of internal extensions (#4355) Added tests for WebSocket client negotiation of requested internal extensions. Changed the algorithm to remove from the requested list rather than add to the negotiated one. Fixed other issues with the parsing of ExtensionConfig not giving correct errors for invalid content. --- .../websocket/core/AbstractExtension.java | 14 +++- .../jetty/websocket/core/ExtensionConfig.java | 70 +++++++--------- .../core/client/ClientUpgradeRequest.java | 31 +++++-- .../server/internal/AbstractHandshaker.java | 2 +- ...org.eclipse.jetty.websocket.core.Extension | 3 +- .../core/WebSocketNegotiationTest.java | 80 ++++++++++++++++++- .../core/extensions/ExtensionConfigTest.java | 26 ++++++ 7 files changed, 171 insertions(+), 55 deletions(-) diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/AbstractExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/AbstractExtension.java index 6f50cc5d4fb..e3c629d5e67 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/AbstractExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/AbstractExtension.java @@ -29,7 +29,7 @@ import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; @ManagedObject("Abstract Extension") -public abstract class AbstractExtension implements Extension +public class AbstractExtension implements Extension { private final Logger log; private ByteBufferPool bufferPool; @@ -54,6 +54,18 @@ public abstract class AbstractExtension implements Extension this.inflaterPool = components.getInflaterPool(); } + @Override + public void onFrame(Frame frame, Callback callback) + { + nextIncomingFrame(frame, callback); + } + + @Override + public void sendFrame(Frame frame, Callback callback, boolean batch) + { + nextOutgoingFrame(frame, callback, batch); + } + public ByteBufferPool getBufferPool() { return bufferPool; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ExtensionConfig.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ExtensionConfig.java index 818b355b9c0..22da3507256 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ExtensionConfig.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/ExtensionConfig.java @@ -30,6 +30,7 @@ import java.util.stream.Collectors; import org.eclipse.jetty.http.QuotedCSV; import org.eclipse.jetty.util.ArrayTrie; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Trie; /** @@ -162,16 +163,9 @@ public class ExtensionConfig public ExtensionConfig(String parameterizedName) { ParamParser paramParser = new ParamParser(parameterizedName); - List keys = paramParser.parse(); - - if (keys.size() > 1) - throw new IllegalStateException("parameterizedName contains multiple ExtensionConfigs: " + parameterizedName); - if (keys.isEmpty()) - throw new IllegalStateException("parameterizedName contains no ExtensionConfigs: " + parameterizedName); - - this.name = keys.get(0); - this.parameters = new HashMap<>(); - this.parameters.putAll(paramParser.params.get(this.name)); + paramParser.parse(); + this.name = paramParser.getName(); + this.parameters = paramParser.getParams(); } public boolean isInternalExtension() @@ -319,17 +313,29 @@ public class ExtensionConfig private static class ParamParser extends QuotedCSV { - Map> params; + private final String parameterizedName; + private String name; + private Map params = new HashMap<>(); - public ParamParser(String rawParams) + public ParamParser(String parameterizedName) { - super(false, rawParams); + super(false); + this.parameterizedName = parameterizedName; + } + + public String getName() + { + return name; + } + + public Map getParams() + { + return params; } @Override protected void parsedParam(StringBuffer buffer, int valueLength, int paramNameIdx, int paramValueIdx) { - String extName = buffer.substring(0, valueLength); String paramName = ""; String paramValue = null; @@ -343,9 +349,7 @@ public class ExtensionConfig paramName = buffer.substring(paramNameIdx); } - Map paramMap = getParamMap(extName); - paramMap.put(paramName, paramValue); - + params.put(paramName, paramValue); super.parsedParam(buffer, valueLength, paramNameIdx, paramValueIdx); } @@ -353,35 +357,17 @@ public class ExtensionConfig protected void parsedValue(StringBuffer buffer) { String extName = buffer.toString(); - getParamMap(extName); + if (name != null) + throw new IllegalArgumentException("parameterizedName contains multiple ExtensionConfigs: " + parameterizedName); + name = extName; super.parsedValue(buffer); } - private Map getParamMap(String extName) + public void parse() { - if (params == null) - { - params = new HashMap<>(); - } - - Map paramMap = params.get(extName); - if (paramMap == null) - { - paramMap = new HashMap<>(); - params.put(extName, paramMap); - } - return paramMap; - } - - public List parse() - { - Iterator iter = iterator(); - while (iter.hasNext()) - { - iter.next(); - } - - return new ArrayList<>(params.keySet()); + addValue(parameterizedName); + if (StringUtil.isEmpty(name)) + throw new IllegalArgumentException("parameterizedName contains no ExtensionConfigs: " + parameterizedName); } } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java index ad29454b843..aa61f1c62ea 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -332,14 +333,28 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon } } - // Put requested internal Extensions into the negotiatedExtension list. - int i = 0; - for (ExtensionConfig reqConfig : requestedExtensions) + // Get list of negotiated extensions with internal extensions in the correct order. + List negotiatedWithInternal = new ArrayList<>(requestedExtensions); + for (Iterator iterator = negotiatedWithInternal.iterator(); iterator.hasNext();) { - if (reqConfig.isInternalExtension()) - negotiatedExtensions.add(i++, reqConfig); - else if (i < negotiatedExtensions.size() && reqConfig.getName().equals(negotiatedExtensions.get(i).getName())) - i++; + ExtensionConfig extConfig = iterator.next(); + + // Always keep internal extensions. + if (extConfig.isInternalExtension()) + continue; + + // If it was not negotiated by the server remove. + long negExtsCount = negotiatedExtensions.stream().filter(ec -> extConfig.getName().equals(ec.getName())).count(); + if (negExtsCount < 1) + { + iterator.remove(); + continue; + } + + // Remove if we have duplicates. + long duplicateCount = negotiatedWithInternal.stream().filter(ec -> extConfig.getName().equals(ec.getName())).count(); + if (duplicateCount > 1) + iterator.remove(); } // Verify the Negotiated Extensions @@ -372,7 +387,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon // Negotiate the extension stack ExtensionStack extensionStack = new ExtensionStack(wsClient.getWebSocketComponents(), Behavior.CLIENT); - extensionStack.negotiate(requestedExtensions, negotiatedExtensions); + extensionStack.negotiate(requestedExtensions, negotiatedWithInternal); // Get the negotiated subprotocol String negotiatedSubProtocol = null; diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java index 0eff2f5e3c4..6647862e817 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java @@ -62,7 +62,7 @@ public abstract class AbstractHandshaker implements Handshaker if (!validateRequest(request)) return false; - Negotiation negotiation = newNegotiation(request, response, new WebSocketComponents()); + Negotiation negotiation = newNegotiation(request, response, negotiator.getWebSocketComponents()); if (LOG.isDebugEnabled()) LOG.debug("negotiation {}", negotiation); negotiation.negotiate(); diff --git a/jetty-websocket/websocket-core/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.core.Extension b/jetty-websocket/websocket-core/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.core.Extension index 517a1ba17df..1e4404b3a0d 100644 --- a/jetty-websocket/websocket-core/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.core.Extension +++ b/jetty-websocket/websocket-core/src/main/resources/META-INF/services/org.eclipse.jetty.websocket.core.Extension @@ -1,4 +1,5 @@ org.eclipse.jetty.websocket.core.internal.IdentityExtension org.eclipse.jetty.websocket.core.internal.FragmentExtension +org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension org.eclipse.jetty.websocket.core.internal.ValidationExtension -org.eclipse.jetty.websocket.core.internal.PerMessageDeflateExtension \ No newline at end of file +org.eclipse.jetty.websocket.core.internal.FrameCaptureExtension \ No newline at end of file diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java index 9e4e3e0cce6..e09b15a39ce 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; import org.eclipse.jetty.client.HttpRequest; import org.eclipse.jetty.client.HttpResponse; @@ -34,16 +35,21 @@ import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.core.FrameHandler.CoreSession; import org.eclipse.jetty.websocket.core.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.core.client.UpgradeListener; import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient; +import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession; import org.eclipse.jetty.websocket.core.server.Negotiation; import org.eclipse.jetty.websocket.core.server.WebSocketNegotiator; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; @@ -69,11 +75,12 @@ public class WebSocketNegotiationTest extends WebSocketTester private WebSocketServer server; private WebSocketCoreClient client; + private WebSocketComponents components = new WebSocketComponents(); @BeforeEach public void startup() throws Exception { - WebSocketNegotiator negotiator = new WebSocketNegotiator.AbstractNegotiator() + WebSocketNegotiator negotiator = new WebSocketNegotiator.AbstractNegotiator(components, null) { @Override public FrameHandler negotiate(Negotiation negotiation) throws IOException @@ -120,7 +127,7 @@ public class WebSocketNegotiationTest extends WebSocketTester }; server = new WebSocketServer(negotiator); - client = new WebSocketCoreClient(); + client = new WebSocketCoreClient(null, components); server.start(); client.start(); @@ -353,4 +360,73 @@ public class WebSocketNegotiationTest extends WebSocketTester assertThat(response, containsString("400 Bad Request")); } + + public static Stream internalExtensionScenarios() throws Exception + { + return Stream.of( + Arguments.of("", ""), + Arguments.of("ext1", "ext1"), + Arguments.of("@int1", "@int1"), + Arguments.of("ext1, ext1", "ext1"), + Arguments.of("ext1, @int1", "ext1, @int1"), + Arguments.of("@int1, ext1", "@int1, ext1"), + Arguments.of("@int1, @int1", "@int1, @int1"), + Arguments.of("@int1, ext1, ext2", "@int1, ext1, ext2"), + Arguments.of("ext1, @int1, ext2", "ext1, @int1, ext2"), + Arguments.of("ext1, ext2, @int1", "ext1, ext2, @int1"), + Arguments.of("@int1, ext1, @int2, ext2, @int3", "@int1, ext1, @int2, ext2, @int3"), + Arguments.of("ext1, ext1, ext1, @int1, ext2", "ext1, @int1, ext2"), + Arguments.of("ext1, @int1, ext1, ext1, ext2", "@int1, ext1, ext2"), + Arguments.of("ext1, ext2, ext3, @int1", "ext1, ext2, ext3, @int1") + ); + } + + @ParameterizedTest + @MethodSource("internalExtensionScenarios") + public void testClientRequestedInternalExtensions(String reqExts, String negExts) throws Exception + { + // Add some simple Extensions for to make test examples clearer. + WebSocketExtensionRegistry extRegistry = components.getExtensionRegistry(); + extRegistry.register("ext1", AbstractExtension.class); + extRegistry.register("ext2", AbstractExtension.class); + extRegistry.register("ext3", AbstractExtension.class); + extRegistry.register("@int1", AbstractExtension.class); + extRegistry.register("@int2", AbstractExtension.class); + extRegistry.register("@int3", AbstractExtension.class); + + TestFrameHandler clientHandler = new TestFrameHandler(); + CompletableFuture extensionHeader = new CompletableFuture<>(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, server.getUri(), clientHandler); + upgradeRequest.setSubProtocols("test"); + if (!StringUtil.isEmpty(reqExts)) + upgradeRequest.addExtensions(reqExts.split(",")); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeResponse(HttpRequest request, HttpResponse response) + { + extensionHeader.complete(response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_EXTENSIONS)); + } + }); + + // Connect to the client then close the Session. + client.connect(upgradeRequest).get(5, TimeUnit.SECONDS); + clientHandler.sendClose(); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + + // We had no internal Extensions in the response headers. + assertThat(extensionHeader.get(5, TimeUnit.SECONDS), not(containsString("@"))); + + // The list of Extensions on the client contains the internal Extensions. + StringBuilder negotiatedExtensions = new StringBuilder(); + List extensions = ((WebSocketCoreSession)clientHandler.coreSession).getExtensionStack().getExtensions(); + for (int i = 0; i < extensions.size(); i++) + { + negotiatedExtensions.append(extensions.get(i).getConfig().getParameterizedName()); + if (i != extensions.size() - 1) + negotiatedExtensions.append(", "); + } + assertThat(negotiatedExtensions.toString(), is(negExts)); + } } diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionConfigTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionConfigTest.java index 20bbac1a2f3..2d9e8109b4c 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionConfigTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionConfigTest.java @@ -26,8 +26,10 @@ import org.eclipse.jetty.websocket.core.ExtensionConfig; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; public class ExtensionConfigTest { @@ -158,4 +160,28 @@ public class ExtensionConfigTest assertThat("Configs[1]", configs.get(1).getName(), is("identity")); assertThat("Configs[2]", configs.get(2).getName(), is("capture")); } + + @Test + public void testParseNoExtensions() + { + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> ExtensionConfig.parse("=params")); + assertThat(error.getMessage(), containsString("contains no ExtensionConfigs")); + } + + @Test + public void testParseMultipleExtensions() + { + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> ExtensionConfig.parse("ext1;param1, ext2;param2")); + assertThat(error.getMessage(), containsString("contains multiple ExtensionConfigs")); + } + + @Test + public void testParseMultipleExtensionsSameName() + { + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> ExtensionConfig.parse("ext1;paramOption1, ext1;paramOption2")); + assertThat(error.getMessage(), containsString("contains multiple ExtensionConfigs")); + } } From 60f00d43c8ab92a5ecdb77f3132d736cb82bd6f8 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 2 Dec 2019 10:23:18 -0600 Subject: [PATCH 50/77] Restoring date of release 10.0.0-alpha0 Signed-off-by: Joakim Erdfelt --- VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.txt b/VERSION.txt index a081f756bf9..72e410d847a 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -163,7 +163,7 @@ jetty-10.0.0.alpha1 - 26 November 2019 + 4334 Better test ErrorHandler changes + 4342 OpenID module cannot create HttpClient in Jetty 10 -jetty-10.0.0-alpha0 +jetty-10.0.0-alpha0 - 11 July 2019 + 113 Add support for NCSA Extended Log File Format + 114 Bring back overlay deployer + 132 ClientConnector abstraction From 666ee4ef600da97706a0b8cc6097951389e48391 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 2 Dec 2019 10:57:15 -0600 Subject: [PATCH 51/77] Issue #4385 - Remove UnsupportedOperationException in SslContextFactory Signed-off-by: Joakim Erdfelt --- .../org/eclipse/jetty/util/ssl/SslContextFactory.java | 10 +++++++++- .../java/org/eclipse/jetty/util/ssl/X509Test.java | 11 +++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index c81236f9b26..e75b1486bd3 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -1270,7 +1270,8 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable @Deprecated protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) { - throw new UnsupportedOperationException("X509ExtendedKeyManager only supported on Server"); + LOG.warn("Using Deprecated SslContextFactory implementation, SNI does not work in this context, use SslContextFactory.Server instead."); + return null; } protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection crls) throws Exception @@ -2178,6 +2179,13 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable checkEndPointIdentificationAlgorithm(); super.checkConfiguration(); } + + @Deprecated + protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) + { + // Overriding base implementation, as this context should have no WARN message. + return null; + } } @ManagedObject diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java index 2445a761831..8a0a25e03f3 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java @@ -26,10 +26,9 @@ import org.eclipse.jetty.util.resource.Resource; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.hamcrest.Matchers.nullValue; public class X509Test { @@ -161,8 +160,8 @@ public class X509Test { SslContextFactory baseSsl = new SslContextFactory(); X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(baseSsl); - UnsupportedOperationException npe = assertThrows(UnsupportedOperationException.class, () -> baseSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); - assertThat("UnsupportedOperationException.message", npe.getMessage(), containsString("X509ExtendedKeyManager only supported on Server")); + X509ExtendedKeyManager sniX509ExtendedKeyManager = baseSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager); + assertThat("SNI X509 ExtendedKeyManager is undefined in this context", sniX509ExtendedKeyManager, nullValue()); } @Test @@ -170,8 +169,8 @@ public class X509Test { SslContextFactory clientSsl = new SslContextFactory.Client(); X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(clientSsl); - UnsupportedOperationException re = assertThrows(UnsupportedOperationException.class, () -> clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); - assertThat("UnsupportedOperationException.message", re.getMessage(), containsString("X509ExtendedKeyManager only supported on Server")); + X509ExtendedKeyManager sniX509ExtendedKeyManager = clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager); + assertThat("SNI X509 ExtendedKeyManager is undefined in this context", sniX509ExtendedKeyManager, nullValue()); } @Test From e1d64af578a7270ac30dbd6eade1ca57aa79a1b5 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 2 Dec 2019 12:00:21 -0600 Subject: [PATCH 52/77] Issue #4385 - Minimize impact of deprecated SNI mode on base class Signed-off-by: Joakim Erdfelt --- .../java/org/eclipse/jetty/util/ssl/SslContextFactory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index e75b1486bd3..f707b050bd3 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -1271,7 +1271,7 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) { LOG.warn("Using Deprecated SslContextFactory implementation, SNI does not work in this context, use SslContextFactory.Server instead."); - return null; + return keyManager; } protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection crls) throws Exception @@ -2184,7 +2184,7 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) { // Overriding base implementation, as this context should have no WARN message. - return null; + return keyManager; } } From 816e34bddf137464ea0e6433315f49121d9d10d2 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 2 Dec 2019 12:13:13 -0600 Subject: [PATCH 53/77] Issue #4385 - Base Class usage now is a WARN logging event in SNI usage Signed-off-by: Joakim Erdfelt --- .../jetty/util/ssl/SslContextFactory.java | 16 ++++++++---- .../org/eclipse/jetty/util/ssl/X509Test.java | 23 +++++++++++++++--- .../src/test/resources/keystore_sni.p12 | Bin 0 -> 7412 bytes 3 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 jetty-util/src/test/resources/keystore_sni.p12 diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index f707b050bd3..e16018b27c7 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -1249,10 +1249,17 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable // Is SNI needed to select a certificate? if (!_certWilds.isEmpty() || _certHosts.size() > 1 || (_certHosts.size() == 1 && _aliasX509.size() > 1)) { - for (int idx = 0; idx < managers.length; idx++) + if (this instanceof SslContextFactory.Server) { - if (managers[idx] instanceof X509ExtendedKeyManager) - managers[idx] = newSniX509ExtendedKeyManager((X509ExtendedKeyManager)managers[idx]); + for (int idx = 0; idx < managers.length; idx++) + { + if (managers[idx] instanceof X509ExtendedKeyManager) + managers[idx] = newSniX509ExtendedKeyManager((X509ExtendedKeyManager)managers[idx]); + } + } + else + { + LOG.warn("Unable to support SNI on {} (expecting {})", this.getClass().getName(), SslContextFactory.Server.class.getName()); } } } @@ -1270,8 +1277,7 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable @Deprecated protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) { - LOG.warn("Using Deprecated SslContextFactory implementation, SNI does not work in this context, use SslContextFactory.Server instead."); - return keyManager; + throw new UnsupportedOperationException("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName()); } protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection crls) throws Exception diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java index 8a0a25e03f3..0faf28eb38d 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java @@ -18,17 +18,21 @@ package org.eclipse.jetty.util.ssl; +import java.nio.file.Path; import java.security.cert.X509Certificate; import javax.net.ssl.KeyManager; import javax.net.ssl.X509ExtendedKeyManager; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; public class X509Test { @@ -160,8 +164,19 @@ public class X509Test { SslContextFactory baseSsl = new SslContextFactory(); X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(baseSsl); - X509ExtendedKeyManager sniX509ExtendedKeyManager = baseSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager); - assertThat("SNI X509 ExtendedKeyManager is undefined in this context", sniX509ExtendedKeyManager, nullValue()); + UnsupportedOperationException npe = assertThrows(UnsupportedOperationException.class, () -> baseSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); + assertThat("UnsupportedOperationException.message", npe.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); + } + + @Test + public void testSniX509ExtendedKeyManager_BaseClass_Start() throws Exception + { + SslContextFactory baseSsl = new SslContextFactory(); + Path keystorePath = MavenTestingUtils.getTestResourcePathFile("keystore_sni.p12"); + baseSsl.setKeyStoreResource(new PathResource(keystorePath)); + baseSsl.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + baseSsl.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + baseSsl.start(); // should not throw an exception } @Test @@ -170,7 +185,7 @@ public class X509Test SslContextFactory clientSsl = new SslContextFactory.Client(); X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(clientSsl); X509ExtendedKeyManager sniX509ExtendedKeyManager = clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager); - assertThat("SNI X509 ExtendedKeyManager is undefined in this context", sniX509ExtendedKeyManager, nullValue()); + assertThat("SNI X509 ExtendedKeyManager is undefined in Client mode", sniX509ExtendedKeyManager, is(x509ExtendedKeyManager)); } @Test diff --git a/jetty-util/src/test/resources/keystore_sni.p12 b/jetty-util/src/test/resources/keystore_sni.p12 new file mode 100644 index 0000000000000000000000000000000000000000..fab22bd8eb807b6d8899e039c0d3e1a146391913 GIT binary patch literal 7412 zcmd6LXH-+sx-AI_0YqA)2|_@6O{fXd1f&Zp2m;ax5PAs+NJlzIQE5t(4uXIfnpA0m zAksuYIttReAms+jJs$5F=Z*V*yz`RmvG=#u-Xm+THNW}IHIG-0R|p6QfcOK9KL7+^ zC#((H6@R6nPqgw4-%|q*0=|Tk6Or-}0YCs=AQb=rCIAHivuFix^72Tt!|%G%o|s;h zqd6vSigJX+8FC^XyG0q@@I#NYdkk;cg0z-M7q~xJK1h^L8Z6uEY1BMS;PYbKyZ2^4 zeLoT&K`X%*tG~va&RmU36UvI=;WXZCqu_Ktj z-`WF?pqw)fmw9AvZQ}*J)(tDdjJ2OcA?Lw4c2}#4O75m%F`dJshYKH@>&cv%+`TDV z3_VroU#R&-Lc(;R51rEa_gc-&Q#r}r-)FQ*aHU&`TnL`?e8sG2^9*<#A2Ib|m7OUd zpywR6`HL8%{YFP3-TZ)e--Po?S+DUPKnG(su2C#JdpS=%DQU!+^5Sa3rhds`?-%XRACOEqVyzEP&!CR(Bwcn^$=$aj930RI{T5|J9e@sfShYU1*Cg1M7&Y|rpCdlAJI zMMBdgb*hgQX|uEb#tqtM7=@m)pGo3MviJ8qIiVy|FmBW zP-kb@loG|7Y)7`!%SDqgDwA%zu4{qiwsubo)8|A)So+7P#9vta#PcmdF*pj3;~+ea z{op}>FPVfu01ya5>)jHBpCuyU4OI!oc8n%LMX+ZJ9h-pKU)PYoE+fH zbY~G_a1mh%xG(~RKpFf9#f8Owh5wN;1!nv?Gx&Tb42&Uw2Sxw`0|^>5eQ#%mPcBJx z>Mq!r7-R^y0ru`TKQJp8#f4f4FTn)d*v^{L)b^w;%U^hFD4DvNVE4q&|8nw86E5AZ z&)_ocrs*NcYmW5`>IR}qPZbZBsJr%ISse>=9d*jhgUh`uS8r{|n-AL0^nF^nnv5I% z>X?1b8i!hdQpRWP&efxUga86SHY=P3egQwD7sx@hpmSS2peZ|yFx;L&#e+kN({zhr zj`Ghpz^^SKe(1#hEK&w_ZuBcHTOq9{o7G5b8sfe9qC%R+ePz=(TXE`(+SO?;_fw8C zKi-}I2+zVe{m!e^pGTT-zcuI3j9hrLlD~&LxxddO@XSd#NWHurxbmnEqUG_O^_yVV zxr*@4p~=k@2CF1tRD|6P+w2bA;{~nv-2|_SJL)0cnfIV!eJ6tj1G3Fl+I^ z#Qh6`eF_H22UnS|B(j1`t3PMI9(#&e=D5AbP>=&GS@t#`>J-G$8nPy-uca_WtSJf7 zM)})@JE>@~8ftN_mUw>TW+R({s)aWJm7IE4Tgxas-yrPVRGG8S^Wya| z_IJIuLXO*qmr`$HFgnJYQfqzM{35=p*_|aP@d+}m=zPft=ZmjN)kLBPCa|#^7|W0G zZEljdE#h_JCsyIj1>r&W$4f8OaZ9;tU`PgX=?3XSOfW6|Dl}VJ@%wC7-*N{ktdEp$ zX}!YIo)3#PbT4}@O~lk5e$LKjqR}g$Ol33coz2Sdafk`BYA+=sCH4D678CX;g+zZ6 zQ|*5>p@Z&GUvGloVTMjqnkgZ6*h=bWF2&y;Z1!7@)=N+UH z)|ql8#H?Z+rF2NdOY=S)Aq4++6lBinzhP=at*z5XsOr*Z!+xFEs}SYc)%49hf_R{? zr*$WIZwrs!Q^oL`VMFmi#1-mfr+MJ400BG$#2SL7eZwA-8Af)v?Q`|Z=pOgEKMJQi%o0DB z{<+gCj@X=NRFlst=e)?jV%Z%8pX>4+X&apcsZZ*8$JSN{g^&MQ-&2;QBRhFTy-<6% zco*>T3;g!l=E%N$_|g!LcC^1a-2Qra{#J99#aKHy&ZomFQ9PpCM~K-&bIv)8hoBUS z>vvsiEyTRLrbeK{RoS98*VZv=K7SHcSRnn;H`TXsCpb~2k~$72Z_e1ApeBAsMB_6% zNG-3q(M-!QA-gKrTYJ6^4@w{b#M;Ty%+m4)&ra^XtNw44625^45w_uxTJjU60D`|> z0Uj8PI0Gj+#S#$|cvJf~VDSRrvMa{h$vJ>n_C+vok6Bed`cEw_>FcxN5H0-iF*2c*dgY|+5 zz?6kgAqz+0zX| z?$t-RER0;A?6~~ov1?(?m7%WO;6wgiCzX+jAlm5uAf zogdYQ(9O&dUxm=tRj>y99+nUu1UjADzjmvjB?D3?lVSka%**^8;DXatcZD8mx+i@B zwQZgH^cEPykR>M@lZJP>nSBYhMEkc!84@~}=Prr7r3<;!EA(nUHy(0^Yl1Jdy-vm< zU{@)lMAOq&yw>pK+4{TbO02rLXX(%@d!!BhvVP%HZT4EvV|dh3X+(t;MV4S>w&KZ* zddP#&_c100=@Nw&3|i%%URZGIU9Nphg!Bw?YkiT57FDmSf`NB$Fitrr7tZuu;n~!$ zA=%cnlATng$AX2>)eDN*^RoTTK2<^{QZRr1VpkgW1KN>!eOIw~Q&^&lP+l#_L~P}p zWHV6A#hj1~VXIN!p+$w1>=9ZYE?3X4eTBUKh>y;YPApN~bozxCim3PpwhTx;0I{aRGS^ykM!`duAEYHboM0!<8Jsyj8LnXf16H2xu=a zq~%_(O!2<9MttN3o$_yY@drGEvOY|dcSkZfgpLJq5v4$xy0-7=iLG4e{vO{4i+Rs% z<|DSf>TaV+UW4|9JFFIexG`w?jr@|?1^&kkXwwbJzbYngMi0Kw7t?3*e@2_YxL}y zWT$Ko(lLPyZU(<<6UtD0B>I@Rkb2I-8nyH|Ll9*Yz!kd`4lpP-+6QM0y>|5K4&Q(B zfmCb$RhjBMSUFlOO;*;Mzasfl9qMlD!AEg7~^e%9nI1}P`^-D zNb6Nfv*fv}5It?B;=>!L2TGM=`7lP#?AV#tZQ{X_%~N*S2~SsMbGzr%YY1yo$40 zsqQ6;i#YaS>ehR~Z4bZK$Z@Vw26sdzdJSgGAs#(_LAO*CZHW#9Oq=cyhC0j<8y2=) z{eE5L%-C+~`i0m^Dgr~gKEBO~pnto17D^SepxS=~=$A%Q%vWmEV=ROg5|JndN*pZRV;=xcKa?XVg+&x*%?i z!X7?1ahE445*(&SY-GCM24eJ#D?5btvmu(1A2&bQ8z;m9dtiziF9>5pC7s=dJUWRW ze#ri%@jcqQb!mBzN*|P*cnXB$zOORR({LzDlE&%vpG>Yg)rmWKUuJ$|ThBpits zGvZ=+=L0Wogik~GukiozX#P(UCS=*8E62r%#iQgYcVjkF0qkD+k-|$Sua2UJzUw@} zB+WP1RjR*a(~|{RX^nF;*dwE4xf*)vViB3x9=Wi(`WA3D)^J13g*Qp&>=i)vjR$ zS5hkTYQ}3J_wB>n99;Kp9Nl2e6B42Y1)qtvU+5`Afh^#{x^`medkTfFe9}xhMgDho zj20BoRfCiENc-}>?z;Vf{`$euuxoiq3b2T+%E~LWHlXpRgi(ac|DjO0jHkCsuAe=yMUGQEQ8{uUJU$75vz{s( zDiB@=2c0=Jx$sMVDuIJY9DZN^1-l<2#wD+elZ;}5>^RibRF%+3;hC3<#eHjITW;v? z7Q~xdQx4|T2kSo&>`)N)3oJT3!dXf3?`#QYs``IVk#3R`EoAIKUDl4?=zc)rs|nJ1 z$gE{#cQ1`59(#Xl5u5Oi>utH2kqBzJQhj&RT}SI>6qVP!tXnL|;=#3JmOkS=$~*1{ zU!{g=t_+~*?_4=buE`-aHxVl^<9iG=UzEEZmq{YW zJs4RNmcw9pw)6V24s&wIW>EB`R(9H!JH_XkittDB-8&#xxb5&kVE*i+$tSI0qoR^W zoz@Wq!}_8$mb;YM72Bj!UbtW-6k?&w=*{X0u&Et5{S|DEMg_u@gC zD@nvKSP!b8KUUu;J;&tV$NIgDWdL{Ieo=_M;OjWsSFR5QDVZ`99FmfhIXm*VPTKS; zW)~%ScT?F>gUX0*G}w|uK4Cg+d5cuH6)Z5QX6&QfM)WA6iz|FWDkF^?t+P*ko)!fO zdagGp_M%1P3$g5#MTlOyBlHw_;sdZ^Lpg;!MD~3>|8%^ru9tM4FA*~fXzhu8{ zkeY^DbTlNl*cWO#P+heEa0KUh6OYNck@6NITeOc68~ldnyhfGCtQloZC030VaEIS# z>EtS8KA=bDuz}vB=`qK)zBMlA-k|e7+60cc(alHV_ERZvY$2KIG5#&}xhh`;R;wr< zs}R4U8l#KOD_L_RmYqm9WNg}x#cf0-x#F6a%}7r5UB%Y` zQSMOmwkwWWvndsP{&Uj2^I7}kyjnx}ImV6S^HIVBqXN$d9%-er^EJIBZHS$*yv;>n zmi#bTLh7iUoElEi?88gZ`VINY-hfY+eC*9cee98({?3K_jJ{&=%Pe9!0j8hS{b(o} zGc~+Jv-ub3R5W0r6G1Y0^C?9srEPiuTI*;Fr62 zxz$BvPaJjh+>bf>66!WnsnexPc&lq`WKgVcEP^GHzmU1F+j97w{ioss48Rv2AN+1` z{#WtQ-H5#Q7Yo2${x6HqAC}NBll@oAAGSLU9QvaGk&*EVS~@wHVSZ53FF!~Wj^9m- zAmQ*|evk%^TW;TA*0R4BEkv1Zd;*PiXPv%3meY}Z`M@>Ddbo~A#CWB!#H^piwmN__1DUtnnB7%ay3e*7@`BdF>i4N`dfjA0Y3S?+)*3_HJ5n}=%UH0 zRgGZ<_(Jtp@fto;SIOIQ?_WFe QCJTR literal 0 HcmV?d00001 From 5b1f9d5f159b385f3ca60f0ab47df165114f6d78 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 2 Dec 2019 12:15:02 -0600 Subject: [PATCH 54/77] Issue #4385 - Client no longer needs override. Signed-off-by: Joakim Erdfelt --- .../java/org/eclipse/jetty/util/ssl/SslContextFactory.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index e16018b27c7..f141b846bec 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -2185,13 +2185,6 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable checkEndPointIdentificationAlgorithm(); super.checkConfiguration(); } - - @Deprecated - protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) - { - // Overriding base implementation, as this context should have no WARN message. - return keyManager; - } } @ManagedObject From c9a65c4676dfac7f4eedf61d93ed3925e73b0bf9 Mon Sep 17 00:00:00 2001 From: Mat Booth Date: Mon, 2 Dec 2019 21:08:01 +0000 Subject: [PATCH 55/77] Allow building against newest version of maven-artifact-transfer (#4381) In later versions of maven-artifact-transfer the package names have been refactored, this change accomodates for that. Signed-off-by: Mat Booth --- jetty-maven-plugin/pom.xml | 10 +++++----- .../org/eclipse/jetty/maven/plugin/JettyRunDistro.java | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index 708e0a84fa1..69e598597a9 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -103,6 +103,11 @@ + + org.apache.maven.shared + maven-artifact-transfer + 0.11.0 + org.apache.maven maven-plugin-api @@ -124,11 +129,6 @@ maven-plugin-annotations provided - - org.apache.maven.shared - maven-artifact-transfer - 0.9.1 - org.eclipse.jetty jetty-util diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java index aa02c304aca..5e2640d786e 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java @@ -55,9 +55,9 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.shared.artifact.DefaultArtifactCoordinate; -import org.apache.maven.shared.artifact.resolve.ArtifactResolver; -import org.apache.maven.shared.artifact.resolve.ArtifactResolverException; +import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; From 85cda88b40c167cc4ab588ccbadfbfbc86c8e0d4 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 3 Dec 2019 08:50:36 +1100 Subject: [PATCH 56/77] Issue #4376 Async Content Complete (#4377) * Issue #4376 Async Content Complete Added test harness to reproduce unready completing write. Fixed test by not closing output prior to becoming READY Signed-off-by: Greg Wilkins * Issue #4376 Async Content Complete ERROR state still needs to be closed! Signed-off-by: Greg Wilkins * Issue #4376 Async Content Complete close after last blocking write Signed-off-by: Greg Wilkins * Issue #4376 Async Content Complete If completion has to do a flush, then we need a call to closed to avoid leaking buffers. Signed-off-by: Greg Wilkins * Issue #4376 Async Content Complete Reformat Signed-off-by: Greg Wilkins --- .../org/eclipse/jetty/server/HttpChannel.java | 4 -- .../jetty/server/HttpChannelState.java | 3 + .../org/eclipse/jetty/server/HttpOutput.java | 16 ++--- .../jetty/server/AsyncCompletionTest.java | 61 +++++++++++++++++-- 4 files changed, 66 insertions(+), 18 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java index 1f787a0356c..9134588cfd9 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java @@ -1195,10 +1195,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor if (_length > 0) _combinedListener.onResponseContent(_request, _content); if (_complete && _state.completeResponse()) - { - _response.getHttpOutput().closed(); _combinedListener.onResponseEnd(_request); - } super.succeeded(); } @@ -1222,7 +1219,6 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor @Override public void failed(Throwable th) { - _response.getHttpOutput().closed(); abort(x); super.failed(x); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java index 53e302d6311..bf302759120 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java @@ -968,6 +968,9 @@ public class HttpChannelState } } + // release any aggregate buffer from a closing flush + _channel.getResponse().getHttpOutput().closed(); + if (event != null) { cancelTimeout(event); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java index 70fbf4868e7..f651179862a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java @@ -234,6 +234,8 @@ public class HttpOutput extends ServletOutputStream implements Runnable { write(content, complete, blocker); blocker.block(); + if (complete) + closed(); } catch (Exception failure) { @@ -403,13 +405,6 @@ public class HttpOutput extends ServletOutputStream implements Runnable State state = _state.get(); switch (state) { - case CLOSING: - { - if (!_state.compareAndSet(state, State.CLOSED)) - break; - releaseBuffer(); - return; - } case CLOSED: { return; @@ -417,7 +412,12 @@ public class HttpOutput extends ServletOutputStream implements Runnable case UNREADY: { if (_state.compareAndSet(state, State.ERROR)) - _writeListener.onError(_onError == null ? new EofException("Async closed") : _onError); + { + if (_onError == null) + _onError = new EofException("Async closed"); + releaseBuffer(); + return; + } break; } default: diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java index a14a6bcd09f..376b9f33baa 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncCompletionTest.java @@ -33,6 +33,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; +import javax.servlet.AsyncContext; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpCompliance; import org.eclipse.jetty.http.HttpTester; @@ -41,6 +47,7 @@ import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.ManagedSelector; import org.eclipse.jetty.io.SocketChannelEndPoint; +import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.thread.Scheduler; import org.hamcrest.Matchers; @@ -89,7 +96,7 @@ public class AsyncCompletionTest extends HttpServerTestFixture _delay.get(10, TimeUnit.SECONDS); getCallback().succeeded(); } - catch(Throwable th) + catch (Throwable th) { th.printStackTrace(); getCallback().failed(th); @@ -97,7 +104,6 @@ public class AsyncCompletionTest extends HttpServerTestFixture } } - @BeforeEach public void init() throws Exception { @@ -153,7 +159,7 @@ public class AsyncCompletionTest extends HttpServerTestFixture @Override public void onCompleted() { - COMPLETE.compareAndSet(false,true); + COMPLETE.compareAndSet(false, true); super.onCompleted(); } } @@ -163,7 +169,8 @@ public class AsyncCompletionTest extends HttpServerTestFixture { List tests = new ArrayList<>(); tests.add(new Object[]{new HelloWorldHandler(), 200, "Hello world"}); - tests.add(new Object[]{new SendErrorHandler(499,"Test async sendError"), 499, "Test async sendError"}); + tests.add(new Object[]{new SendErrorHandler(499, "Test async sendError"), 499, "Test async sendError"}); + tests.add(new Object[]{new AsyncReadyCompleteHandler(), 200, AsyncReadyCompleteHandler.data}); return tests.stream().map(Arguments::of); } @@ -197,7 +204,7 @@ public class AsyncCompletionTest extends HttpServerTestFixture // wait for threads to return to base level long end = System.nanoTime() + TimeUnit.SECONDS.toNanos(10); - while(_threadPool.getBusyThreads() != base) + while (_threadPool.getBusyThreads() != base) { if (System.nanoTime() > end) throw new TimeoutException(); @@ -210,7 +217,7 @@ public class AsyncCompletionTest extends HttpServerTestFixture // proceed with the completion delay.proceed(); - while(!COMPLETE.get()) + while (!COMPLETE.get()) { if (System.nanoTime() > end) throw new TimeoutException(); @@ -218,4 +225,46 @@ public class AsyncCompletionTest extends HttpServerTestFixture } } } + + private static class AsyncReadyCompleteHandler extends AbstractHandler + { + static String data = "Now is the time for all good men to come to the aid of the party"; + + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + AsyncContext context = request.startAsync(); + ServletOutputStream out = response.getOutputStream(); + out.setWriteListener(new WriteListener() + { + byte[] bytes = data.getBytes(StandardCharsets.ISO_8859_1); + + @Override + public void onWritePossible() throws IOException + { + while (out.isReady()) + { + if (bytes != null) + { + response.setContentType("text/plain"); + response.setContentLength(bytes.length); + out.write(bytes); + bytes = null; + } + else + { + context.complete(); + return; + } + } + } + + @Override + public void onError(Throwable t) + { + t.printStackTrace(); + } + }); + } + } } From 65738e770fefc7a0bf2214a6c2a59dc01456c0ff Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 2 Dec 2019 16:00:37 -0600 Subject: [PATCH 57/77] Issue #4385 - Fixing client testcase assertion Signed-off-by: Joakim Erdfelt --- .../src/test/java/org/eclipse/jetty/util/ssl/X509Test.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java index 0faf28eb38d..f5e649eb0a6 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java @@ -184,8 +184,8 @@ public class X509Test { SslContextFactory clientSsl = new SslContextFactory.Client(); X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(clientSsl); - X509ExtendedKeyManager sniX509ExtendedKeyManager = clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager); - assertThat("SNI X509 ExtendedKeyManager is undefined in Client mode", sniX509ExtendedKeyManager, is(x509ExtendedKeyManager)); + UnsupportedOperationException npe = assertThrows(UnsupportedOperationException.class, () -> clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); + assertThat("SNI X509 ExtendedKeyManager is unsupported in Client mode", npe.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); } @Test From d1376c71ebb4d5fcd4d56b65b8851ede9b8ac7e9 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 2 Dec 2019 16:02:18 -0600 Subject: [PATCH 58/77] Issue #4385 - Correcting exception variable name. Signed-off-by: Joakim Erdfelt --- .../test/java/org/eclipse/jetty/util/ssl/X509Test.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java index f5e649eb0a6..a893be2d9eb 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java @@ -164,8 +164,8 @@ public class X509Test { SslContextFactory baseSsl = new SslContextFactory(); X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(baseSsl); - UnsupportedOperationException npe = assertThrows(UnsupportedOperationException.class, () -> baseSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); - assertThat("UnsupportedOperationException.message", npe.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); + UnsupportedOperationException ex = assertThrows(UnsupportedOperationException.class, () -> baseSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); + assertThat("UnsupportedOperationException.message", ex.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); } @Test @@ -184,8 +184,8 @@ public class X509Test { SslContextFactory clientSsl = new SslContextFactory.Client(); X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(clientSsl); - UnsupportedOperationException npe = assertThrows(UnsupportedOperationException.class, () -> clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); - assertThat("SNI X509 ExtendedKeyManager is unsupported in Client mode", npe.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); + UnsupportedOperationException ex = assertThrows(UnsupportedOperationException.class, () -> clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); + assertThat("SNI X509 ExtendedKeyManager is unsupported in Client mode", ex.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); } @Test From f99eb291954f2790376bc34e021b24611992d2aa Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 3 Dec 2019 12:15:02 +1100 Subject: [PATCH 59/77] Issue #4369 Update jsp documenation; remove old config from webdefault.xml (#4384) * Issue #4369 Update jsp documenation; remove old config from webdefault.xml Signed-off-by: Jan Bartel --- .../jsp/configuring-jsp.adoc | 122 +++++++++--------- .../src/main/config/etc/webdefault.xml | 92 +------------ 2 files changed, 66 insertions(+), 148 deletions(-) diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/configuring-jsp.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/configuring-jsp.adoc index 705a03ec1e8..c1d5daaa3ec 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/configuring-jsp.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/jsp/configuring-jsp.adoc @@ -36,6 +36,12 @@ include::{SRCDIR}/jetty-home/src/main/resources/modules/jsp.mod[] Note that the availability of some JSP features may depend on which JSP container implementation you are using. Note also that it may not be possible to precompile your JSPs with one container and deploy to the other. +===== Logging + +The Apache Jasper logging system is bridged to the jetty logging system. +Thus, you can enable logging for jsps in the same way you have setup for your webapp. +For example, assuming you are using Jetty's default StdErr logger, you would enable DEBUG level logging for jsps by adding the system property `-Dorg.apache.jasper.LEVEL=DEBUG` to the command line. + ===== JSPs and Embedding If you have an embedded setup for your webapp and wish to use JSPs, you will need to ensure that a JSP engine is correctly initialized. @@ -79,89 +85,91 @@ If you wish to use a different compiler, you will need to configure the `compile [cols=",,,",options="header",] |======================================================================= |init param |Description |Default |`webdefault.xml` -|classpath |`Classpath used for jsp compilation. Only used if - org.apache.catalina.jsp_classpath context attribute is not - set, which it is in Jetty.` |- |– + +|checkInterval |If non-zero and `development` is `false`, background jsp recompilation is enabled. This value is the interval in seconds between background recompile checks. + |0 |– +|classpath |The classpath is dynamically generated if the context has a URL classloader. The `org.apache.catalina.jsp_classpath` +context attribute is used to add to the classpath, but if this is not set, this `classpath` configuration item is added to the classpath instead.` |- |– |classdebuginfo |Include debugging info in class file. |TRUE |– -|checkInterval |Interval in seconds between background recompile checks. -Only relevant if ` - development=false`. |0 |– +|compilerClassName |If not set, defaults to the Eclipse jdt compiler. |- |– -|development |`development=true`, recompilation checks occur on each -request. See also ` - modificationTestInterval`. |TRUE |– +|compiler |Used if the Eclipse jdt compiler cannot be found on the +classpath. It is the classname of a compiler that Ant should invoke. |– +|– + +|compilerTargetVM |Target vm to compile for. |1.8 |1.8 + +|compilerSourceVM |Sets source compliance level for the jdt compiler. +|1.8 |1.8 + +|development |If `true` recompilation checks occur at the frequency governed by `modificationTestInterval`. |TRUE |– |displaySourceFragment |Should a source fragment be included in exception messages |TRUE |– +|dumpSmap |Dump SMAP JSR45 info to a file. |FALSE |– + +|enablePooling |Determines whether tag handler pooling is enabled. |TRUE |– + +|engineOptionsClass |Allows specifying the Options class used to +configure Jasper. If not present, the default EmbeddedServletOptions +will be used. |- |– + |errorOnUseBeanInvalidClassAttribute |Should Jasper issue an error when the value of the class attribute in an useBean action is not a valid bean class |TRUE |– -|fork |Should Ant fork its Java compiles of JSP pages? |TRUE |FALSE +|fork |Only relevant if you use Ant to compile jsps: by default Jetty will use the Eclipse jdt compiler.|TRUE |- + +|genStrAsCharArray |Option for generating Strings as char arrays. |FALSE |– + +|ieClassId |The class-id value to be sent to Internet Explorer when +using tags. |clsid:8AD9C840-044E-11D1-B3E9-00805F499D93 |– + +|javaEncoding |Pass through the encoding to use for the compilation. +|UTF8 |– + +|jspIdleTimeout |The amount of time in seconds a JSP can be idle before +it is unloaded. A value of zero or less indicates never unload. |-1 |– |keepgenerated |Do you want to keep the generated Java files around? |TRUE |– -|trimSpaces |Should white spaces between directives or actions be -trimmed? |FALSE |– - -|enablePooling |Determines whether tag handler pooling is enabled. |TRUE -|– - -|engineOptionsClass |Allows specifying the Options class used to -configure Jasper. If not present, the default EmbeddedServletOptions -will be used. |– - |mappedFile |Support for mapped Files. Generates a servlet that has a print statement per line of the JSP file  |TRUE |– -|suppressSmap |Generation of SMAP info for JSR45 debugging. |FALSE |– - -|dumpSmap |Dump SMAP JSR45 info to a file. |FALSE |– - -|genStrAsCharArray |Option for generating Strings. |FALSE |– - -|ieClassId |The class-id value to be sent to Internet Explorer when -using tags. |clsid:8AD9C840-044E-11D1-B3E9-00805F499D93 |– - |maxLoadedJsps |The maximum number of JSPs that will be loaded for a web application. If more than this number of JSPs are loaded, the least recently used JSPs will be unloaded so that the number of JSPs loaded at any one time does not exceed this limit. A value of zero or less indicates no limit. |-1 |– -|jspIdleTimeout |The amount of time in seconds a JSP can be idle before -it is unloaded. A value of zero or less indicates never unload. |-1 |– - -|scratchDir |Directory where servlets are generated. See |– |– - -|compilerClassName |If not set, defaults to the Eclipse jdt compiler. |– - -|compiler |Used if the Eclipse jdt compiler cannot be found on the -classpath. It is the classname of a compiler that Ant should invoke. |– -|– - -|compilerTargetVM |Target vm to compile for. |1.7 |– - -|compilerSourceVM |Sets source compliance level for the jdt compiler. -|1.7 |– - -|javaEncoding |Pass through the encoding to use for the compilation. -|UTF8 |– - |modificationTestInterval |If `development=true`, interval between recompilation checks, triggered by a request. |4 |– -|xpoweredBy |Generate an X-Powered-By response header. |FALSE |FALSE +|quoteAttributeEL | When EL is used in an attribute value on a JSP page, should the rules for quoting of attributes described in JSP.1.6 be applied to the expression + |TRUE |- |recompileOnFail |If a JSP compilation fails should the modificationTestInterval be ignored and the next access trigger a re-compilation attempt? Used in development mode only and is disabled by default as compilation may be expensive and could lead to excessive -resource usage. |- |– +resource usage. |FALSE |– + +|scratchDir |Directory where servlets are generated. The default is the value of the context attribute `javax.servlet.context.tempdir`, or the system property `java.io.tmpdir` if the context attribute is not set. |– |– + +|strictQuoteEscaping |Should the quote escaping required by section JSP.1.6 of the JSP specification be applied to scriplet expression. + |TRUE|- + +|suppressSmap |Generation of SMAP info for JSR45 debugging. |FALSE |– + +|trimSpaces |Should template text that consists entirely of whitespace be removed from the output (true), replaced with a single space (single) or left unchanged (false)? Note that if a JSP page or tag file specifies a trimDirectiveWhitespaces value of true, that will take precedence over this configuration setting for that page/tag. +trimmed? |FALSE |– + +|xpoweredBy |Generate an X-Powered-By response header. |FALSE |FALSE + |======================================================================= [[configuring-jsp-for-jetty]] @@ -171,7 +179,7 @@ The JSP engine has many configuration parameters. Some parameters affect only precompilation, and some affect runtime recompilation checking. Parameters also differ among the various versions of the JSP engine. This page lists the configuration parameters, their meanings, and their default settings. -Set all parameters on the `org.apache.jasper.servlet.JspServlet` instance defined in the link:#webdefault-xml[`webdefault.xml`] file. +Set all parameters on the `org.eclipse.jetty.jsp.JettyJspServlet` instance defined in the link:#webdefault-xml[`webdefault.xml`] file. ____ [NOTE] @@ -225,18 +233,10 @@ You can use the entry in link:#webdefault-xml[{$jetty.home}/etc/webdefault.xml] ---- jsp - org.apache.jasper.servlet.JspServlet - - logVerbosityLevel - DEBUG - - - fork - >false - + org.eclipse.jetty.jsp.JettyJspServlet keepgenerated - >true + true ... diff --git a/jetty-webapp/src/main/config/etc/webdefault.xml b/jetty-webapp/src/main/config/etc/webdefault.xml index 891bd28727a..39a9efc4381 100644 --- a/jetty-webapp/src/main/config/etc/webdefault.xml +++ b/jetty-webapp/src/main/config/etc/webdefault.xml @@ -194,107 +194,25 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + jsp org.eclipse.jetty.jsp.JettyJspServlet - - logVerbosityLevel - DEBUG - - - fork - false - xpoweredBy false compilerTargetVM - 1.7 + 1.8 compilerSourceVM - 1.7 + 1.8 - 0 From db9ad2fcecd6158ac9535eebd9fc952809d5e1ff Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 3 Dec 2019 12:16:24 +1100 Subject: [PATCH 60/77] Issue #4323 Ensure QoSFilter handles IllegalStateException (#4372) Signed-off-by: Jan Bartel --- .../org/eclipse/jetty/servlets/QoSFilter.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java index 17fe000e5c3..40a4668b27d 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java @@ -216,6 +216,8 @@ public class QoSFilter implements Filter { if (accepted) { + _passes.release(); + for (int p = _queues.length - 1; p >= 0; --p) { AsyncContext asyncContext = _queues[p].poll(); @@ -225,13 +227,20 @@ public class QoSFilter implements Filter Boolean suspended = (Boolean)candidate.getAttribute(_suspended); if (Boolean.TRUE.equals(suspended)) { - candidate.setAttribute(_resumed, Boolean.TRUE); - asyncContext.dispatch(); - break; + try + { + candidate.setAttribute(_resumed, Boolean.TRUE); + asyncContext.dispatch(); + break; + } + catch (IllegalStateException x) + { + LOG.warn(x); + continue; + } } } } - _passes.release(); } } } @@ -368,7 +377,8 @@ public class QoSFilter implements Filter // redispatched again at the end of the filtering. AsyncContext asyncContext = event.getAsyncContext(); _queues[priority].remove(asyncContext); - asyncContext.dispatch(); + ((HttpServletResponse)event.getSuppliedResponse()).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); + asyncContext.complete(); } @Override From 9628ea3bc158784bb2d9b040e264d1a45fc4b7df Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 3 Dec 2019 11:36:53 +0100 Subject: [PATCH 61/77] Fixes #3512 - File descriptor is not released after zip file uploaded via jetty-client. In case of multiple parts only the last iterator was closed. Now, every part's iterator is closed. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/client/HttpContent.java | 12 +-- .../client/util/MultiPartContentProvider.java | 17 ++-- .../util/MultiPartContentProviderTest.java | 88 +++++++++++++++++++ 3 files changed, 103 insertions(+), 14 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java index 17c8d3ab1bd..ce1e0a82c25 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java @@ -26,6 +26,7 @@ import java.util.Iterator; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -218,15 +219,8 @@ public class HttpContent implements Callback, Closeable @Override public void close() { - try - { - if (iterator instanceof Closeable) - ((Closeable)iterator).close(); - } - catch (Throwable x) - { - LOG.ignore(x); - } + if (iterator instanceof Closeable) + IO.close((Closeable)iterator); } @Override diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java index e6441371d57..30d817dfc81 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java @@ -38,6 +38,7 @@ import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -345,10 +346,16 @@ public class MultiPartContentProvider extends AbstractTypedContentProvider imple if (iterator.hasNext()) return iterator.next(); ++index; - if (index == parts.size()) - state = State.LAST_BOUNDARY; - else + if (index < parts.size()) + { state = State.MIDDLE_BOUNDARY; + if (iterator instanceof Closeable) + IO.close((Closeable)iterator); + } + else + { + state = State.LAST_BOUNDARY; + } break; } case MIDDLE_BOUNDARY: @@ -380,14 +387,14 @@ public class MultiPartContentProvider extends AbstractTypedContentProvider imple @Override public void succeeded() { - if (iterator instanceof Callback) + if (state == State.CONTENT && iterator instanceof Callback) ((Callback)iterator).succeeded(); } @Override public void failed(Throwable x) { - if (iterator instanceof Callback) + if (state == State.CONTENT && iterator instanceof Callback) ((Callback)iterator).failed(x); } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java index e1d855e3e2b..ec90c842c31 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartContentProviderTest.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.client.util; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -31,10 +32,12 @@ import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -435,6 +438,46 @@ public class MultiPartContentProviderTest extends AbstractHttpClientServerTest assertTrue(responseLatch.await(5, TimeUnit.SECONDS)); } + @ParameterizedTest + @ArgumentsSource(ScenarioProvider.class) + public void testEachPartIsClosed(Scenario scenario) throws Exception + { + String name1 = "field1"; + String value1 = "value1"; + String name2 = "field2"; + String value2 = "value2"; + start(scenario, new AbstractMultiPartHandler() + { + @Override + protected void handle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + Collection parts = request.getParts(); + assertEquals(2, parts.size()); + Iterator iterator = parts.iterator(); + Part part1 = iterator.next(); + assertEquals(name1, part1.getName()); + assertEquals(value1, IO.toString(part1.getInputStream())); + Part part2 = iterator.next(); + assertEquals(name2, part2.getName()); + assertEquals(value2, IO.toString(part2.getInputStream())); + } + }); + + AtomicInteger closeCount = new AtomicInteger(); + MultiPartContentProvider multiPart = new MultiPartContentProvider(); + multiPart.addFieldPart(name1, new CloseableStringContentProvider(value1, closeCount::incrementAndGet), null); + multiPart.addFieldPart(name2, new CloseableStringContentProvider(value2, closeCount::incrementAndGet), null); + multiPart.close(); + ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) + .scheme(scenario.getScheme()) + .method(HttpMethod.POST) + .content(multiPart) + .send(); + + assertEquals(200, response.getStatus()); + assertEquals(2, closeCount.get()); + } + private abstract static class AbstractMultiPartHandler extends AbstractHandler { @Override @@ -448,4 +491,49 @@ public class MultiPartContentProviderTest extends AbstractHttpClientServerTest protected abstract void handle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException; } + + private static class CloseableStringContentProvider extends StringContentProvider + { + private final Runnable closeFn; + + private CloseableStringContentProvider(String content, Runnable closeFn) + { + super(content); + this.closeFn = closeFn; + } + + @Override + public Iterator iterator() + { + return new CloseableIterator<>(super.iterator()); + } + + private class CloseableIterator implements Iterator, Closeable + { + private final Iterator iterator; + + public CloseableIterator(Iterator iterator) + { + this.iterator = iterator; + } + + @Override + public boolean hasNext() + { + return iterator.hasNext(); + } + + @Override + public T next() + { + return iterator.next(); + } + + @Override + public void close() + { + closeFn.run(); + } + } + } } From 839846d9a6e56b3557bb2aa3593d8e4591760ffd Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 3 Dec 2019 13:01:28 +0100 Subject: [PATCH 62/77] Fixes #4392 - Suppress logging of QuietException in HttpChannelState.asyncError(). Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/server/HttpChannelState.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java index bf302759120..74e72098f64 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java @@ -28,6 +28,7 @@ import javax.servlet.UnavailableException; import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.QuietException; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler.Context; import org.eclipse.jetty.server.handler.ErrorHandler; @@ -406,8 +407,6 @@ public class HttpChannelState */ protected Action unhandle() { - boolean readInterested = false; - synchronized (this) { if (LOG.isDebugEnabled()) @@ -736,8 +735,10 @@ public class HttpChannelState } else { - LOG.warn(failure.toString()); - LOG.debug(failure); + if (!(failure instanceof QuietException)) + LOG.warn(failure.toString()); + if (LOG.isDebugEnabled()) + LOG.debug(failure); } } @@ -1340,7 +1341,7 @@ public class HttpChannelState * but that a handling thread may need to produce (fill/parse) * it. Typically called by the async read success callback. * - * @return true if more content may be available + * @return {@code true} if more content may be available */ public boolean onReadPossible() { @@ -1372,7 +1373,7 @@ public class HttpChannelState * Called to signal that a read has read -1. * Will wake if the read was called while in ASYNC_WAIT state * - * @return true if woken + * @return {@code true} if woken */ public boolean onReadEof() { From 2ef02da1bd020c420beb6418b79e08d169e6e74c Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 3 Dec 2019 21:40:55 +0100 Subject: [PATCH 63/77] Fixes #4366 - HTTP client uses SOCKS4 proxy hostname for SSL hostname verification. Now setting correctly the host and port to the server destination _after_ the SOCKS tunnel is established, similarly to what is done for the HTTP CONNECT tunnel. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/client/Socks4Proxy.java | 3 + .../eclipse/jetty/client/Socks4ProxyTest.java | 105 +++++++++++++++++- 2 files changed, 103 insertions(+), 5 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/Socks4Proxy.java b/jetty-client/src/main/java/org/eclipse/jetty/client/Socks4Proxy.java index 7150247e8c9..4700591ceab 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/Socks4Proxy.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/Socks4Proxy.java @@ -30,6 +30,7 @@ import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.io.ssl.SslClientConnectionFactory; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Promise; @@ -195,6 +196,8 @@ public class Socks4Proxy extends ProxyConfiguration.Proxy try { HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); + context.put(SslClientConnectionFactory.SSL_PEER_HOST_CONTEXT_KEY, destination.getHost()); + context.put(SslClientConnectionFactory.SSL_PEER_PORT_CONTEXT_KEY, destination.getPort()); ClientConnectionFactory connectionFactory = this.connectionFactory; if (destination.isSecure()) connectionFactory = destination.newSslClientConnectionFactory(null, connectionFactory); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java index df56547514c..5b7eea37db6 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java @@ -18,6 +18,8 @@ package org.eclipse.jetty.client; +import java.io.InputStream; +import java.io.OutputStream; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; @@ -25,7 +27,12 @@ import java.nio.channels.SocketChannel; import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -44,7 +51,10 @@ public class Socks4ProxyTest server = ServerSocketChannel.open(); server.bind(new InetSocketAddress("localhost", 0)); - client = new HttpClient(); + QueuedThreadPool clientThreads = new QueuedThreadPool(); + clientThreads.setName("client"); + client = new HttpClient(new SslContextFactory.Client()); + client.setExecutor(clientThreads); client.start(); } @@ -61,7 +71,7 @@ public class Socks4ProxyTest int proxyPort = server.socket().getLocalPort(); client.getProxyConfiguration().getProxies().add(new Socks4Proxy("localhost", proxyPort)); - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); byte ip1 = 127; byte ip2 = 0; @@ -111,7 +121,7 @@ public class Socks4ProxyTest "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n"; - channel.write(ByteBuffer.wrap(response.getBytes("UTF-8"))); + channel.write(ByteBuffer.wrap(response.getBytes(StandardCharsets.UTF_8))); assertTrue(latch.await(5, TimeUnit.SECONDS)); } @@ -123,7 +133,7 @@ public class Socks4ProxyTest int proxyPort = server.socket().getLocalPort(); client.getProxyConfiguration().getProxies().add(new Socks4Proxy("localhost", proxyPort)); - final CountDownLatch latch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); String serverHost = "127.0.0.13"; // Test expects an IP address. int serverPort = proxyPort + 1; // Any port will do @@ -169,7 +179,92 @@ public class Socks4ProxyTest "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n"; - channel.write(ByteBuffer.wrap(response.getBytes("UTF-8"))); + channel.write(ByteBuffer.wrap(response.getBytes(StandardCharsets.UTF_8))); + + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + } + + @Test + public void testSocks4ProxyWithTLSServer() throws Exception + { + String proxyHost = "localhost"; + int proxyPort = server.socket().getLocalPort(); + + String serverHost = "127.0.0.13"; // Server host different from proxy host. + int serverPort = proxyPort + 1; // Any port will do. + + SslContextFactory clientTLS = client.getSslContextFactory(); + clientTLS.reload(ssl -> + { + // The client keystore contains the trustedCertEntry for the + // self-signed server certificate, so it acts as a truststore. + ssl.setTrustStorePath("src/test/resources/client_keystore.jks"); + ssl.setTrustStorePassword("storepwd"); + // Disable TLS hostname verification, but + // enable application hostname verification. + ssl.setEndpointIdentificationAlgorithm(null); + // The hostname must be that of the server, not of the proxy. + ssl.setHostnameVerifier((hostname, session) -> serverHost.equals(hostname)); + }); + client.getProxyConfiguration().getProxies().add(new Socks4Proxy(proxyHost, proxyPort)); + + CountDownLatch latch = new CountDownLatch(1); + client.newRequest(serverHost, serverPort) + .scheme(HttpScheme.HTTPS.asString()) + .path("/path") + .send(result -> + { + if (result.isSucceeded()) + latch.countDown(); + else + result.getFailure().printStackTrace(); + }); + + try (SocketChannel channel = server.accept()) + { + int socks4MessageLength = 9; + ByteBuffer buffer = ByteBuffer.allocate(socks4MessageLength); + int read = channel.read(buffer); + assertEquals(socks4MessageLength, read); + + // Socks4 response. + channel.write(ByteBuffer.wrap(new byte[]{0, 0x5A, 0, 0, 0, 0, 0, 0})); + + // Wrap the socket with TLS. + SslContextFactory.Server serverTLS = new SslContextFactory.Server(); + serverTLS.setKeyStorePath("src/test/resources/keystore.jks"); + serverTLS.setKeyStorePassword("storepwd"); + serverTLS.start(); + SSLContext sslContext = serverTLS.getSslContext(); + SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(channel.socket(), serverHost, serverPort, false); + sslSocket.setUseClientMode(false); + + // Read the request. + int crlfs = 0; + InputStream input = sslSocket.getInputStream(); + while (true) + { + read = input.read(); + if (read < 0) + break; + if (read == '\r' || read == '\n') + ++crlfs; + else + crlfs = 0; + if (crlfs == 4) + break; + } + + // Send the response. + String response = + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"; + OutputStream output = sslSocket.getOutputStream(); + output.write(response.getBytes(StandardCharsets.UTF_8)); + output.flush(); assertTrue(latch.await(5, TimeUnit.SECONDS)); } From c6633e8d6797f3ff35aa9dd45f2c27da4ebab8df Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 4 Dec 2019 15:32:28 +1100 Subject: [PATCH 64/77] fixed bad merge Signed-off-by: Greg Wilkins --- jetty-http2/http2-server/src/main/java/module-info.java | 2 ++ .../src/main/java/org/eclipse/jetty/server/HttpOutput.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/jetty-http2/http2-server/src/main/java/module-info.java b/jetty-http2/http2-server/src/main/java/module-info.java index 329d1d4efda..27d06e52689 100644 --- a/jetty-http2/http2-server/src/main/java/module-info.java +++ b/jetty-http2/http2-server/src/main/java/module-info.java @@ -25,4 +25,6 @@ module org.eclipse.jetty.http2.server requires org.eclipse.jetty.io; requires org.eclipse.jetty.server; requires org.eclipse.jetty.util; + + requires jetty.servlet.api; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java index a20e219f492..5687c97d15b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java @@ -482,6 +482,8 @@ public class HttpOutput extends ServletOutputStream implements Runnable { write(content, complete, blocker); blocker.block(); + if (complete) + closed(); } catch (Exception failure) { From b3ea7d9f60fababfbe836b464ff40eccc8a87e16 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 4 Dec 2019 16:43:37 +1100 Subject: [PATCH 65/77] re-fixed bad merge Signed-off-by: Greg Wilkins --- jetty-http2/http2-server/src/main/java/module-info.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/jetty-http2/http2-server/src/main/java/module-info.java b/jetty-http2/http2-server/src/main/java/module-info.java index 27d06e52689..329d1d4efda 100644 --- a/jetty-http2/http2-server/src/main/java/module-info.java +++ b/jetty-http2/http2-server/src/main/java/module-info.java @@ -25,6 +25,4 @@ module org.eclipse.jetty.http2.server requires org.eclipse.jetty.io; requires org.eclipse.jetty.server; requires org.eclipse.jetty.util; - - requires jetty.servlet.api; } From 47117f88fbfd8e0bf3d5c5ab13cd22888e739dd1 Mon Sep 17 00:00:00 2001 From: Lachlan Date: Thu, 5 Dec 2019 13:16:16 +1100 Subject: [PATCH 66/77] Allow WebSocket extension selection to be done from UpgradeListener (#4379) * Allow WebSocket extension selection to be done from UpgradeListener * improve generation of extension string Signed-off-by: Lachlan Roberts --- .../core/client/ClientUpgradeRequest.java | 28 ++++++--- .../core/WebSocketNegotiationTest.java | 61 +++++++++++++++++++ 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java index aa61f1c62ea..aacafa94ddb 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/client/ClientUpgradeRequest.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.function.Consumer; +import java.util.stream.Collectors; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpConversation; @@ -286,15 +287,28 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon void requestComplete() { // Add extensions header filtering out internal extensions and internal parameters. - HttpFields headers = getHeaders(); - for (ExtensionConfig config : requestedExtensions) - { - if (config.getName().startsWith("@")) - continue; - headers.add(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, config.getParameterizedNameWithoutInternalParams()); - } + String extensionString = requestedExtensions.stream() + .filter(ec -> !ec.getName().startsWith("@")) + .map(ExtensionConfig::getParameterizedNameWithoutInternalParams) + .collect(Collectors.joining(",")); + if (!StringUtil.isEmpty(extensionString)) + getHeaders().add(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, extensionString); + + // Notify the listener which may change the headers directly. notifyUpgradeListeners((listener) -> listener.onHandshakeRequest(this)); + + // Check if extensions were set in the headers from the upgrade listener. + String extsAfterListener = String.join(",", getHeaders().getCSV(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, true)); + if (!extensionString.equals(extsAfterListener)) + { + // If extensions were set in both the ClientUpgradeRequest and UpgradeListener throw ISE. + if (!requestedExtensions.isEmpty()) + abort(new IllegalStateException("Extensions set in both the ClientUpgradeRequest and UpgradeListener")); + + // Otherwise reparse the new set of requested extensions. + requestedExtensions = ExtensionConfig.parseList(extsAfterListener); + } } private void notifyUpgradeListeners(Consumer action) diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java index e09b15a39ce..63dc1b99b79 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java @@ -53,6 +53,7 @@ import org.junit.jupiter.params.provider.MethodSource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; @@ -361,6 +362,66 @@ public class WebSocketNegotiationTest extends WebSocketTester assertThat(response, containsString("400 Bad Request")); } + @Test + public void testListenerExtensionSelection() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, server.getUri(), clientHandler); + upgradeRequest.setSubProtocols("test"); + + CompletableFuture extensionHeader = new CompletableFuture<>(); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeRequest(HttpRequest request) + { + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "permessage-deflate"); + } + + @Override + public void onHandshakeResponse(HttpRequest request, HttpResponse response) + { + extensionHeader.complete(response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_EXTENSIONS)); + } + }); + + client.connect(upgradeRequest).get(5, TimeUnit.SECONDS); + clientHandler.sendClose(); + assertTrue(clientHandler.closed.await(5, TimeUnit.SECONDS)); + assertNull(clientHandler.getError()); + + assertThat(extensionHeader.get(5, TimeUnit.SECONDS), is("permessage-deflate")); + } + + @Test + public void testListenerExtensionSelectionError() throws Exception + { + TestFrameHandler clientHandler = new TestFrameHandler(); + ClientUpgradeRequest upgradeRequest = ClientUpgradeRequest.from(client, server.getUri(), clientHandler); + upgradeRequest.setSubProtocols("test"); + upgradeRequest.addExtensions("permessage-deflate;server_no_context_takeover"); + + CompletableFuture extensionHeader = new CompletableFuture<>(); + upgradeRequest.addListener(new UpgradeListener() + { + @Override + public void onHandshakeRequest(HttpRequest request) + { + request.getHeaders().put(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "permessage-deflate"); + } + }); + + ExecutionException error = assertThrows(ExecutionException.class, + () -> client.connect(upgradeRequest).get(5, TimeUnit.SECONDS)); + + Throwable upgradeException = error.getCause(); + assertThat(upgradeException, instanceOf(UpgradeException.class)); + Throwable cause = upgradeException.getCause(); + assertThat(cause, instanceOf(IllegalStateException.class)); + assertThat(cause.getMessage(), is("Extensions set in both the ClientUpgradeRequest and UpgradeListener")); + } + public static Stream internalExtensionScenarios() throws Exception { return Stream.of( From 53073ca25704ebd49c7133226053418a5124900f Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 6 Dec 2019 13:20:24 -0600 Subject: [PATCH 67/77] Issue #4385 - Reverting WARN log in favor of IllegalStateException + Plus fleshing out the testcases more for Base / Client / Server with and without certificates that will trigger SNI requirement and ISE. Signed-off-by: Joakim Erdfelt --- .../jetty/util/ssl/SslContextFactory.java | 24 ++-- .../org/eclipse/jetty/util/ssl/X509Test.java | 105 +++++++++--------- 2 files changed, 68 insertions(+), 61 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index f141b846bec..c1f35606430 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -1249,18 +1249,13 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable // Is SNI needed to select a certificate? if (!_certWilds.isEmpty() || _certHosts.size() > 1 || (_certHosts.size() == 1 && _aliasX509.size() > 1)) { - if (this instanceof SslContextFactory.Server) + for (int idx = 0; idx < managers.length; idx++) { - for (int idx = 0; idx < managers.length; idx++) + if (managers[idx] instanceof X509ExtendedKeyManager) { - if (managers[idx] instanceof X509ExtendedKeyManager) - managers[idx] = newSniX509ExtendedKeyManager((X509ExtendedKeyManager)managers[idx]); + managers[idx] = newSniX509ExtendedKeyManager((X509ExtendedKeyManager)managers[idx]); } } - else - { - LOG.warn("Unable to support SNI on {} (expecting {})", this.getClass().getName(), SslContextFactory.Server.class.getName()); - } } } } @@ -1277,7 +1272,11 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable @Deprecated protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) { - throw new UnsupportedOperationException("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName()); + throw new IllegalStateException(String.format( + "KeyStores with multiple certificates are not supported on the base class %s. (Use %s or %s instead)", + SslContextFactory.class.getName(), + Server.class.getName(), + Client.class.getName())); } protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection crls) throws Exception @@ -2185,6 +2184,13 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable checkEndPointIdentificationAlgorithm(); super.checkConfiguration(); } + + @Override + protected X509ExtendedKeyManager newSniX509ExtendedKeyManager(X509ExtendedKeyManager keyManager) + { + // Client has no SNI functionality. + return keyManager; + } } @ManagedObject diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java index a893be2d9eb..85ca35233a9 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java @@ -20,8 +20,6 @@ package org.eclipse.jetty.util.ssl; import java.nio.file.Path; import java.security.cert.X509Certificate; -import javax.net.ssl.KeyManager; -import javax.net.ssl.X509ExtendedKeyManager; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.resource.PathResource; @@ -31,7 +29,6 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; import static org.junit.jupiter.api.Assertions.assertThrows; public class X509Test @@ -133,66 +130,70 @@ public class X509Test assertThat("Normal X509", X509.isCertSign(bogusX509), is(false)); } - private X509ExtendedKeyManager getX509ExtendedKeyManager(SslContextFactory sslContextFactory) throws Exception - { - Resource keystoreResource = Resource.newSystemResource("keystore"); - Resource truststoreResource = Resource.newSystemResource("keystore"); - sslContextFactory.setKeyStoreResource(keystoreResource); - sslContextFactory.setTrustStoreResource(truststoreResource); - sslContextFactory.setKeyStorePassword("storepwd"); - sslContextFactory.setKeyManagerPassword("keypwd"); - sslContextFactory.setTrustStorePassword("storepwd"); - sslContextFactory.start(); - - KeyManager[] keyManagers = sslContextFactory.getKeyManagers(sslContextFactory.getKeyStore()); - X509ExtendedKeyManager x509ExtendedKeyManager = null; - - for (KeyManager keyManager : keyManagers) - { - if (keyManager instanceof X509ExtendedKeyManager) - { - x509ExtendedKeyManager = (X509ExtendedKeyManager)keyManager; - break; - } - } - assertThat("Found X509ExtendedKeyManager", x509ExtendedKeyManager, is(notNullValue())); - return x509ExtendedKeyManager; - } - @Test - public void testSniX509ExtendedKeyManager_BaseClass() throws Exception - { - SslContextFactory baseSsl = new SslContextFactory(); - X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(baseSsl); - UnsupportedOperationException ex = assertThrows(UnsupportedOperationException.class, () -> baseSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); - assertThat("UnsupportedOperationException.message", ex.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); - } - - @Test - public void testSniX509ExtendedKeyManager_BaseClass_Start() throws Exception + public void testBaseClass_WithSni() { SslContextFactory baseSsl = new SslContextFactory(); Path keystorePath = MavenTestingUtils.getTestResourcePathFile("keystore_sni.p12"); baseSsl.setKeyStoreResource(new PathResource(keystorePath)); baseSsl.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); baseSsl.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); - baseSsl.start(); // should not throw an exception + IllegalStateException ex = assertThrows(IllegalStateException.class, baseSsl::start); + assertThat("IllegalStateException.message", ex.getMessage(), containsString("KeyStores with multiple certificates are not supported on the base class")); } @Test - public void testSniX509ExtendedKeyManager_ClientClass() throws Exception - { - SslContextFactory clientSsl = new SslContextFactory.Client(); - X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(clientSsl); - UnsupportedOperationException ex = assertThrows(UnsupportedOperationException.class, () -> clientSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager)); - assertThat("SNI X509 ExtendedKeyManager is unsupported in Client mode", ex.getMessage(), containsString("X509ExtendedKeyManager only supported on " + SslContextFactory.Server.class.getName())); - } - - @Test - public void testSniX509ExtendedKeyManager_ServerClass() throws Exception + public void testServerClass_WithSni() throws Exception { SslContextFactory serverSsl = new SslContextFactory.Server(); - X509ExtendedKeyManager x509ExtendedKeyManager = getX509ExtendedKeyManager(serverSsl); - serverSsl.newSniX509ExtendedKeyManager(x509ExtendedKeyManager); + Path keystorePath = MavenTestingUtils.getTestResourcePathFile("keystore_sni.p12"); + serverSsl.setKeyStoreResource(new PathResource(keystorePath)); + serverSsl.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + serverSsl.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + serverSsl.start(); + } + + @Test + public void testClientClass_WithSni() throws Exception + { + SslContextFactory clientSsl = new SslContextFactory.Client(); + Path keystorePath = MavenTestingUtils.getTestResourcePathFile("keystore_sni.p12"); + clientSsl.setKeyStoreResource(new PathResource(keystorePath)); + clientSsl.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + clientSsl.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + clientSsl.start(); + } + + @Test + public void testBaseClass_WithoutSni() throws Exception + { + SslContextFactory baseSsl = new SslContextFactory(); + Resource keystoreResource = Resource.newSystemResource("keystore"); + baseSsl.setKeyStoreResource(keystoreResource); + baseSsl.setKeyStorePassword("storepwd"); + baseSsl.setKeyManagerPassword("keypwd"); + baseSsl.start(); + } + + @Test + public void testServerClass_WithoutSni() throws Exception + { + SslContextFactory serverSsl = new SslContextFactory.Server(); + Resource keystoreResource = Resource.newSystemResource("keystore"); + serverSsl.setKeyStoreResource(keystoreResource); + serverSsl.setKeyStorePassword("storepwd"); + serverSsl.setKeyManagerPassword("keypwd"); + serverSsl.start(); + } + + @Test + public void testClientClass_WithoutSni() throws Exception + { + SslContextFactory clientSsl = new SslContextFactory.Client(); + Resource keystoreResource = Resource.newSystemResource("keystore"); + clientSsl.setKeyStoreResource(keystoreResource); + clientSsl.setKeyStorePassword("storepwd"); + clientSsl.setKeyManagerPassword("keypwd"); + clientSsl.start(); } } From 53eda03203706e5f29ba3a4881262a7cd63f7ebb Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 6 Dec 2019 13:24:30 -0600 Subject: [PATCH 68/77] Making exception message more clear Signed-off-by: Joakim Erdfelt --- .../src/main/java/org/eclipse/jetty/server/Request.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index f02ad81dbda..0c0f5734e94 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -2306,7 +2306,7 @@ public class Request implements HttpServletRequest { String contentType = getContentType(); if (contentType == null || !MimeTypes.Type.MULTIPART_FORM_DATA.is(HttpFields.valueParameters(contentType, null))) - throw new ServletException("Content-Type != multipart/form-data"); + throw new ServletException("Unsupported Content-Type [" + contentType + "], expected [multipart/form-data]"); return getParts(null); } From 9cfaa414a16a8e4ad3fb0f302ae7d003df38e558 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Mon, 9 Dec 2019 08:33:52 +1100 Subject: [PATCH 69/77] Issue #4238 Pass system properties into xml configurations (#4390) * Issue #4238 Pass system properties into xml configurations Signed-off-by: Jan Bartel --- .../DefaultJettyAtJettyHomeHelper.java | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java index 95f27927ffb..eeb5d5144ab 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java @@ -26,6 +26,8 @@ import java.util.Dictionary; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; +import java.util.Map; +import java.util.Properties; import java.util.StringTokenizer; import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator; @@ -148,9 +150,8 @@ public class DefaultJettyAtJettyHomeHelper LOG.warn("No default jetty created."); return null; } - - //configure the server here rather than letting the JettyServerServiceTracker do it, because we want to be able to - //configure the ThreadPool, which can only be done via the constructor, ie from within the xml configuration processing + + //resolve the jetty xml config files List configURLs = jettyHomeDir != null ? getJettyConfigurationURLs(jettyHomeDir) : getJettyConfigurationURLs(jettyHomeBundle, properties); LOG.info("Configuring the default jetty server with {}", configURLs); @@ -174,14 +175,36 @@ public class DefaultJettyAtJettyHomeHelper } Thread.currentThread().setContextClassLoader(cl); - // these properties usually are the ones passed to this type of - // configuration. + //the default server name properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME); - Util.setProperty(properties, OSGiServerConstants.JETTY_HOST, System.getProperty(OSGiServerConstants.JETTY_HOST, System.getProperty("jetty.host"))); - Util.setProperty(properties, OSGiServerConstants.JETTY_PORT, System.getProperty(OSGiServerConstants.JETTY_PORT, System.getProperty("jetty.port"))); - Util.setProperty(properties, OSGiServerConstants.JETTY_PORT_SSL, System.getProperty(OSGiServerConstants.JETTY_PORT_SSL, System.getProperty("ssl.port"))); + + //Always set home and base Util.setProperty(properties, OSGiServerConstants.JETTY_HOME, home); Util.setProperty(properties, OSGiServerConstants.JETTY_BASE, base); + + // copy all system properties starting with "jetty." to service properties for the jetty server service. + // these will be used as xml configuration properties. + for (Map.Entry prop : System.getProperties().entrySet()) + { + if (prop.getKey() instanceof String) + { + String skey = (String)prop.getKey(); + //never copy the jetty xml config files into the properties as we pass them explicitly into + //the call to configure, also we set home and base explicitly + if (OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS.equals(skey) || + OSGiServerConstants.JETTY_HOME.equals(skey) || + OSGiServerConstants.JETTY_BASE.equals(skey)) + continue; + + if (skey.startsWith("jetty.")) + { + Util.setProperty(properties, skey, prop.getValue()); + } + } + } + + //configure the server here rather than letting the JettyServerServiceTracker do it, because we want to be able to + //configure the ThreadPool, which can only be done via the constructor, ie from within the xml configuration processing Server server = ServerInstanceWrapper.configure(null, configURLs, properties); //Register the default Server instance as an OSGi service. From 0e6a1ce76b1b8427bd05a210a10ed15796c150b4 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 10 Dec 2019 12:29:40 +1100 Subject: [PATCH 70/77] Issue #4402 Fix NPE in JettyRunWarExplodedMojo (#4406) Signed-off-by: Jan Bartel --- .../org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java index 65de9d95f5b..fd124a9457f 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java @@ -88,7 +88,7 @@ public class JettyRunWarExplodedMojo extends AbstractJettyMojo { try { - scanner.addDirectory(webApp.getClasses().toPath()); + scanner.addDirectory(classes.toPath()); } catch (IOException e) { From 6bbec7f3b04278a384d3b55e05ab71cadad0d86e Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 11 Dec 2019 00:11:29 +0100 Subject: [PATCH 71/77] Issue #4411 - Jetty server spins on incomplete request. Fixed HttpInput to be in READY state if an error is detected before the call to setWriteListener(). Signed-off-by: Simone Bordet --- .../jetty/server/HttpConfiguration.java | 2 +- .../org/eclipse/jetty/server/HttpInput.java | 29 ++++--- .../http/client/HttpClientStreamTest.java | 80 +++++++++++++++++++ 3 files changed, 99 insertions(+), 12 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java index 42aa19d9de9..8545600a538 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java @@ -343,7 +343,7 @@ public class HttpConfiguration implements Dumpable } /** - * @param delay if true, delay the application dispatch until content is available (default false) + * @param delay if true, delays the application dispatch until content is available (defaults to true) */ public void setDelayDispatchUntilContent(boolean delay) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java index 15f04a2c864..6b12818296b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java @@ -756,22 +756,29 @@ public class HttpInput extends ServletInputStream implements Runnable _listener = Objects.requireNonNull(readListener); - Content content = produceNextContext(); - if (content != null) + if (isError()) { - _state = ASYNC; woken = _channelState.onReadReady(); } - else if (_state == EOF) - { - _state = AEOF; - woken = _channelState.onReadEof(); - } else { - _state = ASYNC; - _channelState.onReadUnready(); - _waitingForContent = true; + Content content = produceNextContext(); + if (content != null) + { + _state = ASYNC; + woken = _channelState.onReadReady(); + } + else if (_state == EOF) + { + _state = AEOF; + woken = _channelState.onReadEof(); + } + else + { + _state = ASYNC; + _channelState.onReadUnready(); + _waitingForContent = true; + } } } } diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java index f56e260a255..ac83e55357a 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java @@ -43,7 +43,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import javax.servlet.AsyncContext; +import javax.servlet.ReadListener; import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -56,6 +58,7 @@ import org.eclipse.jetty.client.util.DeferredContentProvider; import org.eclipse.jetty.client.util.InputStreamContentProvider; import org.eclipse.jetty.client.util.InputStreamResponseListener; import org.eclipse.jetty.client.util.OutputStreamContentProvider; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; @@ -63,6 +66,7 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; +import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; @@ -1264,4 +1268,80 @@ public class HttpClientStreamTest extends AbstractTest Result result = listener.await(5, TimeUnit.SECONDS); assertTrue(result.isSucceeded()); } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testClientDefersContentServerIdleTimeout(Transport transport) throws Exception + { + // TODO: fix FCGI that is failing this test. + Assumptions.assumeTrue(transport != Transport.FCGI); + + init(transport); + CountDownLatch dataLatch = new CountDownLatch(1); + CountDownLatch errorLatch = new CountDownLatch(1); + scenario.start(new HttpServlet() + { + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException + { + AsyncContext asyncContext = request.startAsync(); + asyncContext.setTimeout(0); + request.getInputStream().setReadListener(new ReadListener() + { + @Override + public void onDataAvailable() + { + dataLatch.countDown(); + } + + @Override + public void onAllDataRead() + { + dataLatch.countDown(); + } + + @Override + public void onError(Throwable t) + { + errorLatch.countDown(); + response.setStatus(HttpStatus.REQUEST_TIMEOUT_408); + asyncContext.complete(); + } + }); + } + }); + long idleTimeout = 1000; + scenario.setServerIdleTimeout(idleTimeout); + + CountDownLatch latch = new CountDownLatch(1); + byte[] bytes = "[{\"key\":\"value\"}]".getBytes(StandardCharsets.UTF_8); + OutputStreamContentProvider content = new OutputStreamContentProvider() + { + @Override + public long getLength() + { + return bytes.length; + } + }; + scenario.client.newRequest(scenario.newURI()) + .method(HttpMethod.POST) + .path(scenario.servletPath) + .content(content, "application/json;charset=UTF-8") + .onResponseSuccess(response -> + { + assertEquals(HttpStatus.REQUEST_TIMEOUT_408, response.getStatus()); + latch.countDown(); + }) + .send(null); + + // Wait for the server to idle timeout. + Thread.sleep(2 * idleTimeout); + + assertTrue(errorLatch.await(5, TimeUnit.SECONDS)); + + // Do not send the content to the server. + + assertFalse(dataLatch.await(1, TimeUnit.SECONDS)); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } } From 8e875ab7a4fbee318e1e7fe3fe59cbeda0b53e9e Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 11 Dec 2019 13:02:23 +0100 Subject: [PATCH 72/77] Issue #4411 - Jetty server spins on incomplete request. Updated FastCGI code to pass the test. Signed-off-by: Simone Bordet --- .../eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java | 8 ++++++++ .../eclipse/jetty/fcgi/server/ServerFCGIConnection.java | 8 ++++++++ .../eclipse/jetty/http/client/HttpClientStreamTest.java | 4 ---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java index 1ba90e21ce2..bc7542ed354 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java @@ -125,6 +125,14 @@ public class HttpChannelOverFCGI extends HttpChannel dispatcher.dispatch(); } + public boolean onIdleTimeout(Throwable timeout) + { + boolean handle = getRequest().getHttpInput().onIdleTimeout(timeout); + if (handle) + execute(this); + return !handle; + } + private static class Dispatcher implements Runnable { private final AtomicReference state = new AtomicReference<>(State.IDLE); diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java index 73b45bda8c8..97cfbbd3ff9 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java @@ -105,6 +105,14 @@ public class ServerFCGIConnection extends AbstractConnection } } + @Override + protected boolean onReadTimeout(Throwable timeout) + { + return channels.values().stream() + .mapToInt(channel -> channel.onIdleTimeout(timeout) ? 0 : 1) + .sum() == 0; + } + private void parse(ByteBuffer buffer) { while (buffer.hasRemaining()) diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java index ac83e55357a..a8ac3c23578 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java @@ -66,7 +66,6 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; -import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; @@ -1273,9 +1272,6 @@ public class HttpClientStreamTest extends AbstractTest @ArgumentsSource(TransportProvider.class) public void testClientDefersContentServerIdleTimeout(Transport transport) throws Exception { - // TODO: fix FCGI that is failing this test. - Assumptions.assumeTrue(transport != Transport.FCGI); - init(transport); CountDownLatch dataLatch = new CountDownLatch(1); CountDownLatch errorLatch = new CountDownLatch(1); From 8245038a901d84f774cb13ef466ab5281654d6fd Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 11 Dec 2019 13:50:05 +0100 Subject: [PATCH 73/77] Merged branch 'jetty-9.4.x' into 'jetty-10.0.x'. --- .../fcgi/server/HttpChannelOverFCGI.java | 8 ++ .../fcgi/server/ServerFCGIConnection.java | 8 ++ .../jetty/server/HttpConfiguration.java | 2 +- .../org/eclipse/jetty/server/HttpInput.java | 29 ++++--- .../http/client/HttpClientStreamTest.java | 76 +++++++++++++++++++ 5 files changed, 111 insertions(+), 12 deletions(-) diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java index 1ba90e21ce2..bc7542ed354 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/HttpChannelOverFCGI.java @@ -125,6 +125,14 @@ public class HttpChannelOverFCGI extends HttpChannel dispatcher.dispatch(); } + public boolean onIdleTimeout(Throwable timeout) + { + boolean handle = getRequest().getHttpInput().onIdleTimeout(timeout); + if (handle) + execute(this); + return !handle; + } + private static class Dispatcher implements Runnable { private final AtomicReference state = new AtomicReference<>(State.IDLE); diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java index 73b45bda8c8..97cfbbd3ff9 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java @@ -105,6 +105,14 @@ public class ServerFCGIConnection extends AbstractConnection } } + @Override + protected boolean onReadTimeout(Throwable timeout) + { + return channels.values().stream() + .mapToInt(channel -> channel.onIdleTimeout(timeout) ? 0 : 1) + .sum() == 0; + } + private void parse(ByteBuffer buffer) { while (buffer.hasRemaining()) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java index cfe93b6a880..764e0150aed 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java @@ -315,7 +315,7 @@ public class HttpConfiguration implements Dumpable } /** - * @param delay if true, delay the application dispatch until content is available (default false) + * @param delay if true, delays the application dispatch until content is available (defaults to true) */ public void setDelayDispatchUntilContent(boolean delay) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java index 151c1bc9467..af8cdaac2da 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java @@ -732,22 +732,29 @@ public class HttpInput extends ServletInputStream implements Runnable _listener = Objects.requireNonNull(readListener); - Content content = produceNextContext(); - if (content != null) + if (isError()) { - _state = ASYNC; woken = _channelState.onReadReady(); } - else if (_state == EOF) - { - _state = AEOF; - woken = _channelState.onReadEof(); - } else { - _state = ASYNC; - _channelState.onReadUnready(); - _waitingForContent = true; + Content content = produceNextContext(); + if (content != null) + { + _state = ASYNC; + woken = _channelState.onReadReady(); + } + else if (_state == EOF) + { + _state = AEOF; + woken = _channelState.onReadEof(); + } + else + { + _state = ASYNC; + _channelState.onReadUnready(); + _waitingForContent = true; + } } } } diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java index f56e260a255..a8ac3c23578 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientStreamTest.java @@ -43,7 +43,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import javax.servlet.AsyncContext; +import javax.servlet.ReadListener; import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -56,6 +58,7 @@ import org.eclipse.jetty.client.util.DeferredContentProvider; import org.eclipse.jetty.client.util.InputStreamContentProvider; import org.eclipse.jetty.client.util.InputStreamResponseListener; import org.eclipse.jetty.client.util.OutputStreamContentProvider; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; @@ -1264,4 +1267,77 @@ public class HttpClientStreamTest extends AbstractTest Result result = listener.await(5, TimeUnit.SECONDS); assertTrue(result.isSucceeded()); } + + @ParameterizedTest + @ArgumentsSource(TransportProvider.class) + public void testClientDefersContentServerIdleTimeout(Transport transport) throws Exception + { + init(transport); + CountDownLatch dataLatch = new CountDownLatch(1); + CountDownLatch errorLatch = new CountDownLatch(1); + scenario.start(new HttpServlet() + { + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException + { + AsyncContext asyncContext = request.startAsync(); + asyncContext.setTimeout(0); + request.getInputStream().setReadListener(new ReadListener() + { + @Override + public void onDataAvailable() + { + dataLatch.countDown(); + } + + @Override + public void onAllDataRead() + { + dataLatch.countDown(); + } + + @Override + public void onError(Throwable t) + { + errorLatch.countDown(); + response.setStatus(HttpStatus.REQUEST_TIMEOUT_408); + asyncContext.complete(); + } + }); + } + }); + long idleTimeout = 1000; + scenario.setServerIdleTimeout(idleTimeout); + + CountDownLatch latch = new CountDownLatch(1); + byte[] bytes = "[{\"key\":\"value\"}]".getBytes(StandardCharsets.UTF_8); + OutputStreamContentProvider content = new OutputStreamContentProvider() + { + @Override + public long getLength() + { + return bytes.length; + } + }; + scenario.client.newRequest(scenario.newURI()) + .method(HttpMethod.POST) + .path(scenario.servletPath) + .content(content, "application/json;charset=UTF-8") + .onResponseSuccess(response -> + { + assertEquals(HttpStatus.REQUEST_TIMEOUT_408, response.getStatus()); + latch.countDown(); + }) + .send(null); + + // Wait for the server to idle timeout. + Thread.sleep(2 * idleTimeout); + + assertTrue(errorLatch.await(5, TimeUnit.SECONDS)); + + // Do not send the content to the server. + + assertFalse(dataLatch.await(1, TimeUnit.SECONDS)); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + } } From ef5c7d79471ab302472dd2dc679a4163e3109979 Mon Sep 17 00:00:00 2001 From: Chris Walker Date: Wed, 11 Dec 2019 12:35:09 -0600 Subject: [PATCH 74/77] Adding documentation for test-keystore module. Resolves #4228 --- .../asciidoc/distribution-guide/http2/enabling-http2.adoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/enabling-http2.adoc b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/enabling-http2.adoc index 9eaefadc53f..f5c14f3f883 100644 --- a/jetty-documentation/src/main/asciidoc/distribution-guide/http2/enabling-http2.adoc +++ b/jetty-documentation/src/main/asciidoc/distribution-guide/http2/enabling-http2.adoc @@ -27,11 +27,12 @@ A demo Jetty base that supports HTTP/1, HTTPS/1 and deployment from a webapps di $ JETTY_BASE=http2-demo $ mkdir $JETTY_BASE $ cd $JETTY_BASE -$ java -jar $JETTY_HOME/start.jar --add-to-start=http,https,deploy +$ java -jar $JETTY_HOME/start.jar --add-to-start=http,https,deploy,test-keystore .... The commands above create a `$JETTY_BASE` directory called `http2-demo`, and initializes the `http,` `https` and `deploy` modules (and their dependencies) to run a typical Jetty Server on port 8080 (for HTTP/1) and 8443 (for HTTPS/1). -Note that the HTTPS module downloads a demo keystore file with a self signed certificate, which needs to be replaced by a Certificate Authority issued certificate for real deployment. +Note that the `test-keystore` module downloads a demo keystore file with a self signed certificate, which needs to be replaced by a Certificate Authority issued certificate for real deployment. +A keystore can also be added by enabling and configuring the `ssl` module. To add HTTP/2 to this demo base, it is just a matter of enabling the `http2` module with the following command: From 2b58379f88899867484bdb94d82e7ace47edf8dc Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 11 Dec 2019 14:38:42 -0600 Subject: [PATCH 75/77] Issue #4415 - Addressing Gzip Decoding of large files + Now applying proper RFC 1952 ISIZE check. + Bit shifting is done with Longs against Long value. Signed-off-by: Joakim Erdfelt --- .../jetty/http/GZIPContentDecoder.java | 10 +- .../jetty/http/GZIPContentDecoderTest.java | 100 ++++++++++++++++++ 2 files changed, 107 insertions(+), 3 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java index 6ca334aba29..c8d7af6f2e0 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java @@ -37,13 +37,16 @@ import org.eclipse.jetty.util.component.Destroyable; */ public class GZIPContentDecoder implements Destroyable { + // Unsigned Integer Max == 2^32 + private static final long UINT_MAX = 0xffffffffL; + private final List _inflateds = new ArrayList<>(); private final Inflater _inflater = new Inflater(true); private final ByteBufferPool _pool; private final int _bufferSize; private State _state; private int _size; - private int _value; + private long _value; private byte _flags; private ByteBuffer _inflated; @@ -375,11 +378,12 @@ public class GZIPContentDecoder implements Destroyable } case ISIZE: { - _value += (currByte & 0xFF) << 8 * _size; + _value = _value | ((currByte & 0xFFL) << (8 * _size)); ++_size; if (_size == 4) { - if (_value != _inflater.getBytesWritten()) + // RFC 1952: Section 2.3.1; ISIZE is the input size modulo 2^32 + if (_value != (_inflater.getBytesWritten() & UINT_MAX)) throw new ZipException("Invalid input size"); // TODO ByteBuffer result = output == null ? BufferUtil.EMPTY_BUFFER : ByteBuffer.wrap(output); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java index 93c7c4c3f37..64e113db32d 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java @@ -20,6 +20,8 @@ package org.eclipse.jetty.http; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.concurrent.atomic.AtomicInteger; @@ -27,10 +29,15 @@ import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import org.eclipse.jetty.io.ArrayByteBufferPool; +import org.eclipse.jetty.util.BufferUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -351,4 +358,97 @@ public class GZIPContentDecoderTest assertTrue(buffer.hasRemaining()); assertEquals(data2, StandardCharsets.UTF_8.decode(buffer).toString()); } + + // Signed Integer Max + final long INT_MAX = Integer.MAX_VALUE; + + // Unsigned Integer Max == 2^32 + final long UINT_MAX = 0xffffffffL; + + @ParameterizedTest + @ValueSource(longs = {INT_MAX, INT_MAX + 1, UINT_MAX, UINT_MAX + 1}) + public void testLargeGzipStream(long origSize) throws IOException + { + final int BUFSIZE = (1 * 1024 * 1024); // 1MB + + // Create a buffer to use over and over again to produce the uncompressed input + byte[] cbuf = "0123456789ABCDEFGHIJKLMOPQRSTUVWXYZ".getBytes(StandardCharsets.UTF_8); + byte[] buf = new byte[BUFSIZE]; + for (int off = 0; off < buf.length; ) + { + int len = Math.min(cbuf.length, buf.length - off); + System.arraycopy(cbuf, 0, buf, off, len); + off += len; + } + + GZIPContentDecoder decoder = new GZIPContentDecoder(BUFSIZE); + + try (GZIPDecoderOutputStream out = new GZIPDecoderOutputStream(decoder); + GZIPOutputStream outputStream = new GZIPOutputStream(out, BUFSIZE)) + { + long writtenBytes = 0L; + for (long bytesLeft = origSize; bytesLeft > 0; ) + { + int len = buf.length; + if (bytesLeft < buf.length) + { + len = (int)bytesLeft; + } + outputStream.write(buf, 0, len); + bytesLeft -= len; + writtenBytes += len; + } + outputStream.close(); + + assertThat("Written byte count", writtenBytes, is(origSize)); + assertThat("Decoded byte count", out.decodedByteCount, is(origSize)); + } + } + + public static class GZIPDecoderOutputStream extends OutputStream + { + private final GZIPContentDecoder decoder; + public long decodedByteCount = 0L; + + public GZIPDecoderOutputStream(GZIPContentDecoder decoder) + { + this.decoder = decoder; + } + + @Override + public void write(byte[] b, int off, int len) throws IOException + { + ByteBuffer buf = ByteBuffer.wrap(b, off, len); + decode(buf); + } + + @Override + public void write(byte[] b) throws IOException + { + ByteBuffer buf = ByteBuffer.wrap(b); + decode(buf); + } + + @Override + public void write(int b) throws IOException + { + ByteBuffer buf = BufferUtil.allocate(32); + buf.put((byte)(b & 0xFF)); + buf.flip(); + decode(buf); + } + + private void decode(ByteBuffer buffer) + { + while (buffer.hasRemaining()) + { + ByteBuffer decoded = decoder.decode(buffer); + if (decoded.hasRemaining()) + { + decodedByteCount += decoded.remaining(); + } + decoder.release(decoded); + } + } + } } From 1e810d370f0e2a2c7751d1cf7bcf4081d8a45ce7 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 12 Dec 2019 11:58:44 -0600 Subject: [PATCH 76/77] Issue #4415 - Addressing Gzip Decoding of large files + Addressing PR review Signed-off-by: Joakim Erdfelt --- .../jetty/http/GZIPContentDecoder.java | 2 +- .../jetty/http/GZIPContentDecoderTest.java | 70 +++++++------------ 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java index c8d7af6f2e0..bd73544e44f 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java @@ -38,7 +38,7 @@ import org.eclipse.jetty.util.component.Destroyable; public class GZIPContentDecoder implements Destroyable { // Unsigned Integer Max == 2^32 - private static final long UINT_MAX = 0xffffffffL; + private static final long UINT_MAX = 0xFFFFFFFFL; private final List _inflateds = new ArrayList<>(); private final Inflater _inflater = new Inflater(true); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java index 64e113db32d..4261a12651d 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java @@ -29,7 +29,6 @@ import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import org.eclipse.jetty.io.ArrayByteBufferPool; -import org.eclipse.jetty.util.BufferUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -363,7 +362,7 @@ public class GZIPContentDecoderTest final long INT_MAX = Integer.MAX_VALUE; // Unsigned Integer Max == 2^32 - final long UINT_MAX = 0xffffffffL; + final long UINT_MAX = 0xFFFFFFFFL; @ParameterizedTest @ValueSource(longs = {INT_MAX, INT_MAX + 1, UINT_MAX, UINT_MAX + 1}) @@ -383,26 +382,26 @@ public class GZIPContentDecoderTest GZIPContentDecoder decoder = new GZIPContentDecoder(BUFSIZE); - try (GZIPDecoderOutputStream out = new GZIPDecoderOutputStream(decoder); - GZIPOutputStream outputStream = new GZIPOutputStream(out, BUFSIZE)) - { - long writtenBytes = 0L; - for (long bytesLeft = origSize; bytesLeft > 0; ) - { - int len = buf.length; - if (bytesLeft < buf.length) - { - len = (int)bytesLeft; - } - outputStream.write(buf, 0, len); - bytesLeft -= len; - writtenBytes += len; - } - outputStream.close(); + GZIPDecoderOutputStream out = new GZIPDecoderOutputStream(decoder); + GZIPOutputStream outputStream = new GZIPOutputStream(out, BUFSIZE); - assertThat("Written byte count", writtenBytes, is(origSize)); - assertThat("Decoded byte count", out.decodedByteCount, is(origSize)); + for (long bytesLeft = origSize; bytesLeft > 0; ) + { + int len = buf.length; + if (bytesLeft < buf.length) + { + len = (int)bytesLeft; + } + outputStream.write(buf, 0, len); + bytesLeft -= len; } + + // Close GZIPOutputStream to have it generate gzip trailer. + // This can cause more writes of unflushed gzip buffers + outputStream.close(); + + // out.decodedByteCount is only valid after close + assertThat("Decoded byte count", out.decodedByteCount, is(origSize)); } public static class GZIPDecoderOutputStream extends OutputStream @@ -419,30 +418,9 @@ public class GZIPContentDecoderTest public void write(byte[] b, int off, int len) throws IOException { ByteBuffer buf = ByteBuffer.wrap(b, off, len); - decode(buf); - } - - @Override - public void write(byte[] b) throws IOException - { - ByteBuffer buf = ByteBuffer.wrap(b); - decode(buf); - } - - @Override - public void write(int b) throws IOException - { - ByteBuffer buf = BufferUtil.allocate(32); - buf.put((byte)(b & 0xFF)); - buf.flip(); - decode(buf); - } - - private void decode(ByteBuffer buffer) - { - while (buffer.hasRemaining()) + while (buf.hasRemaining()) { - ByteBuffer decoded = decoder.decode(buffer); + ByteBuffer decoded = decoder.decode(buf); if (decoded.hasRemaining()) { decodedByteCount += decoded.remaining(); @@ -450,5 +428,11 @@ public class GZIPContentDecoderTest decoder.release(decoded); } } + + @Override + public void write(int b) throws IOException + { + write(new byte[]{(byte)(b & 0xFF)}, 0, 1); + } } } From 36d06d016d966169122ea4858fc4a6c98db60bea Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 12 Dec 2019 13:23:44 -0600 Subject: [PATCH 77/77] Issue #4415 - Addressing Gzip Decoding of large files + Addressing PR review Signed-off-by: Joakim Erdfelt --- .../org/eclipse/jetty/http/GZIPContentDecoderTest.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java index 4261a12651d..47f0165d616 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java @@ -368,7 +368,8 @@ public class GZIPContentDecoderTest @ValueSource(longs = {INT_MAX, INT_MAX + 1, UINT_MAX, UINT_MAX + 1}) public void testLargeGzipStream(long origSize) throws IOException { - final int BUFSIZE = (1 * 1024 * 1024); // 1MB + // Size chosen for trade off between speed of I/O vs speed of Gzip + final int BUFSIZE = 1024 * 1024; // Create a buffer to use over and over again to produce the uncompressed input byte[] cbuf = "0123456789ABCDEFGHIJKLMOPQRSTUVWXYZ".getBytes(StandardCharsets.UTF_8); @@ -380,9 +381,7 @@ public class GZIPContentDecoderTest off += len; } - GZIPContentDecoder decoder = new GZIPContentDecoder(BUFSIZE); - - GZIPDecoderOutputStream out = new GZIPDecoderOutputStream(decoder); + GZIPDecoderOutputStream out = new GZIPDecoderOutputStream(new GZIPContentDecoder(BUFSIZE)); GZIPOutputStream outputStream = new GZIPOutputStream(out, BUFSIZE); for (long bytesLeft = origSize; bytesLeft > 0; ) @@ -432,7 +431,7 @@ public class GZIPContentDecoderTest @Override public void write(int b) throws IOException { - write(new byte[]{(byte)(b & 0xFF)}, 0, 1); + write(new byte[]{(byte)b}, 0, 1); } } }