1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.codec.http.websocketx;
17
18
19 import org.jboss.netty.buffer.ChannelBuffer;
20 import org.jboss.netty.buffer.ChannelBuffers;
21 import org.jboss.netty.channel.Channel;
22 import org.jboss.netty.channel.ChannelHandlerContext;
23 import org.jboss.netty.handler.codec.frame.TooLongFrameException;
24 import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
25
26
27
28
29
30
31
32 public class WebSocketFrameAggregator extends OneToOneDecoder {
33 private final int maxFrameSize;
34 private WebSocketFrame currentFrame;
35 private boolean tooLongFrameFound;
36
37
38
39
40
41
42
43 public WebSocketFrameAggregator(int maxFrameSize) {
44 if (maxFrameSize < 1) {
45 throw new IllegalArgumentException("maxFrameSize must be > 0");
46 }
47 this.maxFrameSize = maxFrameSize;
48 }
49
50 @Override
51 protected Object decode(ChannelHandlerContext ctx, Channel channel, Object message) throws Exception {
52 if (!(message instanceof WebSocketFrame)) {
53 return message;
54 }
55 WebSocketFrame msg = (WebSocketFrame) message;
56 if (currentFrame == null) {
57 tooLongFrameFound = false;
58 if (msg.isFinalFragment()) {
59 return msg;
60 }
61 ChannelBuffer buf = msg.getBinaryData();
62
63 if (msg instanceof TextWebSocketFrame) {
64 currentFrame = new TextWebSocketFrame(true, msg.getRsv(), buf);
65 } else if (msg instanceof BinaryWebSocketFrame) {
66 currentFrame = new BinaryWebSocketFrame(true, msg.getRsv(), buf);
67 } else {
68 throw new IllegalStateException(
69 "WebSocket frame was not of type TextWebSocketFrame or BinaryWebSocketFrame");
70 }
71 return null;
72 }
73 if (msg instanceof ContinuationWebSocketFrame) {
74 if (tooLongFrameFound) {
75 if (msg.isFinalFragment()) {
76 currentFrame = null;
77 }
78 return null;
79 }
80 ChannelBuffer content = currentFrame.getBinaryData();
81 if (content.readableBytes() > maxFrameSize - msg.getBinaryData().readableBytes()) {
82 tooLongFrameFound = true;
83 throw new TooLongFrameException(
84 "WebSocketFrame length exceeded " + content +
85 " bytes.");
86 }
87 currentFrame.setBinaryData(ChannelBuffers.wrappedBuffer(content, msg.getBinaryData()));
88
89 if (msg.isFinalFragment()) {
90 WebSocketFrame currentFrame = this.currentFrame;
91 this.currentFrame = null;
92 return currentFrame;
93 } else {
94 return null;
95 }
96 }
97
98
99 return msg;
100 }
101 }