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.handler.codec.http.websocketx.extensions.WebSocketExtensionData;
19 import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionDecoder;
20 import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionEncoder;
21 import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionFilterProvider;
22 import io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtension;
23 import io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandshaker;
24
25 import java.util.Collections;
26
27 import static io.netty.util.internal.ObjectUtil.*;
28
29
30
31
32
33 public final class DeflateFrameServerExtensionHandshaker implements WebSocketServerExtensionHandshaker {
34
35 public static final int DEFAULT_COMPRESSION_LEVEL = 6;
36 public static final int MIN_WINDOW_SIZE = 8;
37 public static final int MAX_WINDOW_SIZE = 15;
38 public static final int DEFAULT_MEM_LEVEL = 8;
39 public static final int MIN_MEM_LEVEL = 1;
40 public static final int MAX_MEM_LEVEL = 9;
41
42 static final String X_WEBKIT_DEFLATE_FRAME_EXTENSION = "x-webkit-deflate-frame";
43 static final String DEFLATE_FRAME_EXTENSION = "deflate-frame";
44
45 private final int compressionLevel;
46 private final int windowSize;
47 private final int memLevel;
48 private final WebSocketExtensionFilterProvider extensionFilterProvider;
49 private final int maxAllocation;
50
51
52
53
54
55
56
57 @Deprecated
58 public DeflateFrameServerExtensionHandshaker() {
59 this(DEFAULT_COMPRESSION_LEVEL, 0);
60 }
61
62
63
64
65
66
67
68
69
70 @Deprecated
71 public DeflateFrameServerExtensionHandshaker(int compressionLevel) {
72 this(compressionLevel, 0);
73 }
74
75
76
77
78
79
80
81
82
83 public DeflateFrameServerExtensionHandshaker(int compressionLevel, int maxAllocation) {
84 this(compressionLevel, MAX_WINDOW_SIZE, DEFAULT_MEM_LEVEL, WebSocketExtensionFilterProvider.DEFAULT,
85 maxAllocation);
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 public DeflateFrameServerExtensionHandshaker(int compressionLevel, int windowSize, int memLevel,
103 int maxAllocation) {
104 this(compressionLevel, windowSize, memLevel, WebSocketExtensionFilterProvider.DEFAULT, maxAllocation);
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118 @Deprecated
119 public DeflateFrameServerExtensionHandshaker(int compressionLevel,
120 WebSocketExtensionFilterProvider extensionFilterProvider) {
121 this(compressionLevel, extensionFilterProvider, 0);
122 }
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 @Deprecated
138 public DeflateFrameServerExtensionHandshaker(int compressionLevel,
139 WebSocketExtensionFilterProvider extensionFilterProvider,
140 int maxAllocation) {
141 this(compressionLevel, MAX_WINDOW_SIZE, DEFAULT_MEM_LEVEL, extensionFilterProvider, maxAllocation);
142 }
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 public DeflateFrameServerExtensionHandshaker(int compressionLevel, int windowSize, int memLevel,
159 WebSocketExtensionFilterProvider extensionFilterProvider,
160 int maxAllocation) {
161 if (compressionLevel < 0 || compressionLevel > 9) {
162 throw new IllegalArgumentException(
163 "compressionLevel: " + compressionLevel + " (expected: 0-9)");
164 }
165 this.compressionLevel = compressionLevel;
166 this.windowSize = checkInRange(windowSize, MIN_WINDOW_SIZE, MAX_WINDOW_SIZE, "windowSize");
167 this.memLevel = checkInRange(memLevel, MIN_MEM_LEVEL, MAX_MEM_LEVEL, "memLevel");
168 this.extensionFilterProvider = checkNotNull(extensionFilterProvider, "extensionFilterProvider");
169 this.maxAllocation = checkPositiveOrZero(maxAllocation, "maxAllocation");
170 }
171
172 @Override
173 public WebSocketServerExtension handshakeExtension(WebSocketExtensionData extensionData) {
174 if (!X_WEBKIT_DEFLATE_FRAME_EXTENSION.equals(extensionData.name()) &&
175 !DEFLATE_FRAME_EXTENSION.equals(extensionData.name())) {
176 return null;
177 }
178
179 if (extensionData.parameters().isEmpty()) {
180 return new DeflateFrameServerExtension(compressionLevel, windowSize, memLevel, extensionData.name(),
181 extensionFilterProvider, maxAllocation);
182 } else {
183 return null;
184 }
185 }
186
187 private static class DeflateFrameServerExtension implements WebSocketServerExtension {
188
189 private final String extensionName;
190 private final int compressionLevel;
191 private final int windowSize;
192 private final int memLevel;
193 private final WebSocketExtensionFilterProvider extensionFilterProvider;
194 private final int maxAllocation;
195
196 DeflateFrameServerExtension(int compressionLevel, int windowSize, int memLevel, String extensionName,
197 WebSocketExtensionFilterProvider extensionFilterProvider,
198 int maxAllocation) {
199 this.extensionName = extensionName;
200 this.compressionLevel = compressionLevel;
201 this.windowSize = windowSize;
202 this.memLevel = memLevel;
203 this.extensionFilterProvider = extensionFilterProvider;
204 this.maxAllocation = maxAllocation;
205 }
206
207 @Override
208 public int rsv() {
209 return RSV1;
210 }
211
212 @Override
213 public WebSocketExtensionEncoder newExtensionEncoder() {
214 return new PerFrameDeflateEncoder(compressionLevel, windowSize, memLevel, false,
215 extensionFilterProvider.encoderFilter());
216 }
217
218 @Override
219 public WebSocketExtensionDecoder newExtensionDecoder() {
220 return new PerFrameDeflateDecoder(false, extensionFilterProvider.decoderFilter(), maxAllocation);
221 }
222
223 @Override
224 public WebSocketExtensionData newReponseData() {
225 return new WebSocketExtensionData(extensionName, Collections.<String, String>emptyMap());
226 }
227 }
228
229 }