1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.ehcache.constructs.web;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21
22 import javax.servlet.http.Cookie;
23 import javax.servlet.http.HttpServletResponse;
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.io.Serializable;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.zip.GZIPInputStream;
33 import java.util.zip.GZIPOutputStream;
34
35
36
37
38
39
40
41
42 public class PageInfo implements Serializable {
43 private static final Log LOG = LogFactory.getLog(PageInfo.class.getName());
44 private static final int FOUR_KB = 4196;
45 private static final int GZIP_MAGIC_NUMBER_BYTE_1 = 31;
46 private static final int GZIP_MAGIC_NUMBER_BYTE_2 = -117;
47 private final ArrayList headers = new ArrayList();
48 private final ArrayList serializableCookies = new ArrayList();
49 private String contentType;
50 private byte[] gzippedBody;
51 private byte[] ungzippedBody;
52 private int statusCode;
53 private boolean storeGzipped;
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public PageInfo(final int statusCode, final String contentType, final Collection headers, final Collection cookies,
68 final byte[] body, boolean storeGzipped) throws AlreadyGzippedException {
69 this.headers.addAll(headers);
70 this.headers.remove("Content-Encoding");
71 this.contentType = contentType;
72 this.storeGzipped = storeGzipped;
73 this.statusCode = statusCode;
74
75 extractCookies(cookies);
76
77 try {
78 if (storeGzipped) {
79
80 ungzippedBody = null;
81 if (isBodyParameterGzipped()) {
82 gzippedBody = body;
83 } else {
84 gzippedBody = gzip(body);
85 }
86 } else {
87 if (isBodyParameterGzipped()) {
88 throw new IllegalArgumentException("Non gzip content has been gzipped.");
89 } else {
90 ungzippedBody = body;
91 }
92 }
93 } catch (IOException e) {
94 LOG.error("Error ungzipping gzipped body", e);
95 }
96
97
98 }
99
100 private void extractCookies(Collection cookies) {
101 for (Iterator iterator = cookies.iterator(); iterator.hasNext();) {
102 final Cookie cookie = (Cookie) iterator.next();
103 serializableCookies.add(new SerializableCookie(cookie));
104 }
105 }
106
107
108
109
110
111 private byte[] gzip(byte[] ungzipped) throws IOException, AlreadyGzippedException {
112 if (isGzipped(ungzipped)) {
113 throw new AlreadyGzippedException("The byte[] is already gzipped. It should not be gzipped again.");
114 }
115 final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
116 final GZIPOutputStream gzipOutputStream = new GZIPOutputStream(bytes);
117 gzipOutputStream.write(ungzipped);
118 gzipOutputStream.close();
119 return bytes.toByteArray();
120 }
121
122
123
124
125
126
127 private boolean isBodyParameterGzipped() {
128 for (int i = 0; i < headers.size(); i++) {
129 String[] keyValuePair = (String[]) headers.get(i);
130 if (keyValuePair[1].equals("gzip")) {
131 return true;
132 }
133 }
134 return false;
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148 public static boolean isGzipped(byte[] candidate) {
149 if (candidate == null || candidate.length < 2) {
150 return false;
151 } else {
152 return (candidate[0] == GZIP_MAGIC_NUMBER_BYTE_1 && candidate[1] == GZIP_MAGIC_NUMBER_BYTE_2);
153 }
154 }
155
156
157
158
159 public String getContentType() {
160 return contentType;
161 }
162
163
164
165
166 public byte[] getGzippedBody() {
167 if (storeGzipped) {
168 return gzippedBody;
169 } else {
170 return null;
171 }
172 }
173
174
175
176
177 public List getHeaders() {
178 return headers;
179 }
180
181
182
183
184 public List getSerializableCookies() {
185 return serializableCookies;
186 }
187
188
189
190
191 public int getStatusCode() {
192 return statusCode;
193 }
194
195
196
197
198
199 public byte[] getUngzippedBody() throws IOException {
200 if (storeGzipped) {
201 return ungzip(gzippedBody);
202 } else {
203 return ungzippedBody;
204 }
205 }
206
207
208
209
210
211
212
213
214
215 private byte[] ungzip(final byte[] gzipped) throws IOException {
216 final GZIPInputStream inputStream = new GZIPInputStream(new ByteArrayInputStream(gzipped));
217 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(gzipped.length);
218 final byte[] buffer = new byte[FOUR_KB];
219 int bytesRead = 0;
220 while (bytesRead != -1) {
221 bytesRead = inputStream.read(buffer, 0, FOUR_KB);
222 if (bytesRead != -1) {
223 byteArrayOutputStream.write(buffer, 0, bytesRead);
224 }
225 }
226 byte[] ungzipped = byteArrayOutputStream.toByteArray();
227 inputStream.close();
228 byteArrayOutputStream.close();
229 return ungzipped;
230 }
231
232
233
234
235 public boolean hasGzippedBody() {
236 return (gzippedBody != null);
237 }
238
239
240
241
242 public boolean hasUngzippedBody() {
243 return (ungzippedBody != null);
244 }
245
246
247
248
249 public boolean isOk() {
250 return (statusCode == HttpServletResponse.SC_OK);
251 }
252 }
253