Merge remote-tracking branch 'origin/jetty-10.0.x' into jetty-10.0.x-5018-WebSocketClientRequestTimeout

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2020-07-14 16:39:23 +10:00
commit df34a6269b
16 changed files with 81 additions and 62 deletions

View File

@ -1,5 +1,7 @@
jetty-10.0.0-SNAPSHOT jetty-10.0.0-SNAPSHOT
jetty-10.0.0.beta0 - 27 May 2020
jetty-9.4.30.v20200611 - 11 June 2020 jetty-9.4.30.v20200611 - 11 June 2020
+ 4776 Incorrect path matching for WebSocket using PathMappings + 4776 Incorrect path matching for WebSocket using PathMappings
+ 4826 Upgrade to Apache Jasper 8.5.54 + 4826 Upgrade to Apache Jasper 8.5.54
@ -66,7 +68,7 @@ jetty-10.0.0.alpha1 - 26 November 2019
+ 2709 current default for headerCacheSize is not large enough for many + 2709 current default for headerCacheSize is not large enough for many
requests requests
+ 2815 hpack fields are opaque octets + 2815 hpack fields are opaque octets
+ 3040 Allow RFC6265 Cookies to include optional SameSite attribute. + 3040 Allow RFC6265 Cookies to include optional SameSite attribute
+ 3083 The ini-template for jetty.console-capture.dir does not match the + 3083 The ini-template for jetty.console-capture.dir does not match the
default value default value
+ 3106 Websocket connection stats and request stats + 3106 Websocket connection stats and request stats
@ -499,10 +501,10 @@ jetty-9.4.25.v20191220 - 20 December 2019
SslContextFactory usage SslContextFactory usage
+ 4392 Suppress logging of QuietException in HttpChannelState.asyncError() + 4392 Suppress logging of QuietException in HttpChannelState.asyncError()
+ 4402 NPE in JettyRunWarExplodedMojo + 4402 NPE in JettyRunWarExplodedMojo
+ 4411 Jetty server spins on incomplete request due to delayed dispatch + 4411 Jetty server spins on incomplete request due to delayed dispatch until
until content content
+ 4415 GzipHandler invalid input zip size on large + 4415 GzipHandler invalid input zip size on large (over 2,147,483,647 bytes)
(over 2,147,483,647 bytes) request body content request body content
+ 4421 HttpClient support for PROXY protocol + 4421 HttpClient support for PROXY protocol
+ 4427 Retried HttpClient Requests can result in duplicates cookies + 4427 Retried HttpClient Requests can result in duplicates cookies

View File

@ -92,9 +92,8 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable
public Connection acquire(boolean create) public Connection acquire(boolean create)
{ {
Connection connection = activate(); Connection connection = activate();
if (connection == null) if (connection == null && create)
{ {
if (create)
tryCreate(destination.getQueuedRequestCount()); tryCreate(destination.getQueuedRequestCount());
connection = activate(); connection = activate();
} }

View File

@ -372,7 +372,7 @@ public class HttpRequest implements Request
} }
@Override @Override
public HttpFields.Mutable getHeaders() public HttpFields getHeaders()
{ {
return headers; return headers;
} }

View File

@ -56,7 +56,7 @@ public class MultiplexConnectionPool extends AbstractConnectionPool implements C
public Connection acquire(boolean create) public Connection acquire(boolean create)
{ {
Connection connection = activate(); Connection connection = activate();
if (connection == null) if (connection == null && create)
{ {
int queuedRequests = getHttpDestination().getQueuedRequestCount(); int queuedRequests = getHttpDestination().getQueuedRequestCount();
int maxMultiplex = getMaxMultiplex(); int maxMultiplex = getMaxMultiplex();

View File

@ -175,6 +175,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
@Override @Override
public void onSettings(Session session, SettingsFrame frame) public void onSettings(Session session, SettingsFrame frame)
{ {
super.onSettings(session, frame);
// Send another request to simulate a request being // Send another request to simulate a request being
// sent concurrently with connection establishment. // sent concurrently with connection establishment.
// Sending this request will trigger the creation of // Sending this request will trigger the creation of
@ -199,7 +200,6 @@ public class MaxConcurrentStreamsTest extends AbstractTest
} }
}); });
} }
super.onSettings(session, frame);
} }
}, promise, context); }, promise, context);
} }

