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