1 /* 2 * Copyright (c) 2015, 2020, 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 26 package java.net.http; 27 28 import java.io.IOException; 29 import java.io.UncheckedIOException; 30 import java.nio.channels.Selector; 31 import java.net.Authenticator; 32 import java.net.CookieHandler; 33 import java.net.InetSocketAddress; 34 import java.net.Proxy; 35 import java.net.ProxySelector; 36 import java.net.URLPermission; 37 import java.security.AccessController; 38 import java.security.PrivilegedAction; 39 import java.time.Duration; 40 import java.util.Optional; 41 import java.util.concurrent.CompletableFuture; 42 import java.util.concurrent.Executor; 43 import javax.net.ssl.SSLContext; 44 import javax.net.ssl.SSLParameters; 45 import java.net.http.HttpResponse.BodyHandler; 46 import java.net.http.HttpResponse.PushPromiseHandler; 47 import jdk.internal.net.http.HttpClientBuilderImpl; 48 49 /** 50 * An HTTP Client. 51 * 52 * <p> An {@code HttpClient} can be used to send {@linkplain HttpRequest 53 * requests} and retrieve their {@linkplain HttpResponse responses}. An {@code 54 * HttpClient} is created through a {@link HttpClient.Builder builder}. 55 * The {@link #newBuilder() newBuilder} method returns a builder that creates 56 * instances of the default {@code HttpClient} implementation. 57 * The builder can be used to configure per-client state, like: the preferred 58 * protocol version ( HTTP/1.1 or HTTP/2 ), whether to follow redirects, a 59 * proxy, an authenticator, etc. Once built, an {@code HttpClient} is immutable, 60 * and can be used to send multiple requests. 61 * 62 * <p> An {@code HttpClient} provides configuration information, and resource 63 * sharing, for all requests sent through it. 64 * 65 * <p> A {@link BodyHandler BodyHandler} must be supplied for each {@link 66 * HttpRequest} sent. The {@code BodyHandler} determines how to handle the 67 * response body, if any. Once an {@link HttpResponse} is received, the 68 * headers, response code, and body (typically) are available. Whether the 69 * response body bytes have been read or not depends on the type, {@code T}, of 70 * the response body. 71 * 72 * <p> Requests can be sent either synchronously or asynchronously: 73 * <ul> 74 * <li>{@link HttpClient#send(HttpRequest, BodyHandler)} blocks 75 * until the request has been sent and the response has been received.</li> 76 * 77 * <li>{@link HttpClient#sendAsync(HttpRequest, BodyHandler)} sends the 78 * request and receives the response asynchronously. The {@code sendAsync} 79 * method returns immediately with a {@link CompletableFuture 80 * CompletableFuture}<{@link HttpResponse}>. The {@code 81 * CompletableFuture} completes when the response becomes available. The 82 * returned {@code CompletableFuture} can be combined in different ways to 83 * declare dependencies among several asynchronous tasks.</li> 84 * </ul> 85 * 86 * <p><b>Synchronous Example</b> 87 * <pre>{@code HttpClient client = HttpClient.newBuilder() 88 * .version(Version.HTTP_1_1) 89 * .followRedirects(Redirect.NORMAL) 90 * .connectTimeout(Duration.ofSeconds(20)) 91 * .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80))) 92 * .authenticator(Authenticator.getDefault()) 93 * .build(); 94 * HttpResponse<String> response = client.send(request, BodyHandlers.ofString()); 95 * System.out.println(response.statusCode()); 96 * System.out.println(response.body()); }</pre> 97 * 98 * <p><b>Asynchronous Example</b> 99 * <pre>{@code HttpRequest request = HttpRequest.newBuilder() 100 * .uri(URI.create("https://foo.com/")) 101 * .timeout(Duration.ofMinutes(2)) 102 * .header("Content-Type", "application/json") 103 * .POST(BodyPublishers.ofFile(Paths.get("file.json"))) 104 * .build(); 105 * client.sendAsync(request, BodyHandlers.ofString()) 106 * .thenApply(HttpResponse::body) 107 * .thenAccept(System.out::println); }</pre> 108 * 109 * <p> <a id="securitychecks"><b>Security checks</b></a> 110 * 111 * <p> If a security manager is present then security checks are performed by 112 * the HTTP Client's sending methods. An appropriate {@link URLPermission} is 113 * required to access the destination server, and proxy server if one has 114 * been configured. The form of the {@code URLPermission} required to access a 115 * proxy has a {@code method} parameter of {@code "CONNECT"} (for all kinds of 116 * proxying) and a {@code URL} string of the form {@code "socket://host:port"} 117 * where host and port specify the proxy's address. 118 * 119 * @implNote If an explicit {@linkplain HttpClient.Builder#executor(Executor) 120 * executor} has not been set for an {@code HttpClient}, and a security manager 121 * has been installed, then the default executor will execute asynchronous and 122 * dependent tasks in a context that is granted no permissions. Custom 123 * {@linkplain HttpRequest.BodyPublisher request body publishers}, {@linkplain 124 * HttpResponse.BodyHandler response body handlers}, {@linkplain 125 * HttpResponse.BodySubscriber response body subscribers}, and {@linkplain 126 * WebSocket.Listener WebSocket Listeners}, if executing operations that require 127 * privileges, should do so within an appropriate {@linkplain 128 * AccessController#doPrivileged(PrivilegedAction) privileged context}. 129 * 130 * @since 11 131 */ 132 public abstract class HttpClient { 133 134 /** 135 * Creates an HttpClient. 136 */ HttpClient()137 protected HttpClient() {} 138 139 /** 140 * Returns a new {@code HttpClient} with default settings. 141 * 142 * <p> Equivalent to {@code newBuilder().build()}. 143 * 144 * <p> The default settings include: the "GET" request method, a preference 145 * of {@linkplain HttpClient.Version#HTTP_2 HTTP/2}, a redirection policy of 146 * {@linkplain Redirect#NEVER NEVER}, the {@linkplain 147 * ProxySelector#getDefault() default proxy selector}, and the {@linkplain 148 * SSLContext#getDefault() default SSL context}. 149 * 150 * @implNote The system-wide default values are retrieved at the time the 151 * {@code HttpClient} instance is constructed. Changing the system-wide 152 * values after an {@code HttpClient} instance has been built, for 153 * instance, by calling {@link ProxySelector#setDefault(ProxySelector)} 154 * or {@link SSLContext#setDefault(SSLContext)}, has no effect on already 155 * built instances. 156 * 157 * @return a new HttpClient 158 * @throws UncheckedIOException if necessary underlying IO resources required to 159 * {@linkplain Builder#build() build a new HttpClient} cannot be allocated. 160 */ newHttpClient()161 public static HttpClient newHttpClient() { 162 return newBuilder().build(); 163 } 164 165 /** 166 * Creates a new {@code HttpClient} builder. 167 * 168 * <p> Builders returned by this method create instances 169 * of the default {@code HttpClient} implementation. 170 * 171 * @return an {@code HttpClient.Builder} 172 */ newBuilder()173 public static Builder newBuilder() { 174 return new HttpClientBuilderImpl(); 175 } 176 177 /** 178 * A builder of {@linkplain HttpClient HTTP Clients}. 179 * 180 * <p> Builders are created by invoking {@link HttpClient#newBuilder() 181 * newBuilder}. Each of the setter methods modifies the state of the builder 182 * and returns the same instance. Builders are not thread-safe and should not be 183 * used concurrently from multiple threads without external synchronization. 184 * 185 * @since 11 186 */ 187 public interface Builder { 188 189 /** 190 * A proxy selector that always return {@link Proxy#NO_PROXY} implying 191 * a direct connection. 192 * 193 * <p> This is a convenience object that can be passed to 194 * {@link #proxy(ProxySelector)} in order to build an instance of 195 * {@link HttpClient} that uses no proxy. 196 */ 197 public static final ProxySelector NO_PROXY = ProxySelector.of(null); 198 199 200 /** 201 * Sets a cookie handler. 202 * 203 * @param cookieHandler the cookie handler 204 * @return this builder 205 */ cookieHandler(CookieHandler cookieHandler)206 public Builder cookieHandler(CookieHandler cookieHandler); 207 208 /** 209 * Sets the connect timeout duration for this client. 210 * 211 * <p> In the case where a new connection needs to be established, if 212 * the connection cannot be established within the given {@code 213 * duration}, then {@link HttpClient#send(HttpRequest,BodyHandler) 214 * HttpClient::send} throws an {@link HttpConnectTimeoutException}, or 215 * {@link HttpClient#sendAsync(HttpRequest,BodyHandler) 216 * HttpClient::sendAsync} completes exceptionally with an 217 * {@code HttpConnectTimeoutException}. If a new connection does not 218 * need to be established, for example if a connection can be reused 219 * from a previous request, then this timeout duration has no effect. 220 * 221 * @param duration the duration to allow the underlying connection to be 222 * established 223 * @return this builder 224 * @throws IllegalArgumentException if the duration is non-positive 225 */ connectTimeout(Duration duration)226 public Builder connectTimeout(Duration duration); 227 228 /** 229 * Sets an {@code SSLContext}. 230 * 231 * <p> If this method is not invoked prior to {@linkplain #build() 232 * building}, then newly built clients will use the {@linkplain 233 * SSLContext#getDefault() default context}, which is normally adequate 234 * for client applications that do not need to specify protocols, or 235 * require client authentication. 236 * 237 * @param sslContext the SSLContext 238 * @return this builder 239 */ sslContext(SSLContext sslContext)240 public Builder sslContext(SSLContext sslContext); 241 242 /** 243 * Sets an {@code SSLParameters}. 244 * 245 * <p> If this method is not invoked prior to {@linkplain #build() 246 * building}, then newly built clients will use a default, 247 * implementation specific, set of parameters. 248 * 249 * <p> Some parameters which are used internally by the HTTP Client 250 * implementation (such as the application protocol list) should not be 251 * set by callers, as they may be ignored. The contents of the given 252 * object are copied. 253 * 254 * @param sslParameters the SSLParameters 255 * @return this builder 256 */ sslParameters(SSLParameters sslParameters)257 public Builder sslParameters(SSLParameters sslParameters); 258 259 /** 260 * Sets the executor to be used for asynchronous and dependent tasks. 261 * 262 * <p> If this method is not invoked prior to {@linkplain #build() 263 * building}, a default executor is created for each newly built {@code 264 * HttpClient}. 265 * 266 * @implNote The default executor uses a thread pool, with a custom 267 * thread factory. If a security manager has been installed, the thread 268 * factory creates threads that run with an access control context that 269 * has no permissions. 270 * 271 * @param executor the Executor 272 * @return this builder 273 */ executor(Executor executor)274 public Builder executor(Executor executor); 275 276 /** 277 * Specifies whether requests will automatically follow redirects issued 278 * by the server. 279 * 280 * <p> If this method is not invoked prior to {@linkplain #build() 281 * building}, then newly built clients will use a default redirection 282 * policy of {@link Redirect#NEVER NEVER}. 283 * 284 * @param policy the redirection policy 285 * @return this builder 286 */ followRedirects(Redirect policy)287 public Builder followRedirects(Redirect policy); 288 289 /** 290 * Requests a specific HTTP protocol version where possible. 291 * 292 * <p> If this method is not invoked prior to {@linkplain #build() 293 * building}, then newly built clients will prefer {@linkplain 294 * Version#HTTP_2 HTTP/2}. 295 * 296 * <p> If set to {@linkplain Version#HTTP_2 HTTP/2}, then each request 297 * will attempt to upgrade to HTTP/2. If the upgrade succeeds, then the 298 * response to this request will use HTTP/2 and all subsequent requests 299 * and responses to the same 300 * <a href="https://tools.ietf.org/html/rfc6454#section-4">origin server</a> 301 * will use HTTP/2. If the upgrade fails, then the response will be 302 * handled using HTTP/1.1 303 * 304 * @implNote Constraints may also affect the selection of protocol version. 305 * For example, if HTTP/2 is requested through a proxy, and if the implementation 306 * does not support this mode, then HTTP/1.1 may be used 307 * 308 * @param version the requested HTTP protocol version 309 * @return this builder 310 */ version(HttpClient.Version version)311 public Builder version(HttpClient.Version version); 312 313 /** 314 * Sets the default priority for any HTTP/2 requests sent from this 315 * client. The value provided must be between {@code 1} and {@code 256} 316 * (inclusive). 317 * 318 * @param priority the priority weighting 319 * @return this builder 320 * @throws IllegalArgumentException if the given priority is out of range 321 */ priority(int priority)322 public Builder priority(int priority); 323 324 /** 325 * Sets a {@link java.net.ProxySelector}. 326 * 327 * @apiNote {@link ProxySelector#of(InetSocketAddress) ProxySelector::of} 328 * provides a {@code ProxySelector} which uses a single proxy for all 329 * requests. The system-wide proxy selector can be retrieved by 330 * {@link ProxySelector#getDefault()}. 331 * 332 * @implNote 333 * If this method is not invoked prior to {@linkplain #build() building}, 334 * then newly built clients will use the {@linkplain 335 * ProxySelector#getDefault() default proxy selector}, which is usually 336 * adequate for client applications. The default proxy selector supports 337 * a set of system properties related to 338 * <a href="{@docRoot}/java.base/java/net/doc-files/net-properties.html#Proxies"> 339 * proxy settings</a>. This default behavior can be disabled by 340 * supplying an explicit proxy selector, such as {@link #NO_PROXY} or 341 * one returned by {@link ProxySelector#of(InetSocketAddress) 342 * ProxySelector::of}, before {@linkplain #build() building}. 343 * 344 * @param proxySelector the ProxySelector 345 * @return this builder 346 */ proxy(ProxySelector proxySelector)347 public Builder proxy(ProxySelector proxySelector); 348 349 /** 350 * Sets an authenticator to use for HTTP authentication. 351 * 352 * @param authenticator the Authenticator 353 * @return this builder 354 */ authenticator(Authenticator authenticator)355 public Builder authenticator(Authenticator authenticator); 356 357 /** 358 * Returns a new {@link HttpClient} built from the current state of this 359 * builder. 360 * 361 * @return a new {@code HttpClient} 362 * 363 * @throws UncheckedIOException may be thrown if underlying IO resources required 364 * by the implementation cannot be allocated. For instance, 365 * if the implementation requires a {@link Selector}, and opening 366 * one fails due to {@linkplain Selector#open() lack of necessary resources}. 367 */ build()368 public HttpClient build(); 369 } 370 371 372 /** 373 * Returns an {@code Optional} containing this client's {@link 374 * CookieHandler}. If no {@code CookieHandler} was set in this client's 375 * builder, then the {@code Optional} is empty. 376 * 377 * @return an {@code Optional} containing this client's {@code CookieHandler} 378 */ cookieHandler()379 public abstract Optional<CookieHandler> cookieHandler(); 380 381 /** 382 * Returns an {@code Optional} containing the <i>connect timeout duration</i> 383 * for this client. If the {@linkplain Builder#connectTimeout(Duration) 384 * connect timeout duration} was not set in the client's builder, then the 385 * {@code Optional} is empty. 386 * 387 * @return an {@code Optional} containing this client's connect timeout 388 * duration 389 */ connectTimeout()390 public abstract Optional<Duration> connectTimeout(); 391 392 /** 393 * Returns the follow redirects policy for this client. The default value 394 * for client's built by builders that do not specify a redirect policy is 395 * {@link HttpClient.Redirect#NEVER NEVER}. 396 * 397 * @return this client's follow redirects setting 398 */ followRedirects()399 public abstract Redirect followRedirects(); 400 401 /** 402 * Returns an {@code Optional} containing the {@code ProxySelector} 403 * supplied to this client. If no proxy selector was set in this client's 404 * builder, then the {@code Optional} is empty. 405 * 406 * <p> Even though this method may return an empty optional, the {@code 407 * HttpClient} may still have a non-exposed {@linkplain 408 * Builder#proxy(ProxySelector) default proxy selector} that is 409 * used for sending HTTP requests. 410 * 411 * @return an {@code Optional} containing the proxy selector supplied 412 * to this client. 413 */ proxy()414 public abstract Optional<ProxySelector> proxy(); 415 416 /** 417 * Returns this client's {@code SSLContext}. 418 * 419 * <p> If no {@code SSLContext} was set in this client's builder, then the 420 * {@linkplain SSLContext#getDefault() default context} is returned. 421 * 422 * @return this client's SSLContext 423 */ sslContext()424 public abstract SSLContext sslContext(); 425 426 /** 427 * Returns a copy of this client's {@link SSLParameters}. 428 * 429 * <p> If no {@code SSLParameters} were set in the client's builder, then an 430 * implementation specific default set of parameters, that the client will 431 * use, is returned. 432 * 433 * @return this client's {@code SSLParameters} 434 */ sslParameters()435 public abstract SSLParameters sslParameters(); 436 437 /** 438 * Returns an {@code Optional} containing the {@link Authenticator} set on 439 * this client. If no {@code Authenticator} was set in the client's builder, 440 * then the {@code Optional} is empty. 441 * 442 * @return an {@code Optional} containing this client's {@code Authenticator} 443 */ authenticator()444 public abstract Optional<Authenticator> authenticator(); 445 446 /** 447 * Returns the preferred HTTP protocol version for this client. The default 448 * value is {@link HttpClient.Version#HTTP_2} 449 * 450 * @implNote Constraints may also affect the selection of protocol version. 451 * For example, if HTTP/2 is requested through a proxy, and if the 452 * implementation does not support this mode, then HTTP/1.1 may be used 453 * 454 * @return the HTTP protocol version requested 455 */ version()456 public abstract HttpClient.Version version(); 457 458 /** 459 * Returns an {@code Optional} containing this client's {@link 460 * Executor}. If no {@code Executor} was set in the client's builder, 461 * then the {@code Optional} is empty. 462 * 463 * <p> Even though this method may return an empty optional, the {@code 464 * HttpClient} may still have an non-exposed {@linkplain 465 * HttpClient.Builder#executor(Executor) default executor} that is used for 466 * executing asynchronous and dependent tasks. 467 * 468 * @return an {@code Optional} containing this client's {@code Executor} 469 */ executor()470 public abstract Optional<Executor> executor(); 471 472 /** 473 * The HTTP protocol version. 474 * 475 * @since 11 476 */ 477 public enum Version { 478 479 /** 480 * HTTP version 1.1 481 */ 482 HTTP_1_1, 483 484 /** 485 * HTTP version 2 486 */ 487 HTTP_2 488 } 489 490 /** 491 * Defines the automatic redirection policy. 492 * 493 * <p> The automatic redirection policy is checked whenever a {@code 3XX} 494 * response code is received. If redirection does not happen automatically, 495 * then the response, containing the {@code 3XX} response code, is returned, 496 * where it can be handled manually. 497 * 498 * <p> {@code Redirect} policy is set through the {@linkplain 499 * HttpClient.Builder#followRedirects(Redirect) Builder.followRedirects} 500 * method. 501 * 502 * @implNote When automatic redirection occurs, the request method of the 503 * redirected request may be modified depending on the specific {@code 30X} 504 * status code, as specified in <a href="https://tools.ietf.org/html/rfc7231"> 505 * RFC 7231</a>. In addition, the {@code 301} and {@code 302} status codes 506 * cause a {@code POST} request to be converted to a {@code GET} in the 507 * redirected request. 508 * 509 * @since 11 510 */ 511 public enum Redirect { 512 513 /** 514 * Never redirect. 515 */ 516 NEVER, 517 518 /** 519 * Always redirect. 520 */ 521 ALWAYS, 522 523 /** 524 * Always redirect, except from HTTPS URLs to HTTP URLs. 525 */ 526 NORMAL 527 } 528 529 /** 530 * Sends the given request using this client, blocking if necessary to get 531 * the response. The returned {@link HttpResponse}{@code <T>} contains the 532 * response status, headers, and body ( as handled by given response body 533 * handler ). 534 * 535 * <p> If the operation is interrupted, the default {@code HttpClient} 536 * implementation attempts to cancel the HTTP exchange and 537 * {@link InterruptedException} is thrown. 538 * No guarantee is made as to exactly <em>when</em> the cancellation request 539 * may be taken into account. In particular, the request might still get sent 540 * to the server, as its processing might already have started asynchronously 541 * in another thread, and the underlying resources may only be released 542 * asynchronously. 543 * <ul> 544 * <li>With HTTP/1.1, an attempt to cancel may cause the underlying 545 * connection to be closed abruptly. 546 * <li>With HTTP/2, an attempt to cancel may cause the stream to be reset, 547 * or in certain circumstances, may also cause the connection to be 548 * closed abruptly, if, for instance, the thread is currently trying 549 * to write to the underlying socket. 550 * </ul> 551 * 552 * @param <T> the response body type 553 * @param request the request 554 * @param responseBodyHandler the response body handler 555 * @return the response 556 * @throws IOException if an I/O error occurs when sending or receiving 557 * @throws InterruptedException if the operation is interrupted 558 * @throws IllegalArgumentException if the {@code request} argument is not 559 * a request that could have been validly built as specified by {@link 560 * HttpRequest.Builder HttpRequest.Builder}. 561 * @throws SecurityException If a security manager has been installed 562 * and it denies {@link java.net.URLPermission access} to the 563 * URL in the given request, or proxy if one is configured. 564 * See <a href="#securitychecks">security checks</a> for further 565 * information. 566 */ 567 public abstract <T> HttpResponse<T> send(HttpRequest request, HttpResponse.BodyHandler<T> responseBodyHandler)568 send(HttpRequest request, HttpResponse.BodyHandler<T> responseBodyHandler) 569 throws IOException, InterruptedException; 570 571 /** 572 * Sends the given request asynchronously using this client with the given 573 * response body handler. 574 * 575 * <p> Equivalent to: {@code sendAsync(request, responseBodyHandler, null)}. 576 * 577 * @param <T> the response body type 578 * @param request the request 579 * @param responseBodyHandler the response body handler 580 * @return a {@code CompletableFuture<HttpResponse<T>>} 581 * @throws IllegalArgumentException if the {@code request} argument is not 582 * a request that could have been validly built as specified by {@link 583 * HttpRequest.Builder HttpRequest.Builder}. 584 */ 585 public abstract <T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request, BodyHandler<T> responseBodyHandler)586 sendAsync(HttpRequest request, 587 BodyHandler<T> responseBodyHandler); 588 589 /** 590 * Sends the given request asynchronously using this client with the given 591 * response body handler and push promise handler. 592 * 593 * <p> The returned completable future, if completed successfully, completes 594 * with an {@link HttpResponse}{@code <T>} that contains the response status, 595 * headers, and body ( as handled by given response body handler ). 596 * 597 * <p> {@linkplain PushPromiseHandler Push promises} received, if any, are 598 * handled by the given {@code pushPromiseHandler}. A {@code null} valued 599 * {@code pushPromiseHandler} rejects any push promises. 600 * 601 * <p> The returned completable future completes exceptionally with: 602 * <ul> 603 * <li>{@link IOException} - if an I/O error occurs when sending or receiving</li> 604 * <li>{@link SecurityException} - If a security manager has been installed 605 * and it denies {@link java.net.URLPermission access} to the 606 * URL in the given request, or proxy if one is configured. 607 * See <a href="#securitychecks">security checks</a> for further 608 * information.</li> 609 * </ul> 610 * 611 * <p> The default {@code HttpClient} implementation returns 612 * {@code CompletableFuture} objects that are <em>cancelable</em>. 613 * {@code CompletableFuture} objects {@linkplain CompletableFuture#newIncompleteFuture() 614 * derived} from cancelable futures are themselves <em>cancelable</em>. 615 * Invoking {@linkplain CompletableFuture#cancel(boolean) cancel(true)} 616 * on a cancelable future that is not completed, attempts to cancel the HTTP exchange 617 * in an effort to release underlying resources as soon as possible. 618 * No guarantee is made as to exactly <em>when</em> the cancellation request 619 * may be taken into account. In particular, the request might still get sent 620 * to the server, as its processing might already have started asynchronously 621 * in another thread, and the underlying resources may only be released 622 * asynchronously. 623 * <ul> 624 * <li>With HTTP/1.1, an attempt to cancel may cause the underlying connection 625 * to be closed abruptly. 626 * <li>With HTTP/2, an attempt to cancel may cause the stream to be reset. 627 * </ul> 628 * 629 * @param <T> the response body type 630 * @param request the request 631 * @param responseBodyHandler the response body handler 632 * @param pushPromiseHandler push promise handler, may be null 633 * @return a {@code CompletableFuture<HttpResponse<T>>} 634 * @throws IllegalArgumentException if the {@code request} argument is not 635 * a request that could have been validly built as specified by {@link 636 * HttpRequest.Builder HttpRequest.Builder}. 637 */ 638 public abstract <T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request, BodyHandler<T> responseBodyHandler, PushPromiseHandler<T> pushPromiseHandler)639 sendAsync(HttpRequest request, 640 BodyHandler<T> responseBodyHandler, 641 PushPromiseHandler<T> pushPromiseHandler); 642 643 /** 644 * Creates a new {@code WebSocket} builder (optional operation). 645 * 646 * <p> <b>Example</b> 647 * <pre>{@code HttpClient client = HttpClient.newHttpClient(); 648 * CompletableFuture<WebSocket> ws = client.newWebSocketBuilder() 649 * .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre> 650 * 651 * <p> Finer control over the WebSocket Opening Handshake can be achieved 652 * by using a custom {@code HttpClient}. 653 * 654 * <p> <b>Example</b> 655 * <pre>{@code InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80); 656 * HttpClient client = HttpClient.newBuilder() 657 * .proxy(ProxySelector.of(addr)) 658 * .build(); 659 * CompletableFuture<WebSocket> ws = client.newWebSocketBuilder() 660 * .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre> 661 * 662 * @implSpec The default implementation of this method throws 663 * {@code UnsupportedOperationException}. Clients obtained through 664 * {@link HttpClient#newHttpClient()} or {@link HttpClient#newBuilder()} 665 * return a {@code WebSocket} builder. 666 * 667 * @implNote Both builder and {@code WebSocket}s created with it operate in 668 * a non-blocking fashion. That is, their methods do not block before 669 * returning a {@code CompletableFuture}. Asynchronous tasks are executed in 670 * this {@code HttpClient}'s executor. 671 * 672 * <p> When a {@code CompletionStage} returned from 673 * {@link WebSocket.Listener#onClose Listener.onClose} completes, 674 * the {@code WebSocket} will send a Close message that has the same code 675 * the received message has and an empty reason. 676 * 677 * @return a {@code WebSocket.Builder} 678 * @throws UnsupportedOperationException 679 * if this {@code HttpClient} does not provide WebSocket support 680 */ newWebSocketBuilder()681 public WebSocket.Builder newWebSocketBuilder() { 682 throw new UnsupportedOperationException(); 683 } 684 } 685