View File

@ -73,7 +73,6 @@
<groupId>org.ops4j.pax.tinybundles</groupId> <groupId>org.ops4j.pax.tinybundles</groupId>
<artifactId>tinybundles</artifactId> <artifactId>tinybundles</artifactId>
<version>3.0.0</version> <version>3.0.0</version>
<scope>test</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>biz.aQute.bnd</groupId> <groupId>biz.aQute.bnd</groupId>

View File

@ -20,6 +20,7 @@ package org.eclipse.jetty.osgi.test;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -58,20 +59,13 @@ public class TestJettyOSGiAnnotationParser
BundleContext bundleContext = null; BundleContext bundleContext = null;
@Configuration @Configuration
public static Option[] configure() public static Option[] configure() throws IOException
{ {
ArrayList<Option> options = new ArrayList<>(); ArrayList<Option> options = new ArrayList<>();
options.add(TestOSGiUtil.optionalRemoteDebug()); options.add(TestOSGiUtil.optionalRemoteDebug());
options.add(CoreOptions.junitBundles()); options.add(CoreOptions.junitBundles());
options.addAll(TestOSGiUtil.coreJettyDependencies()); options.addAll(TestOSGiUtil.coreJettyDependencies());
options.add(mavenBundle().groupId("biz.aQute.bnd").artifactId("bndlib").versionAsInProject().start());
options.add(mavenBundle().groupId("org.ops4j.pax.tinybundles").artifactId("tinybundles").version("2.1.1").start());
return options.toArray(new Option[options.size()]);
}
@Test
public void testParse() throws Exception
{
//get a reference to a pre-prepared module-info //get a reference to a pre-prepared module-info
Path path = Paths.get("src", "test", "resources", "module-info.clazz"); Path path = Paths.get("src", "test", "resources", "module-info.clazz");
File moduleInfo = path.toFile(); File moduleInfo = path.toFile();
@ -80,8 +74,13 @@ public class TestJettyOSGiAnnotationParser
TinyBundle bundle = TinyBundles.bundle(); TinyBundle bundle = TinyBundles.bundle();
bundle.set(Constants.BUNDLE_SYMBOLICNAME, "bundle.with.module.info"); bundle.set(Constants.BUNDLE_SYMBOLICNAME, "bundle.with.module.info");
bundle.add("module-info.class", new FileInputStream(moduleInfo)); //copy it into the fake bundle bundle.add("module-info.class", new FileInputStream(moduleInfo)); //copy it into the fake bundle
InputStream is = bundle.build(); options.add(CoreOptions.streamBundle(bundle.build()).startLevel(1));
bundleContext.installBundle("dummyLocation", is); return options.toArray(new Option[options.size()]);
}
@Test
public void testParse() throws Exception
{
//test the osgi annotation parser ignore the module-info.class file in the fake bundle //test the osgi annotation parser ignore the module-info.class file in the fake bundle
//Get a reference to the deployed fake bundle //Get a reference to the deployed fake bundle

View File

@ -38,7 +38,6 @@ import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
@ -154,22 +153,26 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon
public void setSubProtocols(String... protocols) public void setSubProtocols(String... protocols)
{ {
HttpFields.Mutable headers = getHeaders(); headers(headers ->
{
headers.remove(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL); headers.remove(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL);
for (String protocol : protocols) for (String protocol : protocols)
{ {
headers.add(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, protocol); headers.add(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, protocol);
} }
});
} }
public void setSubProtocols(List<String> protocols) public void setSubProtocols(List<String> protocols)
{ {
HttpFields.Mutable headers = getHeaders(); headers(headers ->
{
headers.remove(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL); headers.remove(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL);
for (String protocol : protocols) for (String protocol : protocols)
{ {
headers.add(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, protocol); headers.add(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, protocol);
} }
});
} }
@Override @Override
@ -282,7 +285,7 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
if (!StringUtil.isEmpty(extensionString)) if (!StringUtil.isEmpty(extensionString))
getHeaders().add(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, extensionString); headers(headers -> headers.add(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, extensionString));
// Notify the listener which may change the headers directly. // Notify the listener which may change the headers directly.
notifyUpgradeListeners((listener) -> listener.onHandshakeRequest(this)); notifyUpgradeListeners((listener) -> listener.onHandshakeRequest(this));

View File

@ -413,13 +413,12 @@ public class WebSocketNegotiationTest extends WebSocketTester
upgradeRequest.setSubProtocols("test"); upgradeRequest.setSubProtocols("test");
upgradeRequest.addExtensions("permessage-deflate;server_no_context_takeover"); upgradeRequest.addExtensions("permessage-deflate;server_no_context_takeover");
CompletableFuture<String> extensionHeader = new CompletableFuture<>();
upgradeRequest.addListener(new UpgradeListener() upgradeRequest.addListener(new UpgradeListener()
{ {
@Override @Override
public void onHandshakeRequest(HttpRequest request) public void onHandshakeRequest(HttpRequest request)
{ {
request.getHeaders().put(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "permessage-deflate"); request.headers(headers -> headers.put(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "permessage-deflate"));
} }
}); });

View File

@ -33,7 +33,7 @@ import org.eclipse.jetty.websocket.core.client.UpgradeListener;
public class JsrUpgradeListener implements UpgradeListener public class JsrUpgradeListener implements UpgradeListener
{ {
private Configurator configurator; private final Configurator configurator;
public JsrUpgradeListener(Configurator configurator) public JsrUpgradeListener(Configurator configurator)
{ {
@ -46,7 +46,7 @@ public class JsrUpgradeListener implements UpgradeListener
if (configurator == null) if (configurator == null)
return; return;
HttpFields.Mutable fields = request.getHeaders(); HttpFields fields = request.getHeaders();
Map<String, List<String>> originalHeaders = new HashMap<>(); Map<String, List<String>> originalHeaders = new HashMap<>();
fields.forEach(field -> fields.forEach(field ->
{ {
@ -59,8 +59,11 @@ public class JsrUpgradeListener implements UpgradeListener
configurator.beforeRequest(originalHeaders); configurator.beforeRequest(originalHeaders);
// Reset headers on HttpRequest per configurator // Reset headers on HttpRequest per configurator
fields.clear(); request.headers(headers ->
originalHeaders.forEach(fields::put); {
headers.clear();
originalHeaders.forEach(headers::put);
});
} }
@Override @Override

View File

@ -30,7 +30,6 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
@ -72,12 +71,14 @@ public class NetworkFuzzer extends Fuzzer.Adapter implements Fuzzer, AutoCloseab
this.upgradeRequest = new RawUpgradeRequest(client, wsURI); this.upgradeRequest = new RawUpgradeRequest(client, wsURI);
if (requestHeaders != null) if (requestHeaders != null)
{ {
HttpFields.Mutable fields = this.upgradeRequest.getHeaders(); this.upgradeRequest.headers(fields ->
{
requestHeaders.forEach((name, value) -> requestHeaders.forEach((name, value) ->
{ {
fields.remove(name); fields.remove(name);
fields.put(name, value); fields.put(name, value);
}); });
});
} }
this.client.start(); this.client.start();
this.generator = new UnitGenerator(Behavior.CLIENT); this.generator = new UnitGenerator(Behavior.CLIENT);

View File

@ -18,12 +18,13 @@
package org.eclipse.jetty.websocket.client.impl; package org.eclipse.jetty.websocket.client.impl;
import java.net.HttpCookie;
import java.net.URI; import java.net.URI;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.jetty.client.HttpResponse; import org.eclipse.jetty.client.HttpResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
@ -46,11 +47,15 @@ public class JettyClientUpgradeRequest extends org.eclipse.jetty.websocket.core.
if (request != null) if (request != null)
{ {
// Copy request details into actual request // Copy request details into actual request
HttpFields.Mutable fields = getHeaders(); headers(fields -> request.getHeaders().forEach(fields::put));
request.getHeaders().forEach(fields::put);
// Copy manually created Cookies into place // Copy manually created Cookies into place
request.getCookies().forEach(c -> fields.add(HttpHeader.COOKIE, c.toString())); List<HttpCookie> cookies = request.getCookies();
if (cookies != null)
{
// TODO: remove existing Cookie header (if set)?
headers(fields -> cookies.forEach(cookie -> fields.add(HttpHeader.COOKIE, cookie.toString())));
}
// Copy sub-protocols // Copy sub-protocols
setSubProtocols(request.getSubProtocols()); setSubProtocols(request.getSubProtocols());

View File

@ -36,9 +36,9 @@ public class EchoSocket extends EventSocket
} }
@Override @Override
public void onMessage(byte[] buf, int offset, int len) public void onMessage(byte[] buf, int offset, int len) throws IOException
{ {
super.onMessage(buf, offset, len); super.onMessage(buf, offset, len);
session.getRemote().sendBytes(ByteBuffer.wrap(buf, offset, len), WriteCallback.NOOP); session.getRemote().sendBytes(ByteBuffer.wrap(buf, offset, len));
} }
} }

View File

@ -71,7 +71,7 @@ public class EventSocket
} }
@OnWebSocketMessage @OnWebSocketMessage
public void onMessage(byte[] buf, int offset, int len) public void onMessage(byte[] buf, int offset, int len) throws IOException
{ {
ByteBuffer message = ByteBuffer.wrap(buf, offset, len); ByteBuffer message = ByteBuffer.wrap(buf, offset, len);
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())

View File

@ -391,6 +391,14 @@
</goals> </goals>
</execution> </execution>
</executions> </executions>
<!-- this has better support of gh token remove when with next release of jetty-version-maven-plugin -->
<dependencies>
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>github-api</artifactId>
<version>1.114</version>
</dependency>
</dependencies>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

View File

@ -58,18 +58,19 @@ public class MongoTestHelper
static MongoClient mongoClient; static MongoClient mongoClient;
static String mongoHost;
static int mongoPort;
public static void startMongo() public static void startMongo()
{ {
try try
{ {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
mongo.start(); mongo.start();
String containerIpAddress = mongo.getContainerIpAddress(); mongoHost = mongo.getHost();
int mongoPort = mongo.getMappedPort(27017); mongoPort = mongo.getMappedPort(27017);
LOG.info("Mongo container started for {}:{} - {}ms", containerIpAddress, mongoPort, LOG.info("Mongo container started for {}:{} - {}ms", mongoHost, mongoPort,
System.currentTimeMillis() - start); System.currentTimeMillis() - start);
System.setProperty("embedmongoHost", containerIpAddress);
System.setProperty("embedmongoPort", Integer.toString(mongoPort));
} }
catch (Exception e) catch (Exception e)
{ {
@ -94,7 +95,7 @@ public class MongoTestHelper
} }
if (mongoClient == null || restart) if (mongoClient == null || restart)
{ {
mongoClient = new MongoClient(System.getProperty("embedmongoHost"), Integer.getInteger("embedmongoPort")); mongoClient = new MongoClient(mongoHost, mongoPort);
} }
return mongoClient; return mongoClient;
} }
@ -117,8 +118,8 @@ public class MongoTestHelper
public static MongoSessionDataStoreFactory newSessionDataStoreFactory() public static MongoSessionDataStoreFactory newSessionDataStoreFactory()
{ {
MongoSessionDataStoreFactory storeFactory = new MongoSessionDataStoreFactory(); MongoSessionDataStoreFactory storeFactory = new MongoSessionDataStoreFactory();
storeFactory.setHost(System.getProperty("embedmongoHost")); storeFactory.setHost(mongoHost);
storeFactory.setPort(Integer.getInteger("embedmongoPort")); storeFactory.setPort(mongoPort);
storeFactory.setCollectionName(COLLECTION_NAME); storeFactory.setCollectionName(COLLECTION_NAME);
storeFactory.setDbName(DB_NAME); storeFactory.setDbName(DB_NAME);
return storeFactory; return storeFactory;