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