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