Skip to content

Commit 288a9ec

Browse files
committed
Exposes maxFramePayloadLength for Reactor Netty
Issue: SPR-16228
1 parent a278e87 commit 288a9ec

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/NettyWebSocketSessionSupport.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@
4545
public abstract class NettyWebSocketSessionSupport<T> extends AbstractWebSocketSession<T> {
4646

4747
/**
48-
* The default max size for aggregating inbound WebSocket frames.
48+
* The default max size for inbound WebSocket frames.
4949
*/
50-
protected static final int DEFAULT_FRAME_MAX_SIZE = 64 * 1024;
50+
public static final int DEFAULT_FRAME_MAX_SIZE = 64 * 1024;
5151

5252

5353
private static final Map<Class<?>, WebSocketMessage.Type> messageTypes;

spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/ReactorNettyWebSocketSession.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,35 @@
4343
public class ReactorNettyWebSocketSession
4444
extends NettyWebSocketSessionSupport<ReactorNettyWebSocketSession.WebSocketConnection> {
4545

46+
private final int maxFramePayloadLength;
4647

48+
49+
/**
50+
* Constructor for the session, using the {@link #DEFAULT_FRAME_MAX_SIZE} value.
51+
*/
4752
public ReactorNettyWebSocketSession(WebsocketInbound inbound, WebsocketOutbound outbound,
4853
HandshakeInfo info, NettyDataBufferFactory bufferFactory) {
4954

55+
this(inbound, outbound, info, bufferFactory, DEFAULT_FRAME_MAX_SIZE);
56+
}
57+
58+
/**
59+
* Constructor with an additional maxFramePayloadLength argument.
60+
* @since 5.1
61+
*/
62+
public ReactorNettyWebSocketSession(WebsocketInbound inbound, WebsocketOutbound outbound,
63+
HandshakeInfo info, NettyDataBufferFactory bufferFactory,
64+
int maxFramePayloadLength) {
65+
5066
super(new WebSocketConnection(inbound, outbound), info, bufferFactory);
67+
this.maxFramePayloadLength = maxFramePayloadLength;
5168
}
5269

5370

5471
@Override
5572
public Flux<WebSocketMessage> receive() {
5673
return getDelegate().getInbound()
57-
.aggregateFrames(DEFAULT_FRAME_MAX_SIZE)
74+
.aggregateFrames(this.maxFramePayloadLength)
5875
.receiveFrames()
5976
.map(super::toMessage)
6077
.doOnNext(message -> {

spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/upgrade/ReactorNettyRequestUpgradeStrategy.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.springframework.lang.Nullable;
2828
import org.springframework.web.reactive.socket.HandshakeInfo;
2929
import org.springframework.web.reactive.socket.WebSocketHandler;
30+
import org.springframework.web.reactive.socket.adapter.NettyWebSocketSessionSupport;
3031
import org.springframework.web.reactive.socket.adapter.ReactorNettyWebSocketSession;
3132
import org.springframework.web.reactive.socket.server.RequestUpgradeStrategy;
3233
import org.springframework.web.server.ServerWebExchange;
@@ -39,18 +40,49 @@
3940
*/
4041
public class ReactorNettyRequestUpgradeStrategy implements RequestUpgradeStrategy {
4142

43+
private int maxFramePayloadLength = NettyWebSocketSessionSupport.DEFAULT_FRAME_MAX_SIZE;
44+
45+
46+
/**
47+
* Configure the maximum allowable frame payload length. Setting this value
48+
* to your application's requirement may reduce denial of service attacks
49+
* using long data frames.
50+
* <p>Corresponds to the argument with the same name in the constructor of
51+
* {@link io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory
52+
* WebSocketServerHandshakerFactory} in Netty.
53+
* <p>By default set to 65536 (64K).
54+
* @param maxFramePayloadLength the max length for frames.
55+
* @since 5.1
56+
*/
57+
public void setMaxFramePayloadLength(Integer maxFramePayloadLength) {
58+
this.maxFramePayloadLength = maxFramePayloadLength;
59+
}
60+
61+
/**
62+
* Return the configured max length for frames.
63+
* @since 5.1
64+
*/
65+
public int getMaxFramePayloadLength() {
66+
return this.maxFramePayloadLength;
67+
}
68+
4269

4370
@Override
4471
public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
4572
@Nullable String subProtocol, Supplier<HandshakeInfo> handshakeInfoFactory) {
4673

4774
ServerHttpResponse response = exchange.getResponse();
48-
HttpServerResponse nativeResponse = ((AbstractServerHttpResponse) response).getNativeResponse();
75+
HttpServerResponse reactorResponse = ((AbstractServerHttpResponse) response).getNativeResponse();
4976
HandshakeInfo handshakeInfo = handshakeInfoFactory.get();
5077
NettyDataBufferFactory bufferFactory = (NettyDataBufferFactory) response.bufferFactory();
5178

52-
return nativeResponse.sendWebsocket(subProtocol,
53-
(in, out) -> handler.handle(new ReactorNettyWebSocketSession(in, out, handshakeInfo, bufferFactory)));
79+
return reactorResponse.sendWebsocket(subProtocol, this.maxFramePayloadLength,
80+
(in, out) -> {
81+
ReactorNettyWebSocketSession session =
82+
new ReactorNettyWebSocketSession(
83+
in, out, handshakeInfo, bufferFactory, this.maxFramePayloadLength);
84+
return handler.handle(session);
85+
});
5486
}
5587

5688
}

0 commit comments

Comments
 (0)