Skip to content

Commit b68fa4b

Browse files
committed
Notify of WebSocket Continuation frames when aggregateWebSocketFrameFragments is disabled, close #1396
Motivation: 98bef40 introduced a aggregateWebSocketFrameFragments config option. But when it's set to false, WebSocketListener are not notified with those. Modifications: Memorize current fragment type and notify of Continuation frames content. Result: Fixed support of non aggregated fragmented frames
1 parent 9ec6104 commit b68fa4b

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

Diff for: client/src/main/java/org/asynchttpclient/netty/ws/NettyWebSocket.java

+45
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public class NettyWebSocket implements WebSocket {
5252
// no need for volatile because only mutated in IO thread
5353
private boolean ready;
5454
private List<WebSocketFrame> bufferedFrames;
55+
protected FragmentedFrameType expectedFragmentedFrameType;
5556

5657
public NettyWebSocket(Channel channel, HttpHeaders upgradeHeaders) {
5758
this(channel, upgradeHeaders, new ConcurrentLinkedQueue<>());
@@ -238,6 +239,9 @@ public void handleFrame(WebSocketFrame frame) {
238239

239240
} else if (frame instanceof PongWebSocketFrame) {
240241
onPongFrame((PongWebSocketFrame) frame);
242+
243+
} else if (frame instanceof ContinuationWebSocketFrame) {
244+
onContinuationFrame((ContinuationWebSocketFrame) frame);
241245
}
242246
}
243247

@@ -276,13 +280,27 @@ public String toString() {
276280
}
277281

278282
public void onBinaryFrame(BinaryWebSocketFrame frame) {
283+
if (expectedFragmentedFrameType == null && !frame.isFinalFragment()) {
284+
expectedFragmentedFrameType = FragmentedFrameType.BINARY;
285+
}
286+
onBinaryFrame0(frame);
287+
}
288+
289+
private void onBinaryFrame0(WebSocketFrame frame) {
279290
byte[] bytes = byteBuf2Bytes(frame.content());
280291
for (WebSocketListener listener : listeners) {
281292
listener.onBinaryFrame(bytes, frame.isFinalFragment(), frame.rsv());
282293
}
283294
}
284295

285296
public void onTextFrame(TextWebSocketFrame frame) {
297+
if (expectedFragmentedFrameType == null && !frame.isFinalFragment()) {
298+
expectedFragmentedFrameType = FragmentedFrameType.TEXT;
299+
}
300+
onTextFrame0(frame);
301+
}
302+
303+
private void onTextFrame0(WebSocketFrame frame) {
286304
try {
287305
// faster than frame.text();
288306
String text = Utf8ByteBufCharsetDecoder.decodeUtf8(frame.content());
@@ -296,6 +314,29 @@ public void onTextFrame(TextWebSocketFrame frame) {
296314
}
297315
}
298316

317+
public void onContinuationFrame(ContinuationWebSocketFrame frame) {
318+
if (expectedFragmentedFrameType == null) {
319+
LOGGER.warn("Received continuation frame without an original text or binary frame, ignoring");
320+
return;
321+
}
322+
try {
323+
switch (expectedFragmentedFrameType) {
324+
case BINARY:
325+
onBinaryFrame0(frame);
326+
break;
327+
case TEXT:
328+
onTextFrame0(frame);
329+
break;
330+
default:
331+
throw new IllegalArgumentException("Unknown FragmentedFrameType " + expectedFragmentedFrameType);
332+
}
333+
} finally {
334+
if (frame.isFinalFragment()) {
335+
expectedFragmentedFrameType = null;
336+
}
337+
}
338+
}
339+
299340
public void onPingFrame(PingWebSocketFrame frame) {
300341
byte[] bytes = byteBuf2Bytes(frame.content());
301342
for (WebSocketListener listener : listeners) {
@@ -309,4 +350,8 @@ public void onPongFrame(PongWebSocketFrame frame) {
309350
listener.onPongFrame(bytes);
310351
}
311352
}
353+
354+
private enum FragmentedFrameType {
355+
TEXT, BINARY;
356+
}
312357
}

0 commit comments

Comments
 (0)