1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http.websocketx.extensions.compression;
17
18 import io.netty.channel.ChannelHandlerContext;
19 import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
20 import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
21 import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
22 import io.netty.handler.codec.http.websocketx.WebSocketFrame;
23 import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtension;
24 import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilter;
25
26 import java.util.List;
27
28
29
30
31 class PerMessageDeflateDecoder extends DeflateDecoder {
32
33 private boolean compressing;
34
35
36
37
38
39
40 PerMessageDeflateDecoder(boolean noContext) {
41 super(noContext, WebSocketExtensionFilter.NEVER_SKIP);
42 }
43
44
45
46
47
48
49
50 PerMessageDeflateDecoder(boolean noContext, WebSocketExtensionFilter extensionDecoderFilter) {
51 super(noContext, extensionDecoderFilter);
52 }
53
54 @Override
55 public boolean acceptInboundMessage(Object msg) throws Exception {
56 if (!super.acceptInboundMessage(msg)) {
57 return false;
58 }
59
60 WebSocketFrame wsFrame = (WebSocketFrame) msg;
61 if (extensionDecoderFilter().mustSkip(wsFrame)) {
62 if (compressing) {
63 throw new IllegalStateException("Cannot skip per message deflate decoder, compression in progress");
64 }
65 return false;
66 }
67
68 return ((wsFrame instanceof TextWebSocketFrame || wsFrame instanceof BinaryWebSocketFrame) &&
69 (wsFrame.rsv() & WebSocketExtension.RSV1) > 0) ||
70 (wsFrame instanceof ContinuationWebSocketFrame && compressing);
71 }
72
73 @Override
74 protected int newRsv(WebSocketFrame msg) {
75 return (msg.rsv() & WebSocketExtension.RSV1) > 0?
76 msg.rsv() ^ WebSocketExtension.RSV1 : msg.rsv();
77 }
78
79 @Override
80 protected boolean appendFrameTail(WebSocketFrame msg) {
81 return msg.isFinalFragment();
82 }
83
84 @Override
85 protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg,
86 List<Object> out) throws Exception {
87 super.decode(ctx, msg, out);
88
89 if (msg.isFinalFragment()) {
90 compressing = false;
91 } else if (msg instanceof TextWebSocketFrame || msg instanceof BinaryWebSocketFrame) {
92 compressing = true;
93 }
94 }
95
96 }