2121
2222import reactor .core .publisher .Mono ;
2323import reactor .netty .http .server .HttpServerResponse ;
24+ import reactor .netty .http .server .WebsocketServerSpec ;
2425
2526import org .springframework .core .io .buffer .NettyDataBufferFactory ;
2627import org .springframework .http .server .reactive .AbstractServerHttpResponse ;
2728import org .springframework .http .server .reactive .ServerHttpResponse ;
2829import org .springframework .http .server .reactive .ServerHttpResponseDecorator ;
2930import org .springframework .lang .Nullable ;
31+ import org .springframework .util .Assert ;
3032import org .springframework .web .reactive .socket .HandshakeInfo ;
3133import org .springframework .web .reactive .socket .WebSocketHandler ;
32- import org .springframework .web .reactive .socket .adapter .NettyWebSocketSessionSupport ;
3334import org .springframework .web .reactive .socket .adapter .ReactorNettyWebSocketSession ;
3435import org .springframework .web .reactive .socket .server .RequestUpgradeStrategy ;
3536import org .springframework .web .server .ServerWebExchange ;
4243 */
4344public class ReactorNettyRequestUpgradeStrategy implements RequestUpgradeStrategy {
4445
45- private int maxFramePayloadLength = NettyWebSocketSessionSupport . DEFAULT_FRAME_MAX_SIZE ;
46+ private final Supplier < WebsocketServerSpec . Builder > specBuilderSupplier ;
4647
47- private boolean handlePing = false ;
48+ @ Nullable
49+ private Integer maxFramePayloadLength ;
4850
51+ @ Nullable
52+ private Boolean handlePing ;
53+
54+
55+ /**
56+ * Create an instances with a default {@link WebsocketServerSpec.Builder}.
57+ * @since 5.2.6
58+ */
59+ public ReactorNettyRequestUpgradeStrategy () {
60+ this (WebsocketServerSpec .builder ());
61+ }
62+
63+
64+ /**
65+ * Create an instance with a pre-configured {@link WebsocketServerSpec.Builder}
66+ * to use for WebSocket upgrades.
67+ * @since 5.2.6
68+ */
69+ public ReactorNettyRequestUpgradeStrategy (Supplier <WebsocketServerSpec .Builder > builderSupplier ) {
70+ Assert .notNull (builderSupplier , "WebsocketServerSpec.Builder is required" );
71+ this .specBuilderSupplier = builderSupplier ;
72+ }
73+
74+
75+ /**
76+ * Build an instance of {@code WebsocketServerSpec} that reflects the current
77+ * configuration. This can be used to check the configured parameters except
78+ * for sub-protocols which depend on the {@link WebSocketHandler} that is used
79+ * for a given upgrade.
80+ * @since 5.2.6
81+ */
82+ public WebsocketServerSpec getWebsocketServerSpec () {
83+ return buildSpec (null );
84+ }
85+
86+ private WebsocketServerSpec buildSpec (@ Nullable String subProtocol ) {
87+ WebsocketServerSpec .Builder builder = this .specBuilderSupplier .get ();
88+ if (subProtocol != null ) {
89+ builder .protocols (subProtocol );
90+ }
91+ if (this .maxFramePayloadLength != null ) {
92+ builder .maxFramePayloadLength (this .maxFramePayloadLength );
93+ }
94+ if (this .handlePing != null ) {
95+ builder .handlePing (this .handlePing );
96+ }
97+ return builder .build ();
98+ }
4999
50100 /**
51101 * Configure the maximum allowable frame payload length. Setting this value
@@ -57,17 +107,22 @@ public class ReactorNettyRequestUpgradeStrategy implements RequestUpgradeStrateg
57107 * <p>By default set to 65536 (64K).
58108 * @param maxFramePayloadLength the max length for frames.
59109 * @since 5.1
110+ * @deprecated as of 5.2.6 in favor of providing a supplier of
111+ * {@link WebsocketServerSpec.Builder} wiht a constructor argument.
60112 */
113+ @ Deprecated
61114 public void setMaxFramePayloadLength (Integer maxFramePayloadLength ) {
62115 this .maxFramePayloadLength = maxFramePayloadLength ;
63116 }
64117
65118 /**
66119 * Return the configured max length for frames.
67120 * @since 5.1
121+ * @deprecated as of 5.2.6 in favor of {@link #getWebsocketServerSpec()}
68122 */
123+ @ Deprecated
69124 public int getMaxFramePayloadLength () {
70- return this .maxFramePayloadLength ;
125+ return getWebsocketServerSpec () .maxFramePayloadLength () ;
71126 }
72127
73128 /**
@@ -80,43 +135,46 @@ public int getMaxFramePayloadLength() {
80135 * frames will be passed through to the {@link WebSocketHandler}.
81136 * @param handlePing whether to let Ping frames through for handling
82137 * @since 5.2.4
138+ * @deprecated as of 5.2.6 in favor of providing a supplier of
139+ * {@link WebsocketServerSpec.Builder} wiht a constructor argument.
83140 */
141+ @ Deprecated
84142 public void setHandlePing (boolean handlePing ) {
85143 this .handlePing = handlePing ;
86144 }
87145
88146 /**
89147 * Return the configured {@link #setHandlePing(boolean)}.
90148 * @since 5.2.4
149+ * @deprecated as of 5.2.6 in favor of {@link #getWebsocketServerSpec()}
91150 */
151+ @ Deprecated
92152 public boolean getHandlePing () {
93- return this .handlePing ;
153+ return getWebsocketServerSpec () .handlePing () ;
94154 }
95155
96156
97157 @ Override
98- @ SuppressWarnings ("deprecation" )
99158 public Mono <Void > upgrade (ServerWebExchange exchange , WebSocketHandler handler ,
100159 @ Nullable String subProtocol , Supplier <HandshakeInfo > handshakeInfoFactory ) {
101160
102161 ServerHttpResponse response = exchange .getResponse ();
103162 HttpServerResponse reactorResponse = getNativeResponse (response );
104163 HandshakeInfo handshakeInfo = handshakeInfoFactory .get ();
105164 NettyDataBufferFactory bufferFactory = (NettyDataBufferFactory ) response .bufferFactory ();
165+ URI uri = exchange .getRequest ().getURI ();
106166
107167 // Trigger WebFlux preCommit actions and upgrade
108168 return response .setComplete ()
109- .then (Mono .defer (() -> reactorResponse .sendWebsocket (
110- subProtocol ,
111- this .maxFramePayloadLength ,
112- this .handlePing ,
113- (in , out ) -> {
114- ReactorNettyWebSocketSession session =
115- new ReactorNettyWebSocketSession (
116- in , out , handshakeInfo , bufferFactory , this .maxFramePayloadLength );
117- URI uri = exchange .getRequest ().getURI ();
118- return handler .handle (session ).checkpoint (uri + " [ReactorNettyRequestUpgradeStrategy]" );
119- })));
169+ .then (Mono .defer (() -> {
170+ WebsocketServerSpec spec = buildSpec (subProtocol );
171+ return reactorResponse .sendWebsocket ((in , out ) -> {
172+ ReactorNettyWebSocketSession session =
173+ new ReactorNettyWebSocketSession (
174+ in , out , handshakeInfo , bufferFactory , spec .maxFramePayloadLength ());
175+ return handler .handle (session ).checkpoint (uri + " [ReactorNettyRequestUpgradeStrategy]" );
176+ }, spec );
177+ }));
120178 }
121179
122180 private static HttpServerResponse getNativeResponse (ServerHttpResponse response ) {
0 commit comments