1 /*
2 * Copyright (c) 2002-2026 Gargoyle Software Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 * https://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.htmlunit;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.Serializable;
21 import java.net.InetAddress;
22 import java.net.URL;
23 import java.security.KeyStore;
24 import java.security.KeyStoreException;
25 import java.security.NoSuchAlgorithmException;
26 import java.security.cert.CertificateException;
27
28 import javax.net.ssl.SSLContext;
29
30 import org.apache.commons.io.FileUtils;
31
32 /**
33 * Configuration options for {@link WebClient} instances.
34 * This class provides fine-grained control over client behavior including:
35 * <ul>
36 * <li>JavaScript and CSS processing</li>
37 * <li>SSL/TLS configuration and certificates</li>
38 * <li>HTTP timeouts and proxy settings</li>
39 * <li>Memory management and temporary file handling</li>
40 * <li>WebSocket and geolocation support</li>
41 * </ul>
42 *
43 * <p>All options have sensible defaults and can be modified independently.</p>
44 *
45 * @author Ahmed Ashour
46 * @author Marc Guillemot
47 * @author Madis Pärn
48 * @author Ronald Brill
49 */
50 @SuppressWarnings("PMD.TooManyFields")
51 public class WebClientOptions implements Serializable {
52
53 /** 1920. */
54 private static final int DEFAULT_SCRREN_WIDTH = 1920;
55 /** 1080. */
56 private static final int DEFAULT_SCRREN_HEIGHT = 1080;
57
58 private boolean javaScriptEnabled_ = true;
59 private boolean cssEnabled_ = true;
60 private boolean printContentOnFailingStatusCode_ = true;
61 private boolean throwExceptionOnFailingStatusCode_ = true;
62 private boolean throwExceptionOnScriptError_ = true;
63 private boolean popupBlockerEnabled_;
64 private boolean isRedirectEnabled_ = true;
65 // strange value 72 used to be backward compatible with 4.14.0
66 private int pageRefreshLimit_ = 72;
67 private File tempFileDirectory_;
68
69 private transient KeyStore sslClientCertificateStore_;
70 private char[] sslClientCertificatePassword_;
71 private transient KeyStore sslTrustStore_;
72 private String[] sslClientProtocols_;
73 private String[] sslClientCipherSuites_;
74
75 private transient SSLContext sslContext_;
76 private boolean useInsecureSSL_; // default is secure SSL
77 private String sslInsecureProtocol_;
78
79 private boolean doNotTrackEnabled_;
80 private String homePage_ = "https://www.htmlunit.org/";
81 private ProxyConfig proxyConfig_;
82 private int timeout_ = 90_000; // like Firefox 16 default's value for network.http.connection-timeout
83 private long connectionTimeToLive_ = -1; // HttpClient default
84
85 private boolean fileProtocolForXMLHttpRequestsAllowed_;
86
87 private int maxInMemory_ = 500 * 1024;
88 private int historySizeLimit_ = 50;
89 private int historyPageCacheLimit_ = Integer.MAX_VALUE;
90 private InetAddress localAddress_;
91 private boolean downloadImages_;
92 private int screenWidth_ = DEFAULT_SCRREN_WIDTH;
93 private int screenHeight_ = DEFAULT_SCRREN_HEIGHT;
94
95 private boolean geolocationEnabled_;
96 private Geolocation geolocation_;
97
98 private int nekoReaderBufferSize_ = -1;
99
100 private boolean webSocketEnabled_ = true;
101 private int webSocketMaxTextMessageSize_ = -1;
102 private int webSocketMaxBinaryMessageSize_ = -1;
103
104 private boolean isFetchPolyfillEnabled_;
105
106 /**
107 * Sets the SSLContext; if this is set it is used and some other settings are
108 * ignored (protocol, keyStore, keyStorePassword, trustStore,
109 * sslClientCertificateStore, sslClientCertificatePassword).
110 * <p>
111 * This property is transient (because SSLContext is not serializable)
112 * </p>
113 *
114 * @param sslContext the SSLContext, {@code null} to use for default value
115 */
116 public void setSSLContext(final SSLContext sslContext) {
117 sslContext_ = sslContext;
118 }
119
120 /**
121 * Gets the SSLContext; if this is set this is used and some other settings are
122 * ignored (protocol, keyStore, keyStorePassword, trustStore,
123 * sslClientCertificateStore, sslClientCertificatePassword).
124 * <p>
125 * This property is transient (because SSLContext is not serializable)
126 * </p>
127 *
128 * @return the SSLContext
129 */
130 public SSLContext getSSLContext() {
131 return sslContext_;
132 }
133
134 /**
135 * If set to {@code true}, the client will accept connections to any host,
136 * regardless of whether they have valid certificates or not. This is especially
137 * useful when you are trying to connect to a server with expired or corrupt
138 * certificates.
139 *
140 * @param useInsecureSSL whether or not to use insecure SSL
141 */
142 public void setUseInsecureSSL(final boolean useInsecureSSL) {
143 useInsecureSSL_ = useInsecureSSL;
144 }
145
146 /**
147 * Indicates if insecure SSL should be used.
148 *
149 * @return {@code true} if insecure SSL should be used. Default is
150 * {@code false}.
151 */
152 public boolean isUseInsecureSSL() {
153 return useInsecureSSL_;
154 }
155
156 /**
157 * Sets whether or not redirections will be followed automatically on receipt of
158 * a redirect status code from the server.
159 *
160 * @param enabled true to enable automatic redirection
161 */
162 public void setRedirectEnabled(final boolean enabled) {
163 isRedirectEnabled_ = enabled;
164 }
165
166 /**
167 * Sets the redirect limit for page refresh operations using HTTP refresh
168 * headers or meta tags. This prevents infinite refresh loops by limiting the
169 * number of consecutive refreshes allowed. Set to -1 to allow unlimited
170 * refreshes.
171 *
172 * <p>
173 * Note: The {@link NiceRefreshHandler} and {@link ImmediateRefreshHandler} have
174 * additional loop protection that may trigger before this limit.
175 * </p>
176 *
177 * @param pageRefreshLimit the maximum number of refresh loops, or -1 for
178 * unlimited
179 */
180 public void setPageRefreshLimit(final int pageRefreshLimit) {
181 pageRefreshLimit_ = pageRefreshLimit;
182 }
183
184 /**
185 * Returns the directory to be used for storing the response content in a
186 * temporary file see {@link #getMaxInMemory()}.
187 *
188 * @return the directory to be used for storing temp files or null to use the
189 * system default
190 */
191 public File getTempFileDirectory() {
192 return tempFileDirectory_;
193 }
194
195 /**
196 * Sets the directory to be used for storing response content in temporary
197 * files. See {@link #setMaxInMemory(int)} for when temporary files are created.
198 * If the directory doesn't exist, it will be created automatically.
199 *
200 * @param tempFileDirectory the directory to use, or {@code null} for system
201 * default
202 * @throws IOException if directory creation fails
203 * @throws IllegalArgumentException if the path points to an existing file
204 */
205 public void setTempFileDirectory(final File tempFileDirectory) throws IOException {
206 if (tempFileDirectory != null) {
207 if (tempFileDirectory.exists() && !tempFileDirectory.isDirectory()) {
208 throw new IllegalArgumentException("The provided file '" + tempFileDirectory
209 + "' points to an already existing file");
210 }
211
212 if (!tempFileDirectory.exists()) {
213 FileUtils.forceMkdir(tempFileDirectory);
214 }
215 }
216 tempFileDirectory_ = tempFileDirectory;
217 }
218
219 /**
220 * Returns whether or not redirections will be followed automatically on receipt
221 * of a redirect status code from the server.
222 *
223 * @return true if automatic redirection is enabled
224 */
225 public boolean isRedirectEnabled() {
226 return isRedirectEnabled_;
227 }
228
229 /**
230 * Returns the limit to be used when a page refreshes itself by using a http
231 * refresh header or meta tag. Negative values are interpreted as endless
232 * refresh support.
233 *
234 * @return pageRefreshLimit the number of refresh loops before throwing an
235 * exception
236 */
237 public int getPageRefreshLimit() {
238 return pageRefreshLimit_;
239 }
240
241 /**
242 * Sets the SSL client certificate {@link KeyStore} to use.
243 * <p>
244 * If the web server requires Renegotiation, you have to set system property
245 * "sun.security.ssl.allowUnsafeRenegotiation" to true, as hinted in <a href=
246 * "http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html">
247 * TLS Renegotiation Issue</a>.
248 * </p>
249 * <p>
250 * In some cases the impl seems to pick old certificates from the
251 * {@link KeyStore}. To avoid that, wrap your {@link KeyStore} inside your own
252 * {@link KeyStore} impl and filter out outdated certificates.
253 * </p>
254 * <p>
255 * This property is transient (because KeyStore is not serializable)
256 * </p>
257 *
258 * @param keyStore {@link KeyStore} to use
259 * @param keyStorePassword the keystore password
260 */
261 public void setSSLClientCertificateKeyStore(final KeyStore keyStore, final char[] keyStorePassword) {
262 sslClientCertificateStore_ = keyStore;
263 sslClientCertificatePassword_ = keyStorePassword;
264 }
265
266 /**
267 * Sets the SSL client certificate to use. The needed parameters are used to
268 * construct a {@link java.security.KeyStore}.
269 * <p>
270 * If the web server requires Renegotiation, you have to set system property
271 * "sun.security.ssl.allowUnsafeRenegotiation" to true, as hinted in <a href=
272 * "http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html">
273 * TLS Renegotiation Issue</a>.
274 * </p>
275 * <p>
276 * This property is transient (because KeyStore is not serializable)
277 * </p>
278 *
279 * @param keyStoreUrl the URL which locates the certificate
280 * {@link KeyStore}
281 * @param keyStorePassword the certificate {@link KeyStore} password
282 * @param keyStoreType the type of certificate {@link KeyStore}, usually
283 * {@code jks} or {@code pkcs12}
284 *
285 */
286 public void setSSLClientCertificateKeyStore(final URL keyStoreUrl, final String keyStorePassword,
287 final String keyStoreType) {
288 try (InputStream is = keyStoreUrl.openStream()) {
289 sslClientCertificateStore_ = getKeyStore(is, keyStorePassword, keyStoreType);
290 sslClientCertificatePassword_ = keyStorePassword == null ? null : keyStorePassword.toCharArray();
291 }
292 catch (final Exception e) {
293 throw new RuntimeException(e);
294 }
295 }
296
297 /**
298 * Sets the SSL client certificate {@link KeyStore} to use. The parameters are
299 * used to construct the {@link KeyStore}.
300 * <p>
301 * If the web server requires Renegotiation, you have to set system property
302 * "sun.security.ssl.allowUnsafeRenegotiation" to true, as hinted in <a href=
303 * "http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html">
304 * TLS Renegotiation Issue</a>.
305 * </p>
306 * <p>
307 * In some cases the impl seems to pick old certificates from the
308 * {@link KeyStore}. To avoid that, wrap your {@link KeyStore} inside your own
309 * {@link KeyStore} impl and filter out outdated certificates. Provide the
310 * {@link KeyStore} to the options instead of the input stream.
311 * </p>
312 *
313 * @param keyStoreInputStream the input stream which represents the
314 * {@link KeyStore} holding the certificates
315 * @param keyStorePassword the {@link KeyStore} password
316 * @param keyStoreType the type of {@link KeyStore}, usually {@code jks}
317 * or {@code pkcs12}
318 */
319 public void setSSLClientCertificateKeyStore(final InputStream keyStoreInputStream, final String keyStorePassword,
320 final String keyStoreType) {
321 try {
322 setSSLClientCertificateKeyStore(getKeyStore(keyStoreInputStream, keyStorePassword, keyStoreType),
323 keyStorePassword.toCharArray());
324 }
325 catch (final Exception e) {
326 throw new RuntimeException(e);
327 }
328 }
329
330 /**
331 * Gets the SSLClientCertificateStore.
332 * <p>
333 * This property is transient (because KeyStore is not serializable)
334 * </p>
335 *
336 * @return the KeyStore for use on SSL connections
337 */
338 public KeyStore getSSLClientCertificateStore() {
339 return sslClientCertificateStore_;
340 }
341
342 /**
343 * Gets the SSLClientCertificatePassword.
344 *
345 * @return the password
346 */
347 public char[] getSSLClientCertificatePassword() {
348 return sslClientCertificatePassword_;
349 }
350
351 /**
352 * Gets the protocol versions enabled for use on SSL connections.
353 *
354 * @return the protocol versions enabled for use on SSL connections
355 * @see #setSSLClientProtocols(String...)
356 */
357 public String[] getSSLClientProtocols() {
358 return sslClientProtocols_;
359 }
360
361 /**
362 * Sets the protocol versions enabled for use on SSL connections, {@code null}
363 * to use default ones.
364 *
365 * @param sslClientProtocols the protocol versions
366 * @see javax.net.ssl.SSLSocket#setEnabledProtocols(String[])
367 * @see #getSSLClientProtocols()
368 * @see #setSSLClientCipherSuites(String...)
369 * @see #setUseInsecureSSL(boolean)
370 */
371 public void setSSLClientProtocols(final String... sslClientProtocols) {
372 sslClientProtocols_ = sslClientProtocols;
373 }
374
375 /**
376 * Gets the cipher suites enabled for use on SSL connections.
377 *
378 * @return the cipher suites enabled for use on SSL connections
379 * @see #setSSLClientCipherSuites(String...)
380 */
381 public String[] getSSLClientCipherSuites() {
382 return sslClientCipherSuites_;
383 }
384
385 /**
386 * Sets the cipher suites enabled for use on SSL connections, {@code null} to
387 * use default ones.
388 *
389 * @param sslClientCipherSuites the cipher suites
390 * @see javax.net.ssl.SSLSocket#setEnabledCipherSuites(String[])
391 * @see #getSSLClientCipherSuites()
392 */
393 public void setSSLClientCipherSuites(final String... sslClientCipherSuites) {
394 sslClientCipherSuites_ = sslClientCipherSuites;
395 }
396
397 /**
398 * Enables/disables JavaScript support. By default, this property is enabled.
399 *
400 * @param enabled {@code true} to enable JavaScript support
401 */
402 public void setJavaScriptEnabled(final boolean enabled) {
403 javaScriptEnabled_ = enabled;
404 }
405
406 /**
407 * Returns {@code true} if JavaScript is enabled and the script engine was
408 * loaded successfully.
409 *
410 * @return {@code true} if JavaScript is enabled
411 */
412 public boolean isJavaScriptEnabled() {
413 return javaScriptEnabled_;
414 }
415
416 /**
417 * Enables/disables CSS support. By default, this property is enabled. If
418 * disabled HtmlUnit will not download the linked css files and also not
419 * triggered the associated onload/onerror events.
420 *
421 * @param enabled {@code true} to enable CSS support
422 */
423 public void setCssEnabled(final boolean enabled) {
424 cssEnabled_ = enabled;
425 }
426
427 /**
428 * Returns {@code true} if CSS is enabled.
429 *
430 * @return {@code true} if CSS is enabled
431 */
432 public boolean isCssEnabled() {
433 return cssEnabled_;
434 }
435
436 /**
437 * Enable/disable the popup window blocker. By default, the popup blocker is
438 * disabled, and popup windows are allowed. When set to {@code true},
439 * <code>window.open()</code> has no effect and returns {@code null}.
440 *
441 * @param enabled {@code true} to enable the popup window blocker
442 */
443 public void setPopupBlockerEnabled(final boolean enabled) {
444 popupBlockerEnabled_ = enabled;
445 }
446
447 /**
448 * Returns {@code true} if the popup window blocker is enabled.
449 *
450 * @return {@code true} if the popup window blocker is enabled
451 */
452 public boolean isPopupBlockerEnabled() {
453 return popupBlockerEnabled_;
454 }
455
456 /**
457 * Enables/disables "Do Not Track" support. By default, this property is
458 * disabled.
459 *
460 * @param enabled {@code true} to enable "Do Not Track" support
461 */
462 public void setDoNotTrackEnabled(final boolean enabled) {
463 doNotTrackEnabled_ = enabled;
464 }
465
466 /**
467 * Returns {@code true} if "Do Not Track" is enabled.
468 *
469 * @return {@code true} if "Do Not Track" is enabled
470 */
471 public boolean isDoNotTrackEnabled() {
472 return doNotTrackEnabled_;
473 }
474
475 /**
476 * Specify whether or not the content of the resulting document will be printed
477 * to the console in the event of a failing response code. Successful response
478 * codes are in the range 200-299. The default is true.
479 *
480 * @param enabled True to enable this feature
481 */
482 public void setPrintContentOnFailingStatusCode(final boolean enabled) {
483 printContentOnFailingStatusCode_ = enabled;
484 }
485
486 /**
487 * Returns {@code true} if the content of the resulting document will be printed
488 * to the console in the event of a failing response code.
489 *
490 * @return {@code true} if the content of the resulting document will be printed
491 * to the console in the event of a failing response code
492 * @see #setPrintContentOnFailingStatusCode
493 */
494 public boolean isPrintContentOnFailingStatusCode() {
495 return printContentOnFailingStatusCode_;
496 }
497
498 /**
499 * Specify whether or not an exception will be thrown in the event of a failing
500 * status code. Successful status codes are in the range 200-299. The default is
501 * true.
502 *
503 * @param enabled {@code true} to enable this feature
504 */
505 public void setThrowExceptionOnFailingStatusCode(final boolean enabled) {
506 throwExceptionOnFailingStatusCode_ = enabled;
507 }
508
509 /**
510 * Returns {@code true} if an exception will be thrown in the event of a failing
511 * response code.
512 *
513 * @return {@code true} if an exception will be thrown in the event of a failing
514 * response code
515 * @see #setThrowExceptionOnFailingStatusCode
516 */
517 public boolean isThrowExceptionOnFailingStatusCode() {
518 return throwExceptionOnFailingStatusCode_;
519 }
520
521 /**
522 * Indicates if an exception should be thrown when a script execution fails (the
523 * default) or if it should be caught and just logged to allow page execution to
524 * continue.
525 *
526 * @return {@code true} if an exception is thrown on script error (the default)
527 */
528 public boolean isThrowExceptionOnScriptError() {
529 return throwExceptionOnScriptError_;
530 }
531
532 /**
533 * Changes the behavior of this webclient when a script error occurs.
534 *
535 * @param enabled indicates if exception should be thrown or not
536 */
537 public void setThrowExceptionOnScriptError(final boolean enabled) {
538 throwExceptionOnScriptError_ = enabled;
539 }
540
541 /**
542 * Returns the client's current homepage.
543 *
544 * @return the client's current homepage
545 */
546 public String getHomePage() {
547 return homePage_;
548 }
549
550 /**
551 * Sets the client's homepage.
552 *
553 * @param homePage the new homepage URL
554 */
555 public void setHomePage(final String homePage) {
556 homePage_ = homePage;
557 }
558
559 /**
560 * Returns the proxy configuration for this client.
561 *
562 * @return the proxy configuration for this client
563 */
564 public ProxyConfig getProxyConfig() {
565 return proxyConfig_;
566 }
567
568 /**
569 * Sets the proxy configuration for this client.
570 *
571 * @param proxyConfig the proxy configuration for this client
572 */
573 public void setProxyConfig(final ProxyConfig proxyConfig) {
574 WebAssert.notNull("proxyConfig", proxyConfig);
575 proxyConfig_ = proxyConfig;
576 }
577
578 /**
579 * Gets the timeout value for the {@link WebConnection}. The default timeout is
580 * 90 seconds.
581 *
582 * @return the timeout value in milliseconds
583 * @see #setTimeout(int)
584 * @see #setConnectionTimeToLive(long)
585 */
586 public int getTimeout() {
587 return timeout_;
588 }
589
590 /**
591 * <p>
592 * Sets the timeout of the {@link WebConnection}. Set to zero for an infinite
593 * wait.
594 * </p>
595 *
596 * <p>
597 * Note: The timeout is used twice. The first is for making the socket
598 * connection, the second is for data retrieval. If the time is critical you
599 * must allow for twice the time specified here.
600 * </p>
601 *
602 * @param timeout the value of the timeout in milliseconds
603 */
604 public void setTimeout(final int timeout) {
605 timeout_ = timeout;
606 }
607
608 /**
609 * Gets the connTimeToLive value for the HttpClient connection pool.
610 *
611 * @return the timeout value in milliseconds
612 */
613 public long getConnectionTimeToLive() {
614 return connectionTimeToLive_;
615 }
616
617 /**
618 * Sets the connection time-to-live for the HttpClient connection pool. This is
619 * useful when working with web pages behind DNS-based load balancers where IP
620 * addresses may change frequently.
621 *
622 * @param connectionTimeToLive the timeout in milliseconds, or -1 to disable
623 * (default)
624 */
625 public void setConnectionTimeToLive(final long connectionTimeToLive) {
626 connectionTimeToLive_ = connectionTimeToLive;
627 }
628
629 /**
630 * Sets the SSL protocol, used only when {@link #setUseInsecureSSL(boolean)} is
631 * set to {@code true}.
632 *
633 * @param sslInsecureProtocol the SSL protocol for insecure SSL connections,
634 * {@code null} to use for default value
635 */
636 public void setSSLInsecureProtocol(final String sslInsecureProtocol) {
637 sslInsecureProtocol_ = sslInsecureProtocol;
638 }
639
640 /**
641 * Gets the SSL protocol, to be used only when
642 * {@link #setUseInsecureSSL(boolean)} is set to {@code true}.
643 *
644 * @return the SSL protocol for insecure SSL connections
645 */
646 public String getSSLInsecureProtocol() {
647 return sslInsecureProtocol_;
648 }
649
650 /**
651 * Sets the SSL server certificate trust store. All server certificates will be
652 * validated against this trust store.
653 * <p>
654 * This property is transient (because KeyStore is not serializable)
655 * </p>
656 * <p>
657 * The needed parameters are used to construct a {@link java.security.KeyStore}.
658 * </p>
659 *
660 * @param sslTrustStoreUrl the URL which locates the trust store
661 * @param sslTrustStorePassword the trust store password
662 * @param sslTrustStoreType the type of trust store, usually {@code jks} or
663 * {@code pkcs12}
664 */
665 public void setSSLTrustStore(final URL sslTrustStoreUrl, final String sslTrustStorePassword,
666 final String sslTrustStoreType) {
667 try (InputStream is = sslTrustStoreUrl.openStream()) {
668 sslTrustStore_ = getKeyStore(is, sslTrustStorePassword, sslTrustStoreType);
669 }
670 catch (final Exception e) {
671 throw new RuntimeException(e);
672 }
673 }
674
675 void setSSLTrustStore(final KeyStore keyStore) {
676 sslTrustStore_ = keyStore;
677 }
678
679 /**
680 * Gets the SSL TrustStore.
681 * <p>
682 * This property is transient (because KeyStore is not serializable)
683 * </p>
684 *
685 * @return the SSL TrustStore for insecure SSL connections
686 */
687 public KeyStore getSSLTrustStore() {
688 return sslTrustStore_;
689 }
690
691 private static KeyStore getKeyStore(final InputStream inputStream, final String keystorePassword,
692 final String keystoreType)
693 throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
694 if (inputStream == null) {
695 return null;
696 }
697
698 final KeyStore keyStore = KeyStore.getInstance(keystoreType);
699 final char[] passwordChars = keystorePassword == null ? null : keystorePassword.toCharArray();
700 keyStore.load(inputStream, passwordChars);
701 return keyStore;
702 }
703
704 /**
705 * Returns the maximum bytes stored in memory before content is saved to
706 * temporary files. When response content exceeds this limit, it will be written
707 * to a temporary file in the directory specified by
708 * {@link #getTempFileDirectory()}.
709 *
710 * @return the maximum bytes in memory (default: 500 * 1024)
711 * @see #setMaxInMemory(int)
712 * @see #setTempFileDirectory(File)
713 */
714 public int getMaxInMemory() {
715 return maxInMemory_;
716 }
717
718 /**
719 * Sets the maximum bytes to have in memory, after which the content is saved to
720 * a temporary file. Set this to zero or -1 to deactivate the saving at all.
721 *
722 * @param maxInMemory maximum bytes in memory
723 */
724 public void setMaxInMemory(final int maxInMemory) {
725 maxInMemory_ = maxInMemory;
726 }
727
728 /**
729 * Returns the maximum number of {@link Page pages} kept in
730 * {@link WebWindow#getHistory()}.
731 *
732 * @return the maximum number of pages in history
733 */
734 public int getHistorySizeLimit() {
735 return historySizeLimit_;
736 }
737
738 /**
739 * Sets the History size limit. HtmlUnit uses SoftReferences<Page> for
740 * storing the pages that are part of the history. If you like to fine tune this
741 * you can use {@link #setHistoryPageCacheLimit(int)} to limit the number of
742 * page references stored by the history.
743 *
744 * @param historySizeLimit maximum number of pages in history
745 */
746 public void setHistorySizeLimit(final int historySizeLimit) {
747 historySizeLimit_ = historySizeLimit;
748 }
749
750 /**
751 * Returns the maximum number of {@link Page pages} to cache in history.
752 *
753 * @return the maximum number of pages to cache in history
754 */
755 public int getHistoryPageCacheLimit() {
756 return historyPageCacheLimit_;
757 }
758
759 /**
760 * Sets the maximum number of {@link Page pages} to cache in history. If this
761 * value is smaller than the {{@link #getHistorySizeLimit()} than HtmlUnit will
762 * only use soft references for the first historyPageCacheLimit entries in the
763 * history. For older entries only the url is saved; the page will be
764 * (re)retrieved on demand.
765 *
766 * @param historyPageCacheLimit maximum number of pages to cache in history
767 * default is Integer.MAX_VALUE; negative values
768 * are having the same effect as setting this to
769 * zero.
770 */
771 public void setHistoryPageCacheLimit(final int historyPageCacheLimit) {
772 historyPageCacheLimit_ = historyPageCacheLimit;
773 }
774
775 /**
776 * Returns local address to be used for request execution.
777 * <p>
778 * On machines with multiple network interfaces, this parameter can be used to
779 * select the network interface from which the connection originates.
780 * </p>
781 * <p>
782 * Default: {@code null}
783 * </p>
784 *
785 * @return the local address
786 */
787 public InetAddress getLocalAddress() {
788 return localAddress_;
789 }
790
791 /**
792 * Sets the local network interface address for outgoing HTTP requests. Useful
793 * on multi-homed machines to control which network interface is used.
794 *
795 * @param localAddress the local IP address to bind to, or {@code null} for
796 * automatic selection
797 */
798 public void setLocalAddress(final InetAddress localAddress) {
799 localAddress_ = localAddress;
800 }
801
802 /**
803 * Sets whether to automatically download images by default, or not.
804 *
805 * @param downloadImages whether to automatically download images by default, or
806 * not
807 */
808 public void setDownloadImages(final boolean downloadImages) {
809 downloadImages_ = downloadImages;
810 }
811
812 /**
813 * Returns whether to automatically download images by default, or not.
814 *
815 * @return whether to automatically download images by default, or not.
816 */
817 public boolean isDownloadImages() {
818 return downloadImages_;
819 }
820
821 /**
822 * Sets the screen width. This value is used by JavaScript's screen.width
823 * property.
824 *
825 * @param screenWidth the screen width in pixels (must be positive)
826 */
827 public void setScreenWidth(final int screenWidth) {
828 screenWidth_ = screenWidth;
829 }
830
831 /**
832 * Returns the screen width.
833 *
834 * @return the screen width
835 */
836 public int getScreenWidth() {
837 return screenWidth_;
838 }
839
840 /**
841 * Sets the screen height.
842 *
843 * @param screenHeight the screen height
844 */
845 public void setScreenHeight(final int screenHeight) {
846 screenHeight_ = screenHeight;
847 }
848
849 /**
850 * Returns the screen height.
851 *
852 * @return the screen height
853 */
854 public int getScreenHeight() {
855 return screenHeight_;
856 }
857
858 /**
859 * Returns the Neko HTML parser reader buffer size. This controls the internal
860 * buffer size used by the NekoHTML parser for reading HTML content. Larger
861 * buffers can improve performance for large documents but consume more memory.
862 *
863 * @return the buffer size in bytes, or -1 for parser default
864 */
865 public int getNekoReaderBufferSize() {
866 return nekoReaderBufferSize_;
867 }
868
869 /**
870 * Sets the Neko HTML parser reader buffer size. A larger buffer size can
871 * improve parsing performance for large HTML documents but will consume more
872 * memory. Set to -1 to use the parser's default buffer size.
873 *
874 * @param nekoReaderBufferSize the buffer size in bytes, or -1 for default
875 */
876 public void setNekoReaderBufferSize(final int nekoReaderBufferSize) {
877 nekoReaderBufferSize_ = nekoReaderBufferSize;
878 }
879
880 /**
881 * Enables/disables WebSocket support. By default, this property is enabled.
882 *
883 * @param enabled {@code true} to enable WebSocket support
884 */
885 public void setWebSocketEnabled(final boolean enabled) {
886 webSocketEnabled_ = enabled;
887 }
888
889 /**
890 * Returns {@code true} if WebSockets are enabled.
891 *
892 * @return {@code true} if WebSockets are enabled
893 */
894 public boolean isWebSocketEnabled() {
895 return webSocketEnabled_;
896 }
897
898 /**
899 * Returns the maximum size in bytes for WebSocket text messages. Set to -1 to
900 * use the default.
901 *
902 * @return the maximum text message size in bytes, or -1 for default
903 */
904 public int getWebSocketMaxTextMessageSize() {
905 return webSocketMaxTextMessageSize_;
906 }
907
908 /**
909 * Sets the maximum size in bytes for WebSocket text messages. This limit
910 * applies to individual text frames received by the WebSocket.
911 *
912 * @param webSocketMaxTextMessageSize the maximum size in bytes, or -1 for
913 * default
914 */
915 public void setWebSocketMaxTextMessageSize(final int webSocketMaxTextMessageSize) {
916 webSocketMaxTextMessageSize_ = webSocketMaxTextMessageSize;
917 }
918
919 /**
920 * Returns the maximum size in bytes for WebSocket binary messages. Set to -1 to
921 * use the default.
922 *
923 * @return the maximum binary message size in bytes, or -1 for default
924 */
925 public int getWebSocketMaxBinaryMessageSize() {
926 return webSocketMaxBinaryMessageSize_;
927 }
928
929 /**
930 * Sets the maximum size in bytes for WebSocket binary messages. This limit
931 * applies to individual binary frames received by the WebSocket.
932 *
933 * @param webSocketMaxBinaryMessageSize the maximum size in bytes, or -1 for
934 * default
935 */
936 public void setWebSocketMaxBinaryMessageSize(final int webSocketMaxBinaryMessageSize) {
937 webSocketMaxBinaryMessageSize_ = webSocketMaxBinaryMessageSize;
938 }
939
940 /**
941 * Sets whether or not fetch polyfill should be used.
942 *
943 * @param enabled true to enable fetch polyfill
944 */
945 public void setFetchPolyfillEnabled(final boolean enabled) {
946 isFetchPolyfillEnabled_ = enabled;
947 }
948
949 /**
950 * Returns true if the fetch api polyfill is enabled.
951 *
952 * @return true if the fetch api polyfill is enabled
953 */
954 public boolean isFetchPolyfillEnabled() {
955 return isFetchPolyfillEnabled_;
956 }
957
958 /**
959 * Enables/disables Geolocation support. By default, this property is disabled.
960 *
961 * @param enabled {@code true} to enable Geolocation support
962 */
963 public void setGeolocationEnabled(final boolean enabled) {
964 geolocationEnabled_ = enabled;
965 }
966
967 /**
968 * Returns {@code true} if Geolocation is enabled.
969 *
970 * @return {@code true} if Geolocation is enabled
971 */
972 public boolean isGeolocationEnabled() {
973 return geolocationEnabled_;
974 }
975
976 /**
977 * Returns the {@link Geolocation}.
978 *
979 * @return the {@link Geolocation}
980 */
981 public Geolocation getGeolocation() {
982 return geolocation_;
983 }
984
985 /**
986 * Sets the {@link Geolocation} to be used.
987 *
988 * @param geolocation the new location or null
989 */
990 public void setGeolocation(final Geolocation geolocation) {
991 geolocation_ = geolocation;
992 }
993
994 /**
995 * Support class for Geolocation.
996 */
997 public static class Geolocation implements Serializable {
998 private final double accuracy_;
999 private final double latitude_;
1000 private final double longitude_;
1001 private final Double altitude_;
1002 private final Double altitudeAccuracy_;
1003 private final Double heading_;
1004 private final Double speed_;
1005
1006 /**
1007 * Ctor.
1008 *
1009 * @param latitude the latitude coordinate in decimal degrees
1010 * @param longitude the longitude coordinate in decimal degrees
1011 * @param accuracy the accuracy of the position in meters
1012 * @param altitude the altitude in meters above sea level, or null if
1013 * unavailable
1014 * @param altitudeAccuracy the accuracy of the altitude in meters, or null if
1015 * unavailable
1016 * @param heading the direction of travel in degrees (0-359), or null
1017 * if unavailable
1018 * @param speed the current speed in meters per second, or null if
1019 * unavailable
1020 */
1021 public Geolocation(final double latitude, final double longitude, final double accuracy, final Double altitude,
1022 final Double altitudeAccuracy, final Double heading, final Double speed) {
1023 latitude_ = latitude;
1024 longitude_ = longitude;
1025 accuracy_ = accuracy;
1026 altitude_ = altitude;
1027 altitudeAccuracy_ = altitudeAccuracy;
1028 heading_ = heading;
1029 speed_ = speed;
1030 }
1031
1032 /**
1033 * Returns the accuracy.
1034 *
1035 * @return the accuracy
1036 */
1037 public double getAccuracy() {
1038 return accuracy_;
1039 }
1040
1041 /**
1042 * Returns the latitude.
1043 *
1044 * @return the latitude
1045 */
1046 public double getLatitude() {
1047 return latitude_;
1048 }
1049
1050 /**
1051 * Returns the longitude.
1052 *
1053 * @return the longitude
1054 */
1055 public double getLongitude() {
1056 return longitude_;
1057 }
1058
1059 /**
1060 * Returns the longitude.
1061 *
1062 * @return the longitude
1063 */
1064 public Double getAltitude() {
1065 return altitude_;
1066 }
1067
1068 /**
1069 * Returns the altitudeAccuracy.
1070 *
1071 * @return the altitudeAccuracy
1072 */
1073 public Double getAltitudeAccuracy() {
1074 return altitudeAccuracy_;
1075 }
1076
1077 /**
1078 * Returns the heading.
1079 *
1080 * @return the heading
1081 */
1082 public Double getHeading() {
1083 return heading_;
1084 }
1085
1086 /**
1087 * Returns the speed.
1088 *
1089 * @return the speed
1090 */
1091 public Double getSpeed() {
1092 return speed_;
1093 }
1094 }
1095
1096 /**
1097 * If set to {@code true}, the client will accept XMLHttpRequests to URL's using
1098 * the 'file' protocol. Allowing this introduces security problems and is
1099 * therefore not allowed by current browsers. But some browsers have special
1100 * settings to open this door; therefore we have this option also.
1101 *
1102 * <p>
1103 * <b>Security Warning:</b> Enabling this feature may expose local files to web
1104 * content, which can be a serious security risk.
1105 * </p>
1106 *
1107 * @param fileProtocolForXMLHttpRequestsAllowed whether or not allow (local)
1108 * file access
1109 */
1110 public void setFileProtocolForXMLHttpRequestsAllowed(final boolean fileProtocolForXMLHttpRequestsAllowed) {
1111 fileProtocolForXMLHttpRequestsAllowed_ = fileProtocolForXMLHttpRequestsAllowed;
1112 }
1113
1114 /**
1115 * Indicates if the client will accept XMLHttpRequests to URL's using the 'file'
1116 * protocol.
1117 *
1118 * @return {@code true} if access to local files is allowed.
1119 */
1120 public boolean isFileProtocolForXMLHttpRequestsAllowed() {
1121 return fileProtocolForXMLHttpRequestsAllowed_;
1122 }
1123 }