1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit;
16
17 import static java.nio.charset.StandardCharsets.UTF_8;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.Writer;
22 import java.net.URL;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import javax.servlet.Servlet;
29 import javax.servlet.http.HttpServlet;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.apache.commons.io.IOUtils;
34 import org.apache.commons.lang3.StringUtils;
35 import org.htmlunit.html.HtmlPage;
36 import org.htmlunit.http.HttpStatus;
37 import org.htmlunit.junit.BrowserRunner;
38 import org.htmlunit.util.MimeType;
39 import org.htmlunit.util.NameValuePair;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42
43
44
45
46
47
48
49
50 @RunWith(BrowserRunner.class)
51 public class WebResponseDataTest extends WebServerTestCase {
52
53 private static final String GZIPPED_FILE = "testfiles/test.html.gz";
54 private static final String BROTLI_FILE = "testfiles/test.html.brotli";
55
56
57
58
59
60 @Test
61 public void gZippedContent() throws Exception {
62 final InputStream stream = getClass().getClassLoader().getResourceAsStream(GZIPPED_FILE);
63 final byte[] zippedContent = IOUtils.toByteArray(stream);
64
65 final List<NameValuePair> headers = new ArrayList<>();
66 headers.add(new NameValuePair("Content-Encoding", "gzip"));
67
68 final WebResponseData data = new WebResponseData(zippedContent,
69 HttpStatus.OK_200, HttpStatus.OK_200_MSG, headers);
70 final String body = new String(data.getBody(), UTF_8);
71 assertTrue(StringUtils.contains(body, "Test"));
72
73 final WebResponse response = new WebResponse(data, new URL("http://test.com"), HttpMethod.GET, 1000);
74 assertEquals(body, response.getContentAsString(UTF_8));
75 }
76
77
78
79
80
81 @Test
82 public void emptyGZippedContent() throws Exception {
83 testEmptyGZippedContent(HttpStatus.OK_200, 0, null);
84 }
85
86
87
88
89
90 @Test
91 public void contentLengthIsZero() throws Exception {
92 testEmptyGZippedContent(HttpStatus.OK_200, 0, MimeType.TEXT_HTML);
93 }
94
95
96
97
98
99 @Test
100 public void contentLengthIsMissing() throws Exception {
101 testEmptyGZippedContent(HttpStatus.NO_CONTENT_204, -1, null);
102 }
103
104
105
106
107
108 @Test
109 public void htmlEncodingGzipOnlyTextHtml() throws Exception {
110 final InputStream stream = getClass().getClassLoader().getResourceAsStream(GZIPPED_FILE);
111 final byte[] zippedContent = IOUtils.toByteArray(stream);
112
113 final List<NameValuePair> headers = new ArrayList<>();
114 headers.add(new NameValuePair("Content-Encoding", "gzip-only-text/html"));
115 headers.add(new NameValuePair("content-type", MimeType.TEXT_HTML));
116
117 final WebResponseData data = new WebResponseData(zippedContent,
118 HttpStatus.OK_200, HttpStatus.OK_200_MSG, headers);
119 final String body = new String(data.getBody(), UTF_8);
120 assertTrue(StringUtils.contains(body, "Test"));
121
122 final WebResponse response = new WebResponse(data, new URL("http://test.com"), HttpMethod.GET, 1000);
123 assertEquals(body, response.getContentAsString(UTF_8));
124 }
125
126
127
128
129
130 @Test
131 public void binaryEncodingGzipOnlyTextHtml() throws Exception {
132 final InputStream stream = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-png.img");
133 final byte[] zippedContent = IOUtils.toByteArray(stream);
134
135 final List<NameValuePair> headers = new ArrayList<>();
136 headers.add(new NameValuePair("Content-Encoding", "gzip-only-text/html"));
137 headers.add(new NameValuePair("content-type", MimeType.IMAGE_PNG));
138
139 final WebResponseData data = new WebResponseData(zippedContent,
140 HttpStatus.OK_200, HttpStatus.OK_200_MSG, headers);
141 final byte[] bytes = IOUtils.toByteArray(data.getInputStream());
142 assertEquals(128, bytes.length);
143 assertEquals(137 - 256, bytes[0]);
144 assertEquals(80, bytes[1]);
145 assertEquals(78, bytes[2]);
146
147 final WebResponse response = new WebResponse(data, new URL("http://test.com"), HttpMethod.GET, 1000);
148 assertEquals(new String(bytes, UTF_8), response.getContentAsString(UTF_8));
149 }
150
151
152
153
154
155 @Test
156 public void binaryEncodingNoGzip() throws Exception {
157 final InputStream stream = getClass().getClassLoader().getResourceAsStream("testfiles/xhtml.html");
158 final byte[] zippedContent = IOUtils.toByteArray(stream);
159
160 final List<NameValuePair> headers = new ArrayList<>();
161 headers.add(new NameValuePair("Content-Encoding", "no-gzip"));
162 headers.add(new NameValuePair("content-type", MimeType.TEXT_HTML));
163
164 final WebResponseData data = new WebResponseData(zippedContent,
165 HttpStatus.OK_200, HttpStatus.OK_200_MSG, headers);
166 final String body = new String(data.getBody(), UTF_8);
167 assertTrue(StringUtils.contains(body, "Test"));
168
169 final WebResponse response = new WebResponse(data, new URL("http://test.com"), HttpMethod.GET, 1000);
170 assertEquals(body, response.getContentAsString(UTF_8));
171 }
172
173 private static void testEmptyGZippedContent(final int statusCode, final int contentLength,
174 final String contentType) throws Exception {
175 final List<NameValuePair> headers = new ArrayList<>();
176 headers.add(new NameValuePair("Content-Encoding", "gzip"));
177
178 if (contentLength != -1) {
179 headers.add(new NameValuePair(HttpHeader.CONTENT_LENGTH, String.valueOf(contentLength)));
180 }
181
182 if (contentType != null) {
183 headers.add(new NameValuePair(HttpHeader.CONTENT_TYPE, contentType));
184 }
185
186 final WebResponseData data = new WebResponseData("".getBytes(),
187 HttpStatus.OK_200, HttpStatus.OK_200_MSG, headers);
188 final String body = new String(data.getBody(), UTF_8);
189
190 final WebResponse response = new WebResponse(data, new URL("http://test.com"), HttpMethod.GET, 1000);
191 assertEquals(body, response.getContentAsString(UTF_8));
192 }
193
194
195
196
197
198 @Test
199 public void brokenGZippedContent() throws Exception {
200 final List<NameValuePair> headers = new ArrayList<>();
201 headers.add(new NameValuePair("Content-Encoding", "gzip"));
202
203 final WebResponseData data = new WebResponseData("Plain Content".getBytes(),
204 HttpStatus.OK_200, HttpStatus.OK_200_MSG, headers);
205 try {
206 data.getBody();
207 }
208 catch (final RuntimeException e) {
209 assertTrue(e.getMessage(), StringUtils.contains(e.getMessage(), "Not in GZIP format"));
210 }
211 }
212
213
214
215
216
217 @Test
218 public void brotliContent() throws Exception {
219 final InputStream stream = getClass().getClassLoader().getResourceAsStream(BROTLI_FILE);
220 final byte[] zippedContent = IOUtils.toByteArray(stream);
221
222 final List<NameValuePair> headers = new ArrayList<>();
223 headers.add(new NameValuePair("Content-Encoding", "br"));
224
225 final WebResponseData data = new WebResponseData(zippedContent,
226 HttpStatus.OK_200, HttpStatus.OK_200_MSG, headers);
227 final String body = new String(data.getBody(), UTF_8);
228 assertTrue(StringUtils.contains(body, "Test"));
229
230 final WebResponse response = new WebResponse(data, new URL("http://test.com"), HttpMethod.GET, 1000);
231 assertEquals(body, response.getContentAsString(UTF_8));
232 }
233
234
235
236
237
238 @Test
239 public void brokenBrotliContent() throws Exception {
240 final List<NameValuePair> headers = new ArrayList<>();
241 headers.add(new NameValuePair("Content-Encoding", "br"));
242
243 final WebResponseData data = new WebResponseData("Plain Content".getBytes(),
244 HttpStatus.OK_200, HttpStatus.OK_200_MSG, headers);
245 try {
246 data.getBody();
247 }
248 catch (final RuntimeException e) {
249 assertTrue(e.getMessage(), StringUtils.contains(e.getMessage(), "Brotli stream decoding failed"));
250 }
251 }
252
253
254
255
256
257
258 @Test
259 public void nullBody() throws Exception {
260 final DownloadedContent downloadedContent = new DownloadedContent.InMemory(new byte[] {});
261 final List<NameValuePair> headers = new ArrayList<>();
262 final WebResponseData data = new WebResponseData(downloadedContent, 304, "NOT_MODIFIED", headers);
263 assertEquals(0, data.getBody().length);
264
265 final WebResponse response = new WebResponse(data, new URL("http://test.com"), HttpMethod.GET, 1000);
266 assertEquals(0, response.getContentAsString(UTF_8).length());
267 }
268
269
270
271
272 @Test
273 public void deflateCompression() throws Exception {
274 startWebServer("src/test/resources/pjl-comp-filter", null);
275 final WebRequest request = new WebRequest(new URL("http://localhost:"
276 + PORT + "/index.html"));
277 request.setAdditionalHeader(HttpHeader.ACCEPT_ENCODING, "deflate");
278 final WebClient webClient = getWebClient();
279 final HtmlPage page = webClient.getPage(request);
280 assertEquals("Hello Compressed World!", page.asNormalizedText());
281 }
282
283
284
285
286 @Test
287 public void redirection() throws Exception {
288 final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
289 servlets.put("/folder1/page1", RedirectionServlet.class);
290 servlets.put("/folder2/page2", RedirectionServlet.class);
291 startWebServer("./", null, servlets);
292
293 final WebClient client = getWebClient();
294
295 final HtmlPage page = client.getPage(URL_FIRST + "folder1/page1");
296 assertEquals("Hello Redirected!", page.asNormalizedText());
297 }
298
299
300
301
302 public static class RedirectionServlet extends HttpServlet {
303
304
305
306 @Override
307 protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
308 if ("/folder1/page1".equals(request.getRequestURI())) {
309 response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
310 final String location = request.getRequestURL().toString().replace("page1", "../folder2/page2");
311 response.setHeader("Location", location);
312 return;
313 }
314 response.setContentType(MimeType.TEXT_HTML);
315 final Writer writer = response.getWriter();
316 writer.write("Hello Redirected!");
317 }
318 }
319
320 }