1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit;
16
17 import static org.junit.jupiter.api.Assertions.fail;
18
19 import java.io.IOException;
20 import java.io.Writer;
21 import java.net.SocketTimeoutException;
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import javax.servlet.Servlet;
26 import javax.servlet.http.HttpServlet;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29
30 import org.htmlunit.html.HtmlPage;
31 import org.htmlunit.util.Cookie;
32 import org.htmlunit.util.MimeType;
33 import org.junit.jupiter.api.Test;
34
35
36
37
38
39
40
41 public class WebClient4Test extends WebServerTestCase {
42
43
44
45
46
47 @Test
48 public void serialization_afterUse() throws Exception {
49 startWebServer("./");
50
51 try (WebClient client = getWebClient()) {
52 TextPage textPage = client.getPage(URL_FIRST + "LICENSE.txt");
53 assertTrue(textPage.getContent().contains("Apache License"));
54
55 try (WebClient copy = clone(client)) {
56 assertNotNull(copy);
57
58 final WebWindow window = copy.getCurrentWindow();
59 assertNotNull(window);
60
61 final WebWindow topWindow = window.getTopWindow();
62 assertNotNull(topWindow);
63
64 final Page page = topWindow.getEnclosedPage();
65 assertNotNull(page);
66
67 final WebResponse response = page.getWebResponse();
68 assertNotNull(response);
69
70 final String content = response.getContentAsString();
71 assertNotNull(content);
72 assertTrue(content.contains("Apache License"));
73
74 textPage = copy.getPage(URL_FIRST + "LICENSE.txt");
75 assertTrue(textPage.getContent().contains("Apache License"));
76 }
77 }
78 }
79
80
81
82
83
84
85 @Test
86 public void redirectInfinite303And307() throws Exception {
87 final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
88 servlets.put(RedirectServlet307.URL, RedirectServlet307.class);
89 servlets.put(RedirectServlet303.URL, RedirectServlet303.class);
90 startWebServer("./", new String[0], servlets);
91
92 final WebClient client = getWebClient();
93
94 try {
95 client.getPage("http://localhost:" + PORT + RedirectServlet307.URL);
96 }
97 catch (final Exception e) {
98 assertTrue(e.getMessage(), e.getMessage().contains("Too much redirect"));
99 }
100 }
101
102
103
104
105 public static class RedirectServlet extends HttpServlet {
106 private int count_;
107 private int status_;
108 private String location_;
109
110
111
112
113
114
115 public RedirectServlet(final int status, final String location) {
116 count_ = 0;
117 status_ = status;
118 location_ = location;
119 }
120
121
122
123
124 @Override
125 protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
126 count_++;
127 resp.setStatus(status_);
128 resp.setHeader("Location", location_);
129 resp.getWriter().write(status_ + " " + req.getContextPath() + " " + count_);
130 }
131 }
132
133
134
135
136 public static class RedirectServlet303 extends RedirectServlet {
137 static final String URL = "/test";
138
139 public RedirectServlet303() {
140 super(303, RedirectServlet307.URL);
141 }
142 }
143
144
145
146
147 public static class RedirectServlet307 extends RedirectServlet {
148 static final String URL = "/test2";
149
150 public RedirectServlet307() {
151 super(307, RedirectServlet303.URL);
152 }
153 }
154
155
156
157
158
159
160 @Test
161 public void bodyDowloadTime() throws Exception {
162 final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
163 servlets.put("/*", ServeBodySlowlyServlet.class);
164 startWebServer("./", new String[0], servlets);
165
166 final Page page = getWebClient().getPage(URL_FIRST);
167 final long loadTime = page.getWebResponse().getLoadTime();
168 assertTrue("Load time: " + loadTime + ", last request time: " + ServeBodySlowlyServlet.LastRequestTime_,
169 loadTime >= ServeBodySlowlyServlet.LastRequestTime_);
170 }
171
172
173
174
175 public static class ServeBodySlowlyServlet extends HttpServlet {
176 private static volatile long LastRequestTime_ = -1;
177
178 @Override
179 protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
180 final long before = System.currentTimeMillis();
181 final Writer writer = resp.getWriter();
182 writeSomeContent(writer);
183 writer.flush();
184 try {
185 Thread.sleep(500);
186 }
187 catch (final InterruptedException e) {
188 throw new RuntimeException(e);
189 }
190 writeSomeContent(writer);
191 LastRequestTime_ = System.currentTimeMillis() - before;
192 }
193
194 private static void writeSomeContent(final Writer writer) throws IOException {
195 for (int i = 0; i < 1000; i++) {
196 writer.append((char) ('a' + (i % 26)));
197 }
198 }
199 }
200
201
202
203
204 @Test
205 public void useProxy() throws Exception {
206 final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
207 servlets.put("/test", UseProxyHeaderServlet.class);
208 startWebServer("./", null, servlets);
209
210 final WebClient client = getWebClient();
211 final HtmlPage page = client.getPage(URL_FIRST + "test");
212 assertEquals("Going anywhere?", page.asNormalizedText());
213 }
214
215
216
217
218 public static class UseProxyHeaderServlet extends HttpServlet {
219
220
221
222 @Override
223 protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
224 response.setStatus(HttpServletResponse.SC_USE_PROXY);
225
226
227 response.setContentType(MimeType.TEXT_HTML);
228 final Writer writer = response.getWriter();
229 writer.write(DOCTYPE_HTML + "<html><body>Going anywhere?</body></html>");
230 }
231 }
232
233
234
235
236
237 @Test
238 public void noContent() throws Exception {
239 final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
240 servlets.put("/test1", NoContentServlet1.class);
241 servlets.put("/test2", NoContentServlet2.class);
242 startWebServer("./", null, servlets);
243 final WebClient client = getWebClient();
244 final HtmlPage page = client.getPage(URL_FIRST + "test1");
245 final HtmlPage page2 = page.getHtmlElementById("submit").click();
246 assertEquals(page, page2);
247 }
248
249
250
251
252 public static class NoContentServlet1 extends HttpServlet {
253
254
255
256 @Override
257 protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws IOException {
258 res.setContentType(MimeType.TEXT_HTML);
259 final Writer writer = res.getWriter();
260 writer.write(DOCTYPE_HTML
261 + "<html><body><form action='test2'>\n"
262 + "<input id='submit' type='submit' value='submit'></input>\n"
263 + "</form></body></html>");
264 }
265 }
266
267
268
269
270 public static class NoContentServlet2 extends HttpServlet {
271
272
273
274 @Override
275 protected void doGet(final HttpServletRequest req, final HttpServletResponse res) {
276 res.setStatus(HttpServletResponse.SC_NO_CONTENT);
277 }
278 }
279
280
281
282
283
284
285
286 @Test
287 public void notModified() throws Exception {
288 final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
289 servlets.put("/test", NotModifiedServlet.class);
290 startWebServer("./", null, servlets);
291 final WebClient client = getWebClient();
292 final HtmlPage page = client.getPage(URL_FIRST + "test");
293 final TextPage page2 = client.getPage(URL_FIRST + "test");
294 assertNotNull(page);
295 assertNotNull(page2);
296 }
297
298
299
300
301 public static class NotModifiedServlet extends HttpServlet {
302 private boolean first_ = true;
303
304
305
306
307 @Override
308 protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws IOException {
309 if (first_) {
310 first_ = false;
311 res.setContentType(MimeType.TEXT_HTML);
312 final Writer writer = res.getWriter();
313 writer.write(DOCTYPE_HTML + "<html><body>foo</body></html>");
314 }
315 else {
316 res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
317 }
318 }
319 }
320
321
322
323
324 @Test
325 public void timeout() throws Exception {
326 final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
327 servlets.put("/*", DelayDeliverServlet.class);
328 startWebServer("./", null, servlets);
329
330 final WebClient client = getWebClient();
331 client.getOptions().setTimeout(500);
332
333 try {
334 client.getPage(URL_FIRST);
335 fail("timeout expected!");
336 }
337 catch (final SocketTimeoutException e) {
338
339 }
340
341
342 client.getOptions().setTimeout(5000);
343 client.getPage(URL_FIRST);
344 }
345
346
347
348
349
350
351 @Test
352 public void requestHeaderCookieFromRequest() throws Exception {
353 final String content = DOCTYPE_HTML + "<html></html>";
354 final MockWebConnection webConnection = new MockWebConnection();
355 webConnection.setDefaultResponse(content);
356
357 startWebServer(webConnection);
358
359 final WebClient client = getWebClient();
360
361
362 client.getPage(URL_FIRST);
363 assertNull(webConnection.getLastAdditionalHeaders().get(HttpHeader.COOKIE));
364
365
366 WebRequest wr = new WebRequest(URL_FIRST, HttpMethod.GET);
367 wr.setAdditionalHeader(HttpHeader.COOKIE, "yummy_cookie=choco");
368 client.getPage(wr);
369 assertEquals("yummy_cookie=choco", webConnection.getLastAdditionalHeaders().get(HttpHeader.COOKIE));
370
371
372 final CookieManager mgr = client.getCookieManager();
373 mgr.addCookie(new Cookie(URL_FIRST.getHost(), "my_key", "my_value", "/", null, false));
374 wr = new WebRequest(URL_FIRST, HttpMethod.GET);
375 client.getPage(wr);
376 assertEquals("my_key=my_value", webConnection.getLastAdditionalHeaders().get(HttpHeader.COOKIE));
377
378
379 wr = new WebRequest(URL_FIRST, HttpMethod.GET);
380 wr.setAdditionalHeader(HttpHeader.COOKIE, "yummy_cookie=choco");
381 client.getPage(wr);
382 assertEquals("yummy_cookie=choco", webConnection.getLastAdditionalHeaders().get(HttpHeader.COOKIE));
383
384
385 wr = new WebRequest(URL_FIRST, HttpMethod.GET);
386 final Map<String, String> headers = new HashMap<>();
387 headers.put("accept-language", "es-ES,es;q=0.9");
388 headers.put(HttpHeader.COOKIE, "tasty_cookie=strawberry");
389 wr.setAdditionalHeaders(headers);
390 client.getPage(wr);
391 assertEquals("tasty_cookie=strawberry", webConnection.getLastAdditionalHeaders().get(HttpHeader.COOKIE));
392
393
394 wr = new WebRequest(URL_FIRST, HttpMethod.GET);
395 client.getPage(wr);
396 assertEquals("my_key=my_value", webConnection.getLastAdditionalHeaders().get(HttpHeader.COOKIE));
397 }
398
399
400
401
402 public static class DelayDeliverServlet extends HttpServlet {
403
404
405
406 @Override
407 protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws IOException {
408 try {
409 Thread.sleep(1000);
410 }
411 catch (final InterruptedException e) {
412 throw new RuntimeException(e);
413 }
414 res.setContentType(MimeType.TEXT_HTML);
415 final Writer writer = res.getWriter();
416 writer.write(DOCTYPE_HTML + "<html><head><title>hello</title></head><body>foo</body></html>");
417 }
418 }
419
420
421
422
423 @Test
424 public void redirectInfiniteMeta() throws Exception {
425 final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
426 servlets.put("/test1", RedirectMetaServlet1.class);
427 servlets.put("/test2", RedirectMetaServlet2.class);
428 startWebServer("./", new String[0], servlets);
429
430 final WebClient client = getWebClient();
431
432 try {
433 client.getPage(URL_FIRST + "test1");
434 }
435 catch (final Exception e) {
436 assertTrue(e.getMessage(), e.getMessage().contains("Too much redirect"));
437 }
438 }
439
440
441
442
443 public static class RedirectMetaServlet1 extends HttpServlet {
444
445
446
447 @Override
448 protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws IOException {
449 res.setContentType(MimeType.TEXT_HTML);
450 final Writer writer = res.getWriter();
451 writer.write(DOCTYPE_HTML
452 + "<html><head>\n"
453 + " <meta http-equiv='refresh' content='0;URL=test2'>\n"
454 + "</head><body>foo</body></html>");
455 }
456 }
457
458
459
460
461 public static class RedirectMetaServlet2 extends HttpServlet {
462
463
464
465 @Override
466 protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws IOException {
467 res.setContentType(MimeType.TEXT_HTML);
468 final Writer writer = res.getWriter();
469 writer.write(DOCTYPE_HTML
470 + "<html><head>\n"
471 + " <meta http-equiv='refresh' content='0;URL=test1'>\n"
472 + "</head><body>foo</body></html>");
473 }
474 }
475 }