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
59 public class CompressionFilter extends WriteRequestFilter {
60
61
62
63
64 public static final int COMPRESSION_MAX = Zlib.COMPRESSION_MAX;
65
66
67
68
69 public static final int COMPRESSION_MIN = Zlib.COMPRESSION_MIN;
70
71
72
73
74 public static final int COMPRESSION_NONE = Zlib.COMPRESSION_NONE;
75
76
77
78
79
80 public static final int COMPRESSION_DEFAULT = Zlib.COMPRESSION_DEFAULT;
81
82
83
84
85 private final AttributeKey DEFLATER = new AttributeKey(getClass(), "deflater");
86
87
88
89
90 private final AttributeKey INFLATER = new AttributeKey(getClass(), "inflater");
91
92
93
94
95 public static final AttributeKey DISABLE_COMPRESSION_ONCE = new AttributeKey(CompressionFilter.class, "disableOnce");
96
97 private boolean compressInbound = true;
98
99 private boolean compressOutbound = true;
100
101 private int compressionLevel;
102
103
104
105
106
107 public CompressionFilter() {
108 this(true, true, COMPRESSION_DEFAULT);
109 }
110
111
112
113
114
115
116
117
118
119
120
121 public CompressionFilter(final int compressionLevel) {
122 this(true, true, compressionLevel);
123 }
124
125
126
127
128
129
130
131
132
133
134
135
136 public CompressionFilter(final boolean compressInbound,
137 final boolean compressOutbound, final int compressionLevel) {
138 this.compressionLevel = compressionLevel;
139 this.compressInbound = compressInbound;
140 this.compressOutbound = compressOutbound;
141 }
142
143 @Override
144 public void messageReceived(NextFilter nextFilter, IoSession session,
145 Object message) throws Exception {
146 if (!compressInbound || !(message instanceof IoBuffer)) {
147 nextFilter.messageReceived(session, message);
148 return;
149 }
150
151 Zlib inflater = (Zlib) session.getAttribute(INFLATER);
152 if (inflater == null) {
153 throw new IllegalStateException();
154 }
155
156 IoBuffer inBuffer = (IoBuffer) message;
157 IoBuffer outBuffer = inflater.inflate(inBuffer);
158 nextFilter.messageReceived(session, outBuffer);
159 }
160
161
162
163
164 @Override
165 protected Object doFilterWrite(
166 NextFilter nextFilter, IoSession session,
167 WriteRequest writeRequest) throws IOException {
168 if (!compressOutbound) {
169 return null;
170 }
171
172 if (session.containsAttribute(DISABLE_COMPRESSION_ONCE)) {
173
174 session.removeAttribute(DISABLE_COMPRESSION_ONCE);
175 return null;
176 }
177
178 Zlib deflater = (Zlib) session.getAttribute(DEFLATER);
179 if (deflater == null) {
180 throw new IllegalStateException();
181 }
182
183 IoBuffer inBuffer = (IoBuffer) writeRequest.getMessage();
184 if (!inBuffer.hasRemaining()) {
185
186 return null;
187 } else {
188 return deflater.deflate(inBuffer);
189 }
190 }
191
192 @Override
193 public void onPreAdd(IoFilterChain parent, String name,
194 NextFilter nextFilter) throws Exception {
195 if (parent.contains(CompressionFilter.class)) {
196 throw new IllegalStateException(
197 "Only one " + CompressionFilter.class + " is permitted.");
198 }
199
200 Zlib deflater = new Zlib(compressionLevel, Zlib.MODE_DEFLATER);
201 Zlib inflater = new Zlib(compressionLevel, Zlib.MODE_INFLATER);
202
203 IoSession session = parent.getSession();
204
205 session.setAttribute(DEFLATER, deflater);
206 session.setAttribute(INFLATER, inflater);
207 }
208
209
210
211
212 public boolean isCompressInbound() {
213 return compressInbound;
214 }
215
216
217
218
219 public void setCompressInbound(boolean compressInbound) {
220 this.compressInbound = compressInbound;
221 }
222
223
224
225
226 public boolean isCompressOutbound() {
227 return compressOutbound;
228 }
229
230
231
232
233 public void setCompressOutbound(boolean compressOutbound) {
234 this.compressOutbound = compressOutbound;
235 }
236
237 @Override
238 public void onPostRemove(IoFilterChain parent, String name,
239 NextFilter nextFilter) throws Exception {
240 super.onPostRemove(parent, name, nextFilter);
241 IoSession session = parent.getSession();
242 if (session == null) {
243 return;
244 }
245
246 Zlib inflater = (Zlib) session.getAttribute(INFLATER);
247 Zlib deflater = (Zlib) session.getAttribute(DEFLATER);
248 if (deflater != null) {
249 deflater.cleanUp();
250 }
251
252 if (inflater != null) {
253 inflater.cleanUp();
254 }
255 }
256 }