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