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