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