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,
136 final boolean compressOutbound, final int compressionLevel) {
137 this.compressionLevel = compressionLevel;
138 this.compressInbound = compressInbound;
139 this.compressOutbound = compressOutbound;
140 }
141
142 @Override
143 public void messageReceived(NextFilter nextFilter, IoSession session,
144 Object message) throws Exception {
145 if (!compressInbound || !(message instanceof IoBuffer)) {
146 nextFilter.messageReceived(session, message);
147 return;
148 }
149
150 Zlib inflater = (Zlib) session.getAttribute(INFLATER);
151 if (inflater == null) {
152 throw new IllegalStateException();
153 }
154
155 IoBuffer inBuffer = (IoBuffer) message;
156 IoBuffer outBuffer = inflater.inflate(inBuffer);
157 nextFilter.messageReceived(session, outBuffer);
158 }
159
160
161
162
163 @Override
164 protected Object doFilterWrite(
165 NextFilter nextFilter, IoSession session,
166 WriteRequest writeRequest) throws IOException {
167 if (!compressOutbound) {
168 return null;
169 }
170
171 if (session.containsAttribute(DISABLE_COMPRESSION_ONCE)) {
172
173 session.removeAttribute(DISABLE_COMPRESSION_ONCE);
174 return null;
175 }
176
177 Zlib deflater = (Zlib) session.getAttribute(DEFLATER);
178 if (deflater == null) {
179 throw new IllegalStateException();
180 }
181
182 IoBuffer inBuffer = (IoBuffer) writeRequest.getMessage();
183 if (!inBuffer.hasRemaining()) {
184
185 return null;
186 } else {
187 return deflater.deflate(inBuffer);
188 }
189 }
190
191 @Override
192 public void onPreAdd(IoFilterChain parent, String name,
193 NextFilter nextFilter) throws Exception {
194 if (parent.contains(CompressionFilter.class)) {
195 throw new IllegalStateException(
196 "Only one " + CompressionFilter.class + " is permitted.");
197 }
198
199 Zlib deflater = new Zlib(compressionLevel, Zlib.MODE_DEFLATER);
200 Zlib inflater = new Zlib(compressionLevel, Zlib.MODE_INFLATER);
201
202 IoSession session = parent.getSession();
203
204 session.setAttribute(DEFLATER, deflater);
205 session.setAttribute(INFLATER, inflater);
206 }
207
208
209
210
211 public boolean isCompressInbound() {
212 return compressInbound;
213 }
214
215
216
217
218 public void setCompressInbound(boolean compressInbound) {
219 this.compressInbound = compressInbound;
220 }
221
222
223
224
225 public boolean isCompressOutbound() {
226 return compressOutbound;
227 }
228
229
230
231
232 public void setCompressOutbound(boolean compressOutbound) {
233 this.compressOutbound = compressOutbound;
234 }
235
236 @Override
237 public void onPostRemove(IoFilterChain parent, String name,
238 NextFilter nextFilter) throws Exception {
239 super.onPostRemove(parent, name, nextFilter);
240 IoSession session = parent.getSession();
241 if (session == null) {
242 return;
243 }
244
245 Zlib inflater = (Zlib) session.getAttribute(INFLATER);
246 Zlib deflater = (Zlib) session.getAttribute(DEFLATER);
247 if (deflater != null) {
248 deflater.cleanUp();
249 }
250
251 if (inflater != null) {
252 inflater.cleanUp();
253 }
254 }
255 }