1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.compression;
21
22 import java.io.IOException;
23
24 import org.apache.mina.core.buffer.IoBuffer;
25 import org.apache.mina.core.filterchain.IoFilter;
26 import org.apache.mina.core.filterchain.IoFilterChain;
27 import org.apache.mina.core.session.AttributeKey;
28 import org.apache.mina.core.session.IoSession;
29 import org.apache.mina.core.write.WriteRequest;
30 import org.apache.mina.filter.util.WriteRequestFilter;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class CompressionFilter extends WriteRequestFilter {
59
60
61
62
63 public static final int COMPRESSION_MAX = Zlib.COMPRESSION_MAX;
64
65
66
67
68 public static final int COMPRESSION_MIN = Zlib.COMPRESSION_MIN;
69
70
71
72
73 public static final int COMPRESSION_NONE = Zlib.COMPRESSION_NONE;
74
75
76
77
78
79 public static final int COMPRESSION_DEFAULT = Zlib.COMPRESSION_DEFAULT;
80
81
82
83
84 private final AttributeKey DEFLATER = new AttributeKey(getClass(), "deflater");
85
86
87
88
89 private final AttributeKey INFLATER = new AttributeKey(getClass(), "inflater");
90
91
92
93
94 public static final AttributeKey DISABLE_COMPRESSION_ONCE = new AttributeKey(CompressionFilter.class, "disableOnce");
95
96 private boolean compressInbound = true;
97
98 private boolean compressOutbound = true;
99
100 private int compressionLevel;
101
102
103
104
105
106 public CompressionFilter() {
107 this(true, true, COMPRESSION_DEFAULT);
108 }
109
110
111
112
113
114
115
116
117
118
119
120 public CompressionFilter(final int compressionLevel) {
121 this(true, true, compressionLevel);
122 }
123
124
125
126
127
128
129
130
131
132
133
134
135 public CompressionFilter(final boolean compressInbound, final boolean compressOutbound, final int compressionLevel) {
136 this.compressionLevel = compressionLevel;
137 this.compressInbound = compressInbound;
138 this.compressOutbound = compressOutbound;
139 }
140
141 @Override
142 public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
143 if (!compressInbound || !(message instanceof IoBuffer)) {
144 nextFilter.messageReceived(session, message);
145 return;
146 }
147
148 Zlib inflater = (Zlib) session.getAttribute(INFLATER);
149 if (inflater == null) {
150 throw new IllegalStateException();
151 }
152
153 IoBuffer inBuffer = (IoBuffer) message;
154 IoBuffer outBuffer = inflater.inflate(inBuffer);
155 nextFilter.messageReceived(session, outBuffer);
156 }
157
158
159
160
161 @Override
162 protected Object doFilterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest)
163 throws IOException {
164 if (!compressOutbound) {
165 return null;
166 }
167
168 if (session.containsAttribute(DISABLE_COMPRESSION_ONCE)) {
169
170 session.removeAttribute(DISABLE_COMPRESSION_ONCE);
171 return null;
172 }
173
174 Zlib deflater = (Zlib) session.getAttribute(DEFLATER);
175 if (deflater == null) {
176 throw new IllegalStateException();
177 }
178
179 IoBuffer inBuffer = (IoBuffer) writeRequest.getMessage();
180 if (!inBuffer.hasRemaining()) {
181
182 return null;
183 } else {
184 return deflater.deflate(inBuffer);
185 }
186 }
187
188 @Override
189 public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception {
190 if (parent.contains(CompressionFilter.class)) {
191 throw new IllegalStateException("Only one " + CompressionFilter.class + " is permitted.");
192 }
193
194 Zlib deflater = new Zlib(compressionLevel, Zlib.MODE_DEFLATER);
195 Zlib inflater = new Zlib(compressionLevel, Zlib.MODE_INFLATER);
196
197 IoSession session = parent.getSession();
198
199 session.setAttribute(DEFLATER, deflater);
200 session.setAttribute(INFLATER, inflater);
201 }
202
203
204
205
206 public boolean isCompressInbound() {
207 return compressInbound;
208 }
209
210
211
212
213
214
215 public void setCompressInbound(boolean compressInbound) {
216 this.compressInbound = compressInbound;
217 }
218
219
220
221
222 public boolean isCompressOutbound() {
223 return compressOutbound;
224 }
225
226
227
228
229
230
231 public void setCompressOutbound(boolean compressOutbound) {
232 this.compressOutbound = compressOutbound;
233 }
234
235 @Override
236 public void onPostRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception {
237 super.onPostRemove(parent, name, nextFilter);
238 IoSession session = parent.getSession();
239 if (session == null) {
240 return;
241 }
242
243 Zlib inflater = (Zlib) session.getAttribute(INFLATER);
244 Zlib deflater = (Zlib) session.getAttribute(DEFLATER);
245 if (deflater != null) {
246 deflater.cleanUp();
247 }
248
249 if (inflater != null) {
250 inflater.cleanUp();
251 }
252 }
253 }