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