HttpClient.java revision 16234:3b25414eb6af
1/* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package jdk.incubator.http; 27 28import java.io.IOException; 29import java.net.Authenticator; 30import java.net.CookieManager; 31import java.net.InetSocketAddress; 32import java.net.ProxySelector; 33import java.net.URI; 34import java.util.Optional; 35import java.util.concurrent.CompletableFuture; 36import java.util.concurrent.Executor; 37import javax.net.ssl.SSLContext; 38import javax.net.ssl.SSLParameters; 39 40/** 41 * A container for configuration information common to multiple {@link 42 * HttpRequest}s. All requests are sent through a {@code HttpClient}. 43 * 44 * <p> {@code HttpClient}s are immutable and created from a builder returned 45 * from {@link HttpClient#newBuilder()}. Request builders are created by calling 46 * {@link HttpRequest#newBuilder() }. 47 * <p> 48 * See {@link HttpRequest} for examples of usage of this API. 49 * 50 * @since 9 51 */ 52public abstract class HttpClient { 53 54 /** 55 * Creates an HttpClient. 56 */ 57 protected HttpClient() {} 58 59 /** 60 * Returns a new HttpClient with default settings. 61 * 62 * @return a new HttpClient 63 */ 64 public static HttpClient newHttpClient() { 65 return new HttpClientBuilderImpl().build(); 66 } 67 68 /** 69 * Creates a new {@code HttpClient} builder. 70 * 71 * @return a {@code HttpClient.Builder} 72 */ 73 public static Builder newBuilder() { 74 return new HttpClientBuilderImpl(); 75 } 76 77 /** 78 * A builder of immutable {@link HttpClient}s. {@code HttpClient.Builder}s 79 * are created by calling {@link HttpClient#newBuilder() } 80 * 81 * <p> Each of the setter methods in this class modifies the state of the 82 * builder and returns <i>this</i> (ie. the same instance). The methods are 83 * not synchronized and should not be called from multiple threads without 84 * external synchronization. 85 * 86 * <p> {@link #build()} returns a new {@code HttpClient} each time it is 87 * called. 88 * 89 * @since 9 90 */ 91 public abstract static class Builder { 92 93 protected Builder() {} 94 95 /** 96 * Sets a cookie manager. 97 * 98 * @param cookieManager the cookie manager 99 * @return this builder 100 */ 101 public abstract Builder cookieManager(CookieManager cookieManager); 102 103 /** 104 * Sets an {@code SSLContext}. If a security manager is set, then the caller 105 * must have the {@link java.net.NetPermission NetPermission} 106 * ({@code "setSSLContext"}) 107 * 108 * <p> The effect of not calling this method, is that a default {@link 109 * javax.net.ssl.SSLContext} is used, which is normally adequate for 110 * client applications that do not need to specify protocols, or require 111 * client authentication. 112 * 113 * @param sslContext the SSLContext 114 * @return this builder 115 * @throws SecurityException if a security manager is set and the 116 * caller does not have any required permission 117 */ 118 public abstract Builder sslContext(SSLContext sslContext); 119 120 /** 121 * Sets an {@code SSLParameters}. If this method is not called, then a default 122 * set of parameters are used. The contents of the given object are 123 * copied. Some parameters which are used internally by the HTTP protocol 124 * implementation (such as application protocol list) should not be set 125 * by callers, as they are ignored. 126 * 127 * @param sslParameters the SSLParameters 128 * @return this builder 129 */ 130 public abstract Builder sslParameters(SSLParameters sslParameters); 131 132 /** 133 * Sets the executor to be used for asynchronous tasks. If this method is 134 * not called, a default executor is set, which is the one returned from {@link 135 * java.util.concurrent.Executors#newCachedThreadPool() 136 * Executors.newCachedThreadPool}. 137 * 138 * @param executor the Executor 139 * @return this builder 140 */ 141 public abstract Builder executor(Executor executor); 142 143 /** 144 * Specifies whether requests will automatically follow redirects issued 145 * by the server. This setting can be overridden on each request. The 146 * default value for this setting is {@link Redirect#NEVER NEVER} 147 * 148 * @param policy the redirection policy 149 * @return this builder 150 */ 151 public abstract Builder followRedirects(Redirect policy); 152 153 /** 154 * Requests a specific HTTP protocol version where possible. If not set, 155 * the version defaults to {@link HttpClient.Version#HTTP_1_1}. If 156 * {@link HttpClient.Version#HTTP_2} is set, then each request will 157 * attempt to upgrade to HTTP/2. If the upgrade succeeds, then the 158 * response to this request will use HTTP/2 and all subsequent requests 159 * and responses to the same 160 * <a href="https://tools.ietf.org/html/rfc6454#section-4">origin server</a> 161 * will use HTTP/2. If the upgrade fails, then the response will be 162 * handled using HTTP/1.1 163 * 164 * @param version the requested HTTP protocol version 165 * @return this builder 166 */ 167 public abstract Builder version(HttpClient.Version version); 168 169 /** 170 * Sets the default priority for any HTTP/2 requests sent from this 171 * client. The value provided must be between {@code 1} and {@code 256} 172 * (inclusive). 173 * 174 * @param priority the priority weighting 175 * @return this builder 176 * @throws IllegalArgumentException if the given priority is out of range 177 */ 178 public abstract Builder priority(int priority); 179 180 /** 181 * Sets a {@link java.net.ProxySelector} for this client. If no selector 182 * is set, then no proxies are used. If a {@code null} parameter is 183 * given then the system wide default proxy selector is used. 184 * 185 * @implNote {@link java.net.ProxySelector#of(InetSocketAddress)} 186 * provides a {@code ProxySelector} which uses one proxy for all requests. 187 * 188 * @param selector the ProxySelector 189 * @return this builder 190 */ 191 public abstract Builder proxy(ProxySelector selector); 192 193 /** 194 * Sets an authenticator to use for HTTP authentication. 195 * 196 * @param a the Authenticator 197 * @return this builder 198 */ 199 public abstract Builder authenticator(Authenticator a); 200 201 /** 202 * Returns a {@link HttpClient} built from the current state of this 203 * builder. 204 * 205 * @return this builder 206 */ 207 public abstract HttpClient build(); 208 } 209 210 211 /** 212 * Returns an {@code Optional} which contains this client's {@link 213 * CookieManager}. If no {@code CookieManager} was set in this client's builder, 214 * then the {@code Optional} is empty. 215 * 216 * @return an {@code Optional} containing this client's {@code CookieManager} 217 */ 218 public abstract Optional<CookieManager> cookieManager(); 219 220 /** 221 * Returns the follow-redirects setting for this client. The default value 222 * for this setting is {@link HttpClient.Redirect#NEVER} 223 * 224 * @return this client's follow redirects setting 225 */ 226 public abstract Redirect followRedirects(); 227 228 /** 229 * Returns an {@code Optional} containing the {@code ProxySelector} for this client. 230 * If no proxy is set then the {@code Optional} is empty. 231 * 232 * @return an {@code Optional} containing this client's proxy selector 233 */ 234 public abstract Optional<ProxySelector> proxy(); 235 236 /** 237 * Returns the {@code SSLContext}, if one was set on this client. If a security 238 * manager is set, then the caller must have the 239 * {@link java.net.NetPermission NetPermission}("getSSLContext") permission. 240 * If no {@code SSLContext} was set, then the default context is returned. 241 * 242 * @return this client's SSLContext 243 * @throws SecurityException if the caller does not have permission to get 244 * the SSLContext 245 */ 246 public abstract SSLContext sslContext(); 247 248 /** 249 * Returns an {@code Optional} containing the {@link SSLParameters} set on 250 * this client. If no {@code SSLParameters} were set in the client's builder, 251 * then the {@code Optional} is empty. 252 * 253 * @return an {@code Optional} containing this client's {@code SSLParameters} 254 */ 255 public abstract Optional<SSLParameters> sslParameters(); 256 257 /** 258 * Returns an {@code Optional} containing the {@link Authenticator} set on 259 * this client. If no {@code Authenticator} was set in the client's builder, 260 * then the {@code Optional} is empty. 261 * 262 * @return an {@code Optional} containing this client's {@code Authenticator} 263 */ 264 public abstract Optional<Authenticator> authenticator(); 265 266 /** 267 * Returns the HTTP protocol version requested for this client. The default 268 * value is {@link HttpClient.Version#HTTP_1_1} 269 * 270 * @return the HTTP protocol version requested 271 */ 272 public abstract HttpClient.Version version(); 273 274 /** 275 * Returns the {@code Executor} set on this client. If an {@code 276 * Executor} was not set on the client's builder, then a default 277 * object is returned. The default {@code Executor} is created independently 278 * for each client. 279 * 280 * @return this client's Executor 281 */ 282 public abstract Executor executor(); 283 284 /** 285 * The HTTP protocol version. 286 * 287 * @since 9 288 */ 289 public enum Version { 290 291 /** 292 * HTTP version 1.1 293 */ 294 HTTP_1_1, 295 296 /** 297 * HTTP version 2 298 */ 299 HTTP_2 300 } 301 302 /** 303 * Defines automatic redirection policy. This is checked whenever a {@code 3XX} 304 * response code is received. If redirection does not happen automatically 305 * then the response is returned to the user, where it can be handled 306 * manually. 307 * 308 * <p> {@code Redirect} policy is set via the {@link 309 * HttpClient.Builder#followRedirects(HttpClient.Redirect)} method. 310 * 311 * @since 9 312 */ 313 public enum Redirect { 314 315 /** 316 * Never redirect. 317 */ 318 NEVER, 319 320 /** 321 * Always redirect. 322 */ 323 ALWAYS, 324 325 /** 326 * Redirect to same protocol only. Redirection may occur from HTTP URLs 327 * to other HTTP URLs, and from HTTPS URLs to other HTTPS URLs. 328 */ 329 SAME_PROTOCOL, 330 331 /** 332 * Redirect always except from HTTPS URLs to HTTP URLs. 333 */ 334 SECURE 335 } 336 337 /** 338 * Sends the given request using this client, blocking if necessary to get 339 * the response. The returned {@link HttpResponse}{@code <T>} contains the 340 * response status, headers, and body ( as handled by given response body 341 * handler ). 342 * 343 * @param <T> the response body type 344 * @param req the request 345 * @param responseBodyHandler the response body handler 346 * @return the response body 347 * @throws java.io.IOException if an I/O error occurs when sending or receiving 348 * @throws java.lang.InterruptedException if the operation is interrupted 349 */ 350 public abstract <T> HttpResponse<T> 351 send(HttpRequest req, HttpResponse.BodyHandler<T> responseBodyHandler) 352 throws IOException, InterruptedException; 353 354 /** 355 * Sends the given request asynchronously using this client and the given 356 * response handler. 357 * 358 * @param <T> the response body type 359 * @param req the request 360 * @param responseBodyHandler the response body handler 361 * @return a {@code CompletableFuture<HttpResponse<T>>} 362 */ 363 public abstract <T> CompletableFuture<HttpResponse<T>> 364 sendAsync(HttpRequest req, HttpResponse.BodyHandler<T> responseBodyHandler); 365 366 /** 367 * Sends the given request asynchronously using this client and the given 368 * multi response handler. 369 * 370 * @param <U> a type representing the aggregated results 371 * @param <T> a type representing all of the response bodies 372 * @param req the request 373 * @param multiProcessor the MultiProcessor for the request 374 * @return a {@code CompletableFuture<U>} 375 */ 376 public abstract <U, T> CompletableFuture<U> 377 sendAsync(HttpRequest req, HttpResponse.MultiProcessor<U, T> multiProcessor); 378 379 /** 380 * Creates a builder of {@link WebSocket} instances connected to the given 381 * URI and receiving events and messages with the given {@code Listener}. 382 * 383 * <p> <b>Example</b> 384 * <pre>{@code 385 * HttpClient client = HttpClient.newHttpClient(); 386 * WebSocket.Builder builder = client.newWebSocketBuilder( 387 * URI.create("ws://websocket.example.com"), 388 * listener); 389 * }</pre> 390 * 391 * <p> Finer control over the WebSocket Opening Handshake can be achieved 392 * by using a custom {@code HttpClient}. 393 * 394 * <p> <b>Example</b> 395 * <pre>{@code 396 * InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80); 397 * HttpClient client = HttpClient.newBuilder() 398 * .proxy(ProxySelector.of(addr)) 399 * .build(); 400 * WebSocket.Builder builder = client.newWebSocketBuilder( 401 * URI.create("ws://websocket.example.com"), 402 * listener); 403 * }</pre> 404 * 405 * @implSpec The default implementation of this method throws {@code 406 * UnsupportedOperationException}. However, clients obtained through 407 * {@link HttpClient#newHttpClient()} or {@link HttpClient#newBuilder()} 408 * provide WebSocket capability. 409 * 410 * @param uri 411 * the WebSocket URI 412 * @param listener 413 * the listener 414 * 415 * @return a builder of {@code WebSocket} instances 416 * @throws UnsupportedOperationException 417 * if this {@code HttpClient} does not provide WebSocket support 418 */ 419 public WebSocket.Builder newWebSocketBuilder(URI uri, 420 WebSocket.Listener listener) 421 { 422 throw new UnsupportedOperationException(); 423 } 424} 425