From 7f8966774e2096b9ddd55ee931643b48bfc30218 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 24 Oct 2019 20:46:59 +0100 Subject: [PATCH 1/6] Upgrade Jetty to 9.4.21 Make use of the new getAvailableExtensionNames() method. Closes gh-23799 --- build.gradle | 2 +- .../server/jetty/JettyRequestUpgradeStrategy.java | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index afeb6d166d7..f8751bdd78e 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ ext { groovyVersion = "2.5.8" hsqldbVersion = "2.4.1" jackson2Version = "2.9.9" - jettyVersion = "9.4.20.v20190813" + jettyVersion = "9.4.21.v20190926" junit5Version = "5.3.2" kotlinVersion = "1.2.71" log4jVersion = "2.11.2" diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java index fab7634b9fb..b3a10faf881 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/jetty/JettyRequestUpgradeStrategy.java @@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; -import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory; import org.eclipse.jetty.websocket.server.HandshakeRFC6455; import org.eclipse.jetty.websocket.server.WebSocketServerFactory; @@ -180,14 +179,17 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv return result; } - @SuppressWarnings({"unchecked"}) + @SuppressWarnings({"unchecked", "deprecation"}) private Set getExtensionNames() { try { - return this.factory.getExtensionFactory().getExtensionNames(); + return this.factory.getAvailableExtensionNames(); } catch (IncompatibleClassChangeError ex) { + // Fallback for versions prior to 9.4.21: // 9.4.20.v20190813: ExtensionFactory (abstract class -> interface) - Method method = ClassUtils.getMethod(ExtensionFactory.class, "getExtensionNames"); + // 9.4.21.v20190926: ExtensionFactory (interface -> abstract class) + deprecated + Class clazz = org.eclipse.jetty.websocket.api.extensions.ExtensionFactory.class; + Method method = ClassUtils.getMethod(clazz, "getExtensionNames"); return (Set) ReflectionUtils.invokeMethod(method, this.factory.getExtensionFactory()); } } From 562c0871e9f588cdf0e457b85b1df726a551a7d8 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 24 Oct 2019 20:51:16 +0100 Subject: [PATCH 2/6] Charset argument in RestClientResponseException See gh-23803 --- .../web/client/RestClientResponseException.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java b/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java index 36006cc4834..f93f2334fa5 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,11 +99,22 @@ public class RestClientResponseException extends RestClientException { } /** - * Return the response body as a string. + * Return the response body converted to String. The charset used is that + * of the response "Content-Type" or otherwise {@code "UTF-8"}. */ public String getResponseBodyAsString() { + return getResponseBodyAsString(DEFAULT_CHARSET); + } + + /** + * Return the response body converted to String. The charset used is that + * of the response "Content-Type" or otherwise the one given. + * @param fallbackCharset the charset to use on if the response doesn't specify. + * @since 5.1.11 + */ + public String getResponseBodyAsString(Charset fallbackCharset) { if (this.responseCharset == null) { - return new String(this.responseBody, DEFAULT_CHARSET); + return new String(this.responseBody, fallbackCharset); } try { return new String(this.responseBody, this.responseCharset); From 53dcb00074d4d0e8b3798dcbe034634efd80e0e5 Mon Sep 17 00:00:00 2001 From: Tomasz Letachowicz Date: Thu, 10 Oct 2019 23:24:56 +0200 Subject: [PATCH 3/6] Typos in WebSocket section Closes gh-23777 --- src/docs/asciidoc/web/websocket.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/docs/asciidoc/web/websocket.adoc b/src/docs/asciidoc/web/websocket.adoc index 769e98e5315..c5c2b5e71fe 100644 --- a/src/docs/asciidoc/web/websocket.adoc +++ b/src/docs/asciidoc/web/websocket.adoc @@ -1403,7 +1403,7 @@ for the return value, by default, a message is sent directly to the client (thro When is this useful? Assume that the broker is mapped to `/topic` and `/queue`, while application controllers are mapped to `/app`. In this setup, the broker stores all subscriptions to `/topic` and `/queue` that are intended for repeated broadcasts, and -there is no need for the application to get involved. A client could also also subscribe to +there is no need for the application to get involved. A client could also subscribe to some `/app` destination, and a controller could return a value in response to that subscription without involving the broker without storing or using the subscription again (effectively a one-time request-reply exchange). One use case for this is populating a UI @@ -2579,7 +2579,7 @@ When you use `@EnableWebSocketMessageBroker` or ``, ke infrastructure components automatically gather statisticss and counters that provide important insight into the internal state of the application. The configuration also declares a bean of type `WebSocketMessageBrokerStats` that gathers all -available information in one place and by, default logs, it at the `INFO` level once +available information in one place and by default logs it at the `INFO` level once every 30 minutes. This bean can be exported to JMX through Spring's `MBeanExporter` for viewing at runtime (for example, through JDK's `jconsole`). The following list summarizes the available information: @@ -2652,7 +2652,7 @@ Ideally, controllers under test should be invoked as they are at runtime, much l the approach to testing controllers that handle HTTP requests by using the Spring MVC Test framework -- that is, without running a Servlet container but relying on the Spring Framework to invoke the annotated controllers. As with Spring MVC Test, you have two -two possible alternatives here, either use a "`context-based`" or use a "`standalone`" setup: +possible alternatives here, either use a "`context-based`" or use a "`standalone`" setup: * Load the actual Spring configuration with the help of the Spring TestContext framework, inject `clientInboundChannel` as a test field, and From 7854f4964311ba97f11e260a8c47bb55d8055a9b Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 24 Oct 2019 20:57:25 +0100 Subject: [PATCH 4/6] Polishing in HttpWebHandlerAdapter Closes gh-23780 --- .../server/adapter/HttpWebHandlerAdapter.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java b/spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java index 8f4788adafb..bd3edea6ace 100644 --- a/spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java @@ -267,12 +267,14 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa ServerHttpResponse response = exchange.getResponse(); String logPrefix = exchange.getLogPrefix(); - if (isDisconnectedClientError(ex)) { - // Request handling error (e.g. remote call), if we manage to set the status.. - if (response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR)) { - logger.error(logPrefix + "500 Server Error for " + formatRequest(request), ex); - return Mono.empty(); - } + // Sometimes a remote call error can look like a disconnected client. + // Try to set the response first before the "isDisconnectedClient" check. + + if (response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR)) { + logger.error(logPrefix + "500 Server Error for " + formatRequest(request), ex); + return Mono.empty(); + } + else if (isDisconnectedClientError(ex)) { if (lostClientLogger.isTraceEnabled()) { lostClientLogger.trace(logPrefix + "Client went away", ex); } @@ -282,10 +284,6 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa } return Mono.empty(); } - else if (response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR)) { - logger.error(logPrefix + "500 Server Error for " + formatRequest(request), ex); - return Mono.empty(); - } else { // After the response is committed, propagate errors to the server... logger.error(logPrefix + "Error [" + ex + "] for " + formatRequest(request) + From 3a377f86b237e957610ff21ac9f6553e1beca11e Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 25 Oct 2019 09:00:22 +0200 Subject: [PATCH 5/6] Start building against Californium-SR13 snapshots See gh-23870 --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f8751bdd78e..a609b9b375a 100644 --- a/build.gradle +++ b/build.gradle @@ -38,7 +38,7 @@ ext { kotlinVersion = "1.2.71" log4jVersion = "2.11.2" nettyVersion = "4.1.39.Final" - reactorVersion = "Californium-SR12" + reactorVersion = "Californium-BUILD-SNAPSHOT" rxjavaVersion = "1.3.8" rxjavaAdapterVersion = "1.2.1" rxjava2Version = "2.2.12" @@ -148,6 +148,7 @@ configure(allprojects) { project -> repositories { maven { url "https://repo.spring.io/libs-release" } + maven { url "https://repo.spring.io/snapshot" } mavenLocal() } From 7ca96c02bd2f1d4c8d9282364650315dfeb2fb31 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 25 Oct 2019 09:06:53 +0200 Subject: [PATCH 6/6] Upgrade to Netty 4.1.43.Final --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a609b9b375a..f3ae8271c90 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ ext { junit5Version = "5.3.2" kotlinVersion = "1.2.71" log4jVersion = "2.11.2" - nettyVersion = "4.1.39.Final" + nettyVersion = "4.1.43.Final" reactorVersion = "Californium-BUILD-SNAPSHOT" rxjavaVersion = "1.3.8" rxjavaAdapterVersion = "1.2.1"