View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.client.config;
29  
30  import java.net.InetAddress;
31  import java.util.Collection;
32  
33  import org.apache.http.HttpHost;
34  import org.apache.http.annotation.Contract;
35  import org.apache.http.annotation.ThreadingBehavior;
36  
37  /**
38   *  Immutable class encapsulating request configuration items.
39   *  The default setting for stale connection checking changed
40   *  to false, and the feature was deprecated starting with version 4.4.
41   */
42  @Contract(threading = ThreadingBehavior.IMMUTABLE)
43  public class RequestConfig implements Cloneable {
44  
45      public static final RequestConfig DEFAULT = new Builder().build();
46  
47      private final boolean expectContinueEnabled;
48      private final HttpHost proxy;
49      private final InetAddress localAddress;
50      private final boolean staleConnectionCheckEnabled;
51      private final String cookieSpec;
52      private final boolean redirectsEnabled;
53      private final boolean relativeRedirectsAllowed;
54      private final boolean circularRedirectsAllowed;
55      private final int maxRedirects;
56      private final boolean authenticationEnabled;
57      private final Collection<String> targetPreferredAuthSchemes;
58      private final Collection<String> proxyPreferredAuthSchemes;
59      private final int connectionRequestTimeout;
60      private final int connectTimeout;
61      private final int socketTimeout;
62      private final boolean contentCompressionEnabled;
63  
64      /**
65       * Intended for CDI compatibility
66      */
67      protected RequestConfig() {
68          this(false, null, null, false, null, false, false, false, 0, false, null, null, 0, 0, 0, true);
69      }
70  
71      RequestConfig(
72              final boolean expectContinueEnabled,
73              final HttpHost proxy,
74              final InetAddress localAddress,
75              final boolean staleConnectionCheckEnabled,
76              final String cookieSpec,
77              final boolean redirectsEnabled,
78              final boolean relativeRedirectsAllowed,
79              final boolean circularRedirectsAllowed,
80              final int maxRedirects,
81              final boolean authenticationEnabled,
82              final Collection<String> targetPreferredAuthSchemes,
83              final Collection<String> proxyPreferredAuthSchemes,
84              final int connectionRequestTimeout,
85              final int connectTimeout,
86              final int socketTimeout,
87              final boolean contentCompressionEnabled) {
88          super();
89          this.expectContinueEnabled = expectContinueEnabled;
90          this.proxy = proxy;
91          this.localAddress = localAddress;
92          this.staleConnectionCheckEnabled = staleConnectionCheckEnabled;
93          this.cookieSpec = cookieSpec;
94          this.redirectsEnabled = redirectsEnabled;
95          this.relativeRedirectsAllowed = relativeRedirectsAllowed;
96          this.circularRedirectsAllowed = circularRedirectsAllowed;
97          this.maxRedirects = maxRedirects;
98          this.authenticationEnabled = authenticationEnabled;
99          this.targetPreferredAuthSchemes = targetPreferredAuthSchemes;
100         this.proxyPreferredAuthSchemes = proxyPreferredAuthSchemes;
101         this.connectionRequestTimeout = connectionRequestTimeout;
102         this.connectTimeout = connectTimeout;
103         this.socketTimeout = socketTimeout;
104         this.contentCompressionEnabled = contentCompressionEnabled;
105     }
106 
107     /**
108      * Determines whether the 'Expect: 100-Continue' handshake is enabled
109      * for entity enclosing methods. The purpose of the 'Expect: 100-Continue'
110      * handshake is to allow a client that is sending a request message with
111      * a request body to determine if the origin server is willing to
112      * accept the request (based on the request headers) before the client
113      * sends the request body.
114      * <p>
115      * The use of the 'Expect: 100-continue' handshake can result in
116      * a noticeable performance improvement for entity enclosing requests
117      * (such as POST and PUT) that require the target server's
118      * authentication.
119      * </p>
120      * <p>
121      * 'Expect: 100-continue' handshake should be used with caution, as it
122      * may cause problems with HTTP servers and proxies that do not support
123      * HTTP/1.1 protocol.
124      * </p>
125      * <p>
126      * Default: {@code false}
127      * </p>
128      */
129     public boolean isExpectContinueEnabled() {
130         return expectContinueEnabled;
131     }
132 
133     /**
134      * Returns HTTP proxy to be used for request execution.
135      * <p>
136      * Default: {@code null}
137      * </p>
138      */
139     public HttpHost getProxy() {
140         return proxy;
141     }
142 
143     /**
144      * Returns local address to be used for request execution.
145      * <p>
146      * On machines with multiple network interfaces, this parameter
147      * can be used to select the network interface from which the
148      * connection originates.
149      * </p>
150      * <p>
151      * Default: {@code null}
152      * </p>
153      */
154     public InetAddress getLocalAddress() {
155         return localAddress;
156     }
157 
158     /**
159      * Determines whether stale connection check is to be used. The stale
160      * connection check can cause up to 30 millisecond overhead per request and
161      * should be used only when appropriate. For performance critical
162      * operations this check should be disabled.
163      * <p>
164      * Default: {@code false} since 4.4
165      * </p>
166      *
167      * @deprecated (4.4) Use {@link
168      *   org.apache.http.impl.conn.PoolingHttpClientConnectionManager#getValidateAfterInactivity()}
169      */
170     @Deprecated
171     public boolean isStaleConnectionCheckEnabled() {
172         return staleConnectionCheckEnabled;
173     }
174 
175     /**
176      * Determines the name of the cookie specification to be used for HTTP state
177      * management.
178      * <p>
179      * Default: {@code null}
180      * </p>
181      */
182     public String getCookieSpec() {
183         return cookieSpec;
184     }
185 
186     /**
187      * Determines whether redirects should be handled automatically.
188      * <p>
189      * Default: {@code true}
190      * </p>
191      */
192     public boolean isRedirectsEnabled() {
193         return redirectsEnabled;
194     }
195 
196     /**
197      * Determines whether relative redirects should be rejected. HTTP specification
198      * requires the location value be an absolute URI.
199      * <p>
200      * Default: {@code true}
201      * </p>
202      */
203     public boolean isRelativeRedirectsAllowed() {
204         return relativeRedirectsAllowed;
205     }
206 
207     /**
208      * Determines whether circular redirects (redirects to the same location) should
209      * be allowed. The HTTP spec is not sufficiently clear whether circular redirects
210      * are permitted, therefore optionally they can be enabled
211      * <p>
212      * Default: {@code false}
213      * </p>
214      */
215     public boolean isCircularRedirectsAllowed() {
216         return circularRedirectsAllowed;
217     }
218 
219     /**
220      * Returns the maximum number of redirects to be followed. The limit on number
221      * of redirects is intended to prevent infinite loops.
222      * <p>
223      * Default: {@code 50}
224      * </p>
225      */
226     public int getMaxRedirects() {
227         return maxRedirects;
228     }
229 
230     /**
231      * Determines whether authentication should be handled automatically.
232      * <p>
233      * Default: {@code true}
234      * </p>
235      */
236     public boolean isAuthenticationEnabled() {
237         return authenticationEnabled;
238     }
239 
240     /**
241      * Determines the order of preference for supported authentication schemes
242      * when authenticating with the target host.
243      * <p>
244      * Default: {@code null}
245      * </p>
246      */
247     public Collection<String> getTargetPreferredAuthSchemes() {
248         return targetPreferredAuthSchemes;
249     }
250 
251     /**
252      * Determines the order of preference for supported authentication schemes
253      * when authenticating with the proxy host.
254      * <p>
255      * Default: {@code null}
256      * </p>
257      */
258     public Collection<String> getProxyPreferredAuthSchemes() {
259         return proxyPreferredAuthSchemes;
260     }
261 
262     /**
263      * Returns the timeout in milliseconds used when requesting a connection
264      * from the connection manager. A timeout value of zero is interpreted
265      * as an infinite timeout.
266      * <p>
267      * A timeout value of zero is interpreted as an infinite timeout.
268      * A negative value is interpreted as undefined (system default).
269      * </p>
270      * <p>
271      * Default: {@code -1}
272      * </p>
273      */
274     public int getConnectionRequestTimeout() {
275         return connectionRequestTimeout;
276     }
277 
278     /**
279      * Determines the timeout in milliseconds until a connection is established.
280      * A timeout value of zero is interpreted as an infinite timeout.
281      * <p>
282      * A timeout value of zero is interpreted as an infinite timeout.
283      * A negative value is interpreted as undefined (system default).
284      * </p>
285      * <p>
286      * Default: {@code -1}
287      * </p>
288      */
289     public int getConnectTimeout() {
290         return connectTimeout;
291     }
292 
293     /**
294      * Defines the socket timeout ({@code SO_TIMEOUT}) in milliseconds,
295      * which is the timeout for waiting for data  or, put differently,
296      * a maximum period inactivity between two consecutive data packets).
297      * <p>
298      * A timeout value of zero is interpreted as an infinite timeout.
299      * A negative value is interpreted as undefined (system default).
300      * </p>
301      * <p>
302      * Default: {@code -1}
303      * </p>
304      */
305     public int getSocketTimeout() {
306         return socketTimeout;
307     }
308 
309     /**
310      * Determines whether compressed entities should be decompressed automatically.
311      * <p>
312      * Default: {@code true}
313      * </p>
314      *
315      * @since 4.4
316      * @deprecated (4.5) Use {@link #isContentCompressionEnabled()}
317      */
318     @Deprecated
319     public boolean isDecompressionEnabled() {
320         return contentCompressionEnabled;
321     }
322 
323     /**
324      * Determines whether the target server is requested to compress content.
325      * <p>
326      * Default: {@code true}
327      * </p>
328      *
329      * @since 4.5
330      */
331     public boolean isContentCompressionEnabled() {
332         return contentCompressionEnabled;
333     }
334 
335     @Override
336     protected RequestConfig clone() throws CloneNotSupportedException {
337         return (RequestConfig) super.clone();
338     }
339 
340     @Override
341     public String toString() {
342         final StringBuilder builder = new StringBuilder();
343         builder.append("[");
344         builder.append("expectContinueEnabled=").append(expectContinueEnabled);
345         builder.append(", proxy=").append(proxy);
346         builder.append(", localAddress=").append(localAddress);
347         builder.append(", cookieSpec=").append(cookieSpec);
348         builder.append(", redirectsEnabled=").append(redirectsEnabled);
349         builder.append(", relativeRedirectsAllowed=").append(relativeRedirectsAllowed);
350         builder.append(", maxRedirects=").append(maxRedirects);
351         builder.append(", circularRedirectsAllowed=").append(circularRedirectsAllowed);
352         builder.append(", authenticationEnabled=").append(authenticationEnabled);
353         builder.append(", targetPreferredAuthSchemes=").append(targetPreferredAuthSchemes);
354         builder.append(", proxyPreferredAuthSchemes=").append(proxyPreferredAuthSchemes);
355         builder.append(", connectionRequestTimeout=").append(connectionRequestTimeout);
356         builder.append(", connectTimeout=").append(connectTimeout);
357         builder.append(", socketTimeout=").append(socketTimeout);
358         builder.append(", contentCompressionEnabled=").append(contentCompressionEnabled);
359         builder.append("]");
360         return builder.toString();
361     }
362 
363     public static RequestConfig.Builder custom() {
364         return new Builder();
365     }
366 
367     @SuppressWarnings("deprecation")
368     public static RequestConfig.Builder copy(final RequestConfig config) {
369         return new Builder()
370             .setExpectContinueEnabled(config.isExpectContinueEnabled())
371             .setProxy(config.getProxy())
372             .setLocalAddress(config.getLocalAddress())
373             .setStaleConnectionCheckEnabled(config.isStaleConnectionCheckEnabled())
374             .setCookieSpec(config.getCookieSpec())
375             .setRedirectsEnabled(config.isRedirectsEnabled())
376             .setRelativeRedirectsAllowed(config.isRelativeRedirectsAllowed())
377             .setCircularRedirectsAllowed(config.isCircularRedirectsAllowed())
378             .setMaxRedirects(config.getMaxRedirects())
379             .setAuthenticationEnabled(config.isAuthenticationEnabled())
380             .setTargetPreferredAuthSchemes(config.getTargetPreferredAuthSchemes())
381             .setProxyPreferredAuthSchemes(config.getProxyPreferredAuthSchemes())
382             .setConnectionRequestTimeout(config.getConnectionRequestTimeout())
383             .setConnectTimeout(config.getConnectTimeout())
384             .setSocketTimeout(config.getSocketTimeout())
385             .setDecompressionEnabled(config.isDecompressionEnabled())
386             .setContentCompressionEnabled(config.isContentCompressionEnabled());
387     }
388 
389     public static class Builder {
390 
391         private boolean expectContinueEnabled;
392         private HttpHost proxy;
393         private InetAddress localAddress;
394         private boolean staleConnectionCheckEnabled;
395         private String cookieSpec;
396         private boolean redirectsEnabled;
397         private boolean relativeRedirectsAllowed;
398         private boolean circularRedirectsAllowed;
399         private int maxRedirects;
400         private boolean authenticationEnabled;
401         private Collection<String> targetPreferredAuthSchemes;
402         private Collection<String> proxyPreferredAuthSchemes;
403         private int connectionRequestTimeout;
404         private int connectTimeout;
405         private int socketTimeout;
406         private boolean contentCompressionEnabled;
407 
408         Builder() {
409             super();
410             this.staleConnectionCheckEnabled = false;
411             this.redirectsEnabled = true;
412             this.maxRedirects = 50;
413             this.relativeRedirectsAllowed = true;
414             this.authenticationEnabled = true;
415             this.connectionRequestTimeout = -1;
416             this.connectTimeout = -1;
417             this.socketTimeout = -1;
418             this.contentCompressionEnabled = true;
419         }
420 
421         public Builder setExpectContinueEnabled(final boolean expectContinueEnabled) {
422             this.expectContinueEnabled = expectContinueEnabled;
423             return this;
424         }
425 
426         public Builder setProxy(final HttpHost proxy) {
427             this.proxy = proxy;
428             return this;
429         }
430 
431         public Builder setLocalAddress(final InetAddress localAddress) {
432             this.localAddress = localAddress;
433             return this;
434         }
435 
436         /**
437          * @deprecated (4.4) Use {@link
438          *   org.apache.http.impl.conn.PoolingHttpClientConnectionManager#setValidateAfterInactivity(int)}
439          */
440         @Deprecated
441         public Builder setStaleConnectionCheckEnabled(final boolean staleConnectionCheckEnabled) {
442             this.staleConnectionCheckEnabled = staleConnectionCheckEnabled;
443             return this;
444         }
445 
446         public Builder setCookieSpec(final String cookieSpec) {
447             this.cookieSpec = cookieSpec;
448             return this;
449         }
450 
451         public Builder setRedirectsEnabled(final boolean redirectsEnabled) {
452             this.redirectsEnabled = redirectsEnabled;
453             return this;
454         }
455 
456         public Builder setRelativeRedirectsAllowed(final boolean relativeRedirectsAllowed) {
457             this.relativeRedirectsAllowed = relativeRedirectsAllowed;
458             return this;
459         }
460 
461         public Builder setCircularRedirectsAllowed(final boolean circularRedirectsAllowed) {
462             this.circularRedirectsAllowed = circularRedirectsAllowed;
463             return this;
464         }
465 
466         public Builder setMaxRedirects(final int maxRedirects) {
467             this.maxRedirects = maxRedirects;
468             return this;
469         }
470 
471         public Builder setAuthenticationEnabled(final boolean authenticationEnabled) {
472             this.authenticationEnabled = authenticationEnabled;
473             return this;
474         }
475 
476         public Builder setTargetPreferredAuthSchemes(final Collection<String> targetPreferredAuthSchemes) {
477             this.targetPreferredAuthSchemes = targetPreferredAuthSchemes;
478             return this;
479         }
480 
481         public Builder setProxyPreferredAuthSchemes(final Collection<String> proxyPreferredAuthSchemes) {
482             this.proxyPreferredAuthSchemes = proxyPreferredAuthSchemes;
483             return this;
484         }
485 
486         public Builder setConnectionRequestTimeout(final int connectionRequestTimeout) {
487             this.connectionRequestTimeout = connectionRequestTimeout;
488             return this;
489         }
490 
491         public Builder setConnectTimeout(final int connectTimeout) {
492             this.connectTimeout = connectTimeout;
493             return this;
494         }
495 
496         public Builder setSocketTimeout(final int socketTimeout) {
497             this.socketTimeout = socketTimeout;
498             return this;
499         }
500 
501         /**
502          * @deprecated (4.5) Set {@link #setContentCompressionEnabled(boolean)} to {@code false} and
503          * add the {@code Accept-Encoding} request header.
504          */
505         @Deprecated
506         public Builder setDecompressionEnabled(final boolean decompressionEnabled) {
507             this.contentCompressionEnabled = decompressionEnabled;
508             return this;
509         }
510 
511         public Builder setContentCompressionEnabled(final boolean contentCompressionEnabled) {
512             this.contentCompressionEnabled = contentCompressionEnabled;
513             return this;
514         }
515 
516         public RequestConfig build() {
517             return new RequestConfig(
518                     expectContinueEnabled,
519                     proxy,
520                     localAddress,
521                     staleConnectionCheckEnabled,
522                     cookieSpec,
523                     redirectsEnabled,
524                     relativeRedirectsAllowed,
525                     circularRedirectsAllowed,
526                     maxRedirects,
527                     authenticationEnabled,
528                     targetPreferredAuthSchemes,
529                     proxyPreferredAuthSchemes,
530                     connectionRequestTimeout,
531                     connectTimeout,
532                     socketTimeout,
533                     contentCompressionEnabled);
534         }
535 
536     }
537 
538 }