001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027 028package org.apache.http.client.config; 029 030import java.net.InetAddress; 031import java.util.Collection; 032 033import org.apache.http.HttpHost; 034import org.apache.http.annotation.Contract; 035import org.apache.http.annotation.ThreadingBehavior; 036 037/** 038 * Immutable class encapsulating request configuration items. 039 * The default setting for stale connection checking changed 040 * to false, and the feature was deprecated starting with version 4.4. 041 */ 042@Contract(threading = ThreadingBehavior.IMMUTABLE) 043public class RequestConfig implements Cloneable { 044 045 public static final RequestConfig DEFAULT = new Builder().build(); 046 047 private final boolean expectContinueEnabled; 048 private final HttpHost proxy; 049 private final InetAddress localAddress; 050 private final boolean staleConnectionCheckEnabled; 051 private final String cookieSpec; 052 private final boolean redirectsEnabled; 053 private final boolean relativeRedirectsAllowed; 054 private final boolean circularRedirectsAllowed; 055 private final int maxRedirects; 056 private final boolean authenticationEnabled; 057 private final Collection<String> targetPreferredAuthSchemes; 058 private final Collection<String> proxyPreferredAuthSchemes; 059 private final int connectionRequestTimeout; 060 private final int connectTimeout; 061 private final int socketTimeout; 062 private final boolean contentCompressionEnabled; 063 064 /** 065 * Intended for CDI compatibility 066 */ 067 protected RequestConfig() { 068 this(false, null, null, false, null, false, false, false, 0, false, null, null, 0, 0, 0, true); 069 } 070 071 RequestConfig( 072 final boolean expectContinueEnabled, 073 final HttpHost proxy, 074 final InetAddress localAddress, 075 final boolean staleConnectionCheckEnabled, 076 final String cookieSpec, 077 final boolean redirectsEnabled, 078 final boolean relativeRedirectsAllowed, 079 final boolean circularRedirectsAllowed, 080 final int maxRedirects, 081 final boolean authenticationEnabled, 082 final Collection<String> targetPreferredAuthSchemes, 083 final Collection<String> proxyPreferredAuthSchemes, 084 final int connectionRequestTimeout, 085 final int connectTimeout, 086 final int socketTimeout, 087 final boolean contentCompressionEnabled) { 088 super(); 089 this.expectContinueEnabled = expectContinueEnabled; 090 this.proxy = proxy; 091 this.localAddress = localAddress; 092 this.staleConnectionCheckEnabled = staleConnectionCheckEnabled; 093 this.cookieSpec = cookieSpec; 094 this.redirectsEnabled = redirectsEnabled; 095 this.relativeRedirectsAllowed = relativeRedirectsAllowed; 096 this.circularRedirectsAllowed = circularRedirectsAllowed; 097 this.maxRedirects = maxRedirects; 098 this.authenticationEnabled = authenticationEnabled; 099 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}