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.
268      * <p>
269      * A timeout value of zero is interpreted as an infinite timeout.
270      * A negative value is interpreted as undefined (system default if applicable).
271      * </p>
272      * <p>
273      * Default: {@code -1}
274      * </p>
275      */
276     public int getConnectionRequestTimeout() {
277         return connectionRequestTimeout;
278     }
279 
280     /**
281      * Determines the timeout in milliseconds until a connection is established.
282      * <p>
283      * A timeout value of zero is interpreted as an infinite timeout.
284      * A negative value is interpreted as undefined (system default if applicable).
285      * </p>
286      * <p>
287      * Default: {@code -1}
288      * </p>
289      */
290     public int getConnectTimeout() {
291         return connectTimeout;
292     }
293 
294     /**
295      * Defines the socket timeout ({@code SO_TIMEOUT}) in milliseconds,
296      * which is the timeout for waiting for data or, put differently,
297      * a maximum period inactivity between two consecutive data packets).
298      * <p>
299      * A timeout value of zero is interpreted as an infinite timeout.
300      * A negative value is interpreted as undefined (system default if applicable).
301      * </p>
302      * <p>
303      * Default: {@code -1}
304      * </p>
305      */
306     public int getSocketTimeout() {
307         return socketTimeout;
308     }
309 
310     /**
311      * Determines whether compressed entities should be decompressed automatically.
312      * <p>
313      * Default: {@code true}
314      * </p>
315      *
316      * @since 4.4
317      * @deprecated (4.5) Use {@link #isContentCompressionEnabled()}
318      */
319     @Deprecated
320     public boolean isDecompressionEnabled() {
321         return contentCompressionEnabled;
322     }
323 
324     /**
325      * Determines whether the target server is requested to compress content.
326      * <p>
327      * Default: {@code true}
328      * </p>
329      *
330      * @since 4.5
331      */
332     public boolean isContentCompressionEnabled() {
333         return contentCompressionEnabled;
334     }
335 
336     /**
337      * Determines whether client should normalize URIs in requests or not.
338      * <p>
339      * Default: {@code true}
340      * </p>
341      *
342      * @since 4.5.8
343      */
344     public boolean isNormalizeUri() {
345         return normalizeUri;
346     }
347 
348     @Override
349     protected RequestConfig clone() throws CloneNotSupportedException {
350         return (RequestConfig) super.clone();
351     }
352 
353     @Override
354     public String toString() {
355         final StringBuilder builder = new StringBuilder();
356         builder.append("[");
357         builder.append("expectContinueEnabled=").append(expectContinueEnabled);
358         builder.append(", proxy=").append(proxy);
359         builder.append(", localAddress=").append(localAddress);
360         builder.append(", cookieSpec=").append(cookieSpec);
361         builder.append(", redirectsEnabled=").append(redirectsEnabled);
362         builder.append(", relativeRedirectsAllowed=").append(relativeRedirectsAllowed);
363         builder.append(", maxRedirects=").append(maxRedirects);
364         builder.append(", circularRedirectsAllowed=").append(circularRedirectsAllowed);
365         builder.append(", authenticationEnabled=").append(authenticationEnabled);
366         builder.append(", targetPreferredAuthSchemes=").append(targetPreferredAuthSchemes);
367         builder.append(", proxyPreferredAuthSchemes=").append(proxyPreferredAuthSchemes);
368         builder.append(", connectionRequestTimeout=").append(connectionRequestTimeout);
369         builder.append(", connectTimeout=").append(connectTimeout);
370         builder.append(", socketTimeout=").append(socketTimeout);
371         builder.append(", contentCompressionEnabled=").append(contentCompressionEnabled);
372         builder.append(", normalizeUri=").append(normalizeUri);
373         builder.append("]");
374         return builder.toString();
375     }
376 
377     public static RequestConfig.Builder custom() {
378         return new Builder();
379     }
380 
381     @SuppressWarnings("deprecation")
382     public static RequestConfig.Builder copy(final RequestConfig config) {
383         return new Builder()
384             .setExpectContinueEnabled(config.isExpectContinueEnabled())
385             .setProxy(config.getProxy())
386             .setLocalAddress(config.getLocalAddress())
387             .setStaleConnectionCheckEnabled(config.isStaleConnectionCheckEnabled())
388             .setCookieSpec(config.getCookieSpec())
389             .setRedirectsEnabled(config.isRedirectsEnabled())
390             .setRelativeRedirectsAllowed(config.isRelativeRedirectsAllowed())
391             .setCircularRedirectsAllowed(config.isCircularRedirectsAllowed())
392             .setMaxRedirects(config.getMaxRedirects())
393             .setAuthenticationEnabled(config.isAuthenticationEnabled())
394             .setTargetPreferredAuthSchemes(config.getTargetPreferredAuthSchemes())
395             .setProxyPreferredAuthSchemes(config.getProxyPreferredAuthSchemes())
396             .setConnectionRequestTimeout(config.getConnectionRequestTimeout())
397             .setConnectTimeout(config.getConnectTimeout())
398             .setSocketTimeout(config.getSocketTimeout())
399             .setDecompressionEnabled(config.isDecompressionEnabled())
400             .setContentCompressionEnabled(config.isContentCompressionEnabled())
401             .setNormalizeUri(config.isNormalizeUri());
402     }
403 
404     public static class Builder {
405 
406         private boolean expectContinueEnabled;
407         private HttpHost proxy;
408         private InetAddress localAddress;
409         private boolean staleConnectionCheckEnabled;
410         private String cookieSpec;
411         private boolean redirectsEnabled;
412         private boolean relativeRedirectsAllowed;
413         private boolean circularRedirectsAllowed;
414         private int maxRedirects;
415         private boolean authenticationEnabled;
416         private Collection<String> targetPreferredAuthSchemes;
417         private Collection<String> proxyPreferredAuthSchemes;
418         private int connectionRequestTimeout;
419         private int connectTimeout;
420         private int socketTimeout;
421         private boolean contentCompressionEnabled;
422         private boolean normalizeUri;
423 
424         Builder() {
425             super();
426             this.staleConnectionCheckEnabled = false;
427             this.redirectsEnabled = true;
428             this.maxRedirects = 50;
429             this.relativeRedirectsAllowed = true;
430             this.authenticationEnabled = true;
431             this.connectionRequestTimeout = -1;
432             this.connectTimeout = -1;
433             this.socketTimeout = -1;
434             this.contentCompressionEnabled = true;
435             this.normalizeUri = true;
436         }
437 
438         public Builder setExpectContinueEnabled(final boolean expectContinueEnabled) {
439             this.expectContinueEnabled = expectContinueEnabled;
440             return this;
441         }
442 
443         public Builder setProxy(final HttpHost proxy) {
444             this.proxy = proxy;
445             return this;
446         }
447 
448         public Builder setLocalAddress(final InetAddress localAddress) {
449             this.localAddress = localAddress;
450             return this;
451         }
452 
453         /**
454          * @deprecated (4.4) Use {@link
455          *   org.apache.http.impl.conn.PoolingHttpClientConnectionManager#setValidateAfterInactivity(int)}
456          */
457         @Deprecated
458         public Builder setStaleConnectionCheckEnabled(final boolean staleConnectionCheckEnabled) {
459             this.staleConnectionCheckEnabled = staleConnectionCheckEnabled;
460             return this;
461         }
462 
463         public Builder setCookieSpec(final String cookieSpec) {
464             this.cookieSpec = cookieSpec;
465             return this;
466         }
467 
468         public Builder setRedirectsEnabled(final boolean redirectsEnabled) {
469             this.redirectsEnabled = redirectsEnabled;
470             return this;
471         }
472 
473         public Builder setRelativeRedirectsAllowed(final boolean relativeRedirectsAllowed) {
474             this.relativeRedirectsAllowed = relativeRedirectsAllowed;
475             return this;
476         }
477 
478         public Builder setCircularRedirectsAllowed(final boolean circularRedirectsAllowed) {
479             this.circularRedirectsAllowed = circularRedirectsAllowed;
480             return this;
481         }
482 
483         public Builder setMaxRedirects(final int maxRedirects) {
484             this.maxRedirects = maxRedirects;
485             return this;
486         }
487 
488         public Builder setAuthenticationEnabled(final boolean authenticationEnabled) {
489             this.authenticationEnabled = authenticationEnabled;
490             return this;
491         }
492 
493         public Builder setTargetPreferredAuthSchemes(final Collection<String> targetPreferredAuthSchemes) {
494             this.targetPreferredAuthSchemes = targetPreferredAuthSchemes;
495             return this;
496         }
497 
498         public Builder setProxyPreferredAuthSchemes(final Collection<String> proxyPreferredAuthSchemes) {
499             this.proxyPreferredAuthSchemes = proxyPreferredAuthSchemes;
500             return this;
501         }
502 
503         public Builder setConnectionRequestTimeout(final int connectionRequestTimeout) {
504             this.connectionRequestTimeout = connectionRequestTimeout;
505             return this;
506         }
507 
508         public Builder setConnectTimeout(final int connectTimeout) {
509             this.connectTimeout = connectTimeout;
510             return this;
511         }
512 
513         public Builder setSocketTimeout(final int socketTimeout) {
514             this.socketTimeout = socketTimeout;
515             return this;
516         }
517 
518         /**
519          * @deprecated (4.5) Set {@link #setContentCompressionEnabled(boolean)} to {@code false} and
520          * add the {@code Accept-Encoding} request header.
521          */
522         @Deprecated
523         public Builder setDecompressionEnabled(final boolean decompressionEnabled) {
524             this.contentCompressionEnabled = decompressionEnabled;
525             return this;
526         }
527 
528         public Builder setContentCompressionEnabled(final boolean contentCompressionEnabled) {
529             this.contentCompressionEnabled = contentCompressionEnabled;
530             return this;
531         }
532 
533         public Builder setNormalizeUri(final boolean normalizeUri) {
534             this.normalizeUri = normalizeUri;
535             return this;
536         }
537 
538         public RequestConfig build() {
539             return new RequestConfig(
540                     expectContinueEnabled,
541                     proxy,
542                     localAddress,
543                     staleConnectionCheckEnabled,
544                     cookieSpec,
545                     redirectsEnabled,
546                     relativeRedirectsAllowed,
547                     circularRedirectsAllowed,
548                     maxRedirects,
549                     authenticationEnabled,
550                     targetPreferredAuthSchemes,
551                     proxyPreferredAuthSchemes,
552                     connectionRequestTimeout,
553                     connectTimeout,
554                     socketTimeout,
555                     contentCompressionEnabled,
556                     normalizeUri);
557         }
558 
559     }
560 
561 }