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