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 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
60
61
62
63
64
65
66
67
68 PerMessageDeflateEncoder(int compressionLevel, int windowSize, int memLevel, boolean noContext,
69 WebSocketExtensionFilter extensionEncoderFilter) {
70 super(compressionLevel, windowSize, memLevel, noContext, extensionEncoderFilter);
71 }
72
73 @Override
74 public boolean acceptOutboundMessage(Object msg) throws Exception {
75 if (!super.acceptOutboundMessage(msg)) {
76 return false;
77 }
78
79 WebSocketFrame wsFrame = (WebSocketFrame) msg;
80 if (extensionEncoderFilter().mustSkip(wsFrame)) {
81 if (compressing) {
82 throw new IllegalStateException("Cannot skip per message deflate encoder, compression in progress");
83 }
84 return false;
85 }
86
87 return ((wsFrame instanceof TextWebSocketFrame || wsFrame instanceof BinaryWebSocketFrame) &&
88 (wsFrame.rsv() & WebSocketExtension.RSV1) == 0) ||
89 (wsFrame instanceof ContinuationWebSocketFrame && compressing);
90 }
91
92 @Override
93 protected int rsv(WebSocketFrame msg) {
94 return msg instanceof TextWebSocketFrame || msg instanceof BinaryWebSocketFrame?
95 msg.rsv() | WebSocketExtension.RSV1 : msg.rsv();
96 }
97
98 @Override
99 protected boolean removeFrameTail(WebSocketFrame msg) {
100 return msg.isFinalFragment();
101 }
102
103 @Override
104 protected void encode(ChannelHandlerContext ctx, WebSocketFrame msg,
105 List<Object> out) throws Exception {
106 super.encode(ctx, msg, out);
107
108 if (msg.isFinalFragment()) {
109 compressing = false;
110 } else if (msg instanceof TextWebSocketFrame || msg instanceof BinaryWebSocketFrame) {
111 compressing = true;
112 }
113 }
114
115 }