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 import java.util.List;
27
28
29
30
31 class PerMessageDeflateEncoder extends DeflateEncoder {
32
33 private boolean compressing;
34
35
36
37
38
39
40
41
42 PerMessageDeflateEncoder(int compressionLevel, int windowSize, boolean noContext) {
43 super(compressionLevel, windowSize, noContext, WebSocketExtensionFilter.NEVER_SKIP);
44 }
45
46
47
48
49
50
51
52
53
54 PerMessageDeflateEncoder(int compressionLevel, int windowSize, boolean noContext,
55 WebSocketExtensionFilter extensionEncoderFilter) {
56 super(compressionLevel, windowSize, noContext, extensionEncoderFilter);
57 }
58
59 @Override
60 public boolean acceptOutboundMessage(Object msg) throws Exception {
61 if (!super.acceptOutboundMessage(msg)) {
62 return false;
63 }
64
65 WebSocketFrame wsFrame = (WebSocketFrame) msg;
66 if (extensionEncoderFilter().mustSkip(wsFrame)) {
67 if (compressing) {
68 throw new IllegalStateException("Cannot skip per message deflate encoder, compression in progress");
69 }
70 return false;
71 }
72
73 return (wsFrame instanceof TextWebSocketFrame || wsFrame instanceof BinaryWebSocketFrame) &&
74 (wsFrame.rsv() & WebSocketExtension.RSV1) == 0 ||
75 wsFrame instanceof ContinuationWebSocketFrame && compressing;
76 }
77
78 @Override
79 protected int rsv(WebSocketFrame msg) {
80 return msg instanceof TextWebSocketFrame || msg instanceof BinaryWebSocketFrame?
81 msg.rsv() | WebSocketExtension.RSV1 : msg.rsv();
82 }
83
84 @Override
85 protected boolean removeFrameTail(WebSocketFrame msg) {
86 return msg.isFinalFragment();
87 }
88
89 @Override
90 protected void encodeAndClose(ChannelHandlerContext ctx, WebSocketFrame msg,
91 List<Object> out) throws Exception {
92 super.encodeAndClose(ctx, msg, out);
93
94 if (msg.isFinalFragment()) {
95 compressing = false;
96 } else if (msg instanceof TextWebSocketFrame || msg instanceof BinaryWebSocketFrame) {
97 compressing = true;
98 }
99 }
100 }