|
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 send 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}<{@link HttpResponse}>. 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}. The default executor uses a {@linkplain |
|
236 * Executors#newCachedThreadPool(ThreadFactory) cached thread pool}, |
|
237 * with a custom thread factory. |
|
238 * |
|
239 * @implNote If a security manager has been installed, the thread |
|
240 * factory creates threads that run with an access control context that |
|
241 * has no permissions. |
|
242 * |
|
243 * @param executor the Executor |
|
244 * @return this builder |
|
245 */ |
|
246 public Builder executor(Executor executor); |
|
247 |
|
248 /** |
|
249 * Specifies whether requests will automatically follow redirects issued |
|
250 * by the server. |
|
251 * |
|
252 * <p> If this method is not invoked prior to {@linkplain #build() |
|
253 * building}, then newly built clients will use a default redirection |
|
254 * policy of {@link Redirect#NEVER NEVER}. |
|
255 * |
|
256 * @param policy the redirection policy |
|
257 * @return this builder |
|
258 */ |
|
259 public Builder followRedirects(Redirect policy); |
|
260 |
|
261 /** |
|
262 * Requests a specific HTTP protocol version where possible. |
|
263 * |
|
264 * <p> If this method is not invoked prior to {@linkplain #build() |
|
265 * building}, then newly built clients will prefer {@linkplain |
|
266 * Version#HTTP_2 HTTP/2}. |
|
267 * |
|
268 * <p> If set to {@linkplain Version#HTTP_2 HTTP/2}, then each request |
|
269 * will attempt to upgrade to HTTP/2. If the upgrade succeeds, then the |
|
270 * response to this request will use HTTP/2 and all subsequent requests |
|
271 * and responses to the same |
|
272 * <a href="https://tools.ietf.org/html/rfc6454#section-4">origin server</a> |
|
273 * will use HTTP/2. If the upgrade fails, then the response will be |
|
274 * handled using HTTP/1.1 |
|
275 * |
|
276 * @implNote Constraints may also affect the selection of protocol version. |
|
277 * For example, if HTTP/2 is requested through a proxy, and if the implementation |
|
278 * does not support this mode, then HTTP/1.1 may be used |
|
279 * |
|
280 * @param version the requested HTTP protocol version |
|
281 * @return this builder |
|
282 */ |
|
283 public Builder version(HttpClient.Version version); |
|
284 |
|
285 /** |
|
286 * Sets the default priority for any HTTP/2 requests sent from this |
|
287 * client. The value provided must be between {@code 1} and {@code 256} |
|
288 * (inclusive). |
|
289 * |
|
290 * @param priority the priority weighting |
|
291 * @return this builder |
|
292 * @throws IllegalArgumentException if the given priority is out of range |
|
293 */ |
|
294 public Builder priority(int priority); |
|
295 |
|
296 /** |
|
297 * Sets a {@link java.net.ProxySelector}. |
|
298 * |
|
299 * @apiNote {@link ProxySelector#of(InetSocketAddress) ProxySelector::of} |
|
300 * provides a {@code ProxySelector} which uses a single proxy for all |
|
301 * requests. The system-wide proxy selector can be retrieved by |
|
302 * {@link ProxySelector#getDefault()}. |
|
303 * |
|
304 * @implNote |
|
305 * If this method is not invoked prior to {@linkplain #build() building}, |
|
306 * then newly built clients will use the {@linkplain |
|
307 * ProxySelector#getDefault() default proxy selector}, which is usually |
|
308 * adequate for client applications. The default proxy selector supports |
|
309 * a set of system properties</a> related to |
|
310 * <a href="{@docRoot}/java.base/java/net/doc-files/net-properties.html#Proxies"> |
|
311 * proxy settings</a>. This default behavior can be disabled by |
|
312 * supplying an explicit proxy selector, such as {@link #NO_PROXY} or |
|
313 * one returned by {@link ProxySelector#of(InetSocketAddress) |
|
314 * ProxySelector::of}, before {@linkplain #build() building}. |
|
315 * |
|
316 * @param proxySelector the ProxySelector |
|
317 * @return this builder |
|
318 */ |
|
319 public Builder proxy(ProxySelector proxySelector); |
|
320 |
|
321 /** |
|
322 * Sets an authenticator to use for HTTP authentication. |
|
323 * |
|
324 * @param authenticator the Authenticator |
|
325 * @return this builder |
|
326 */ |
|
327 public Builder authenticator(Authenticator authenticator); |
|
328 |
|
329 /** |
|
330 * Returns a new {@link HttpClient} built from the current state of this |
|
331 * builder. |
|
332 * |
|
333 * @return a new {@code HttpClient} |
|
334 */ |
|
335 public HttpClient build(); |
|
336 } |
|
337 |
|
338 |
|
339 /** |
|
340 * Returns an {@code Optional} containing this client's {@link |
|
341 * CookieHandler}. If no {@code CookieHandler} was set in this client's |
|
342 * builder, then the {@code Optional} is empty. |
|
343 * |
|
344 * @return an {@code Optional} containing this client's {@code CookieHandler} |
|
345 */ |
|
346 public abstract Optional<CookieHandler> cookieHandler(); |
|
347 |
|
348 /** |
|
349 * Returns the follow redirects policy for this client. The default value |
|
350 * for client's built by builders that do not specify a redirect policy is |
|
351 * {@link HttpClient.Redirect#NEVER NEVER}. |
|
352 * |
|
353 * @return this client's follow redirects setting |
|
354 */ |
|
355 public abstract Redirect followRedirects(); |
|
356 |
|
357 /** |
|
358 * Returns an {@code Optional} containing the {@code ProxySelector} |
|
359 * supplied to this client. If no proxy selector was set in this client's |
|
360 * builder, then the {@code Optional} is empty. |
|
361 * |
|
362 * <p> Even though this method may return an empty optional, the {@code |
|
363 * HttpClient} may still have a non-exposed {@linkplain |
|
364 * Builder#proxy(ProxySelector) default proxy selector} that is |
|
365 * used for sending HTTP requests. |
|
366 * |
|
367 * @return an {@code Optional} containing the proxy selector supplied |
|
368 * to this client. |
|
369 */ |
|
370 public abstract Optional<ProxySelector> proxy(); |
|
371 |
|
372 /** |
|
373 * Returns this client's {@code SSLContext}. |
|
374 * |
|
375 * <p> If no {@code SSLContext} was set in this client's builder, then the |
|
376 * {@linkplain SSLContext#getDefault() default context} is returned. |
|
377 * |
|
378 * @return this client's SSLContext |
|
379 */ |
|
380 public abstract SSLContext sslContext(); |
|
381 |
|
382 /** |
|
383 * Returns a copy of this client's {@link SSLParameters}. |
|
384 * |
|
385 * <p> If no {@code SSLParameters} were set in the client's builder, then an |
|
386 * implementation specific default set of parameters, that the client will |
|
387 * use, is returned. |
|
388 * |
|
389 * @return this client's {@code SSLParameters} |
|
390 */ |
|
391 public abstract SSLParameters sslParameters(); |
|
392 |
|
393 /** |
|
394 * Returns an {@code Optional} containing the {@link Authenticator} set on |
|
395 * this client. If no {@code Authenticator} was set in the client's builder, |
|
396 * then the {@code Optional} is empty. |
|
397 * |
|
398 * @return an {@code Optional} containing this client's {@code Authenticator} |
|
399 */ |
|
400 public abstract Optional<Authenticator> authenticator(); |
|
401 |
|
402 /** |
|
403 * Returns the preferred HTTP protocol version for this client. The default |
|
404 * value is {@link HttpClient.Version#HTTP_2} |
|
405 * |
|
406 * @implNote Constraints may also affect the selection of protocol version. |
|
407 * For example, if HTTP/2 is requested through a proxy, and if the |
|
408 * implementation does not support this mode, then HTTP/1.1 may be used |
|
409 * |
|
410 * @return the HTTP protocol version requested |
|
411 */ |
|
412 public abstract HttpClient.Version version(); |
|
413 |
|
414 /** |
|
415 * Returns an {@code Optional} containing this client's {@link |
|
416 * Executor}. If no {@code Executor} was set in the client's builder, |
|
417 * then the {@code Optional} is empty. |
|
418 * |
|
419 * <p> Even though this method may return an empty optional, the {@code |
|
420 * HttpClient} may still have an non-exposed {@linkplain |
|
421 * HttpClient.Builder#executor(Executor) default executor} that is used for |
|
422 * executing asynchronous and dependent tasks. |
|
423 * |
|
424 * @return an {@code Optional} containing this client's {@code Executor} |
|
425 */ |
|
426 public abstract Optional<Executor> executor(); |
|
427 |
|
428 /** |
|
429 * The HTTP protocol version. |
|
430 * |
|
431 * @since 11 |
|
432 */ |
|
433 public enum Version { |
|
434 |
|
435 /** |
|
436 * HTTP version 1.1 |
|
437 */ |
|
438 HTTP_1_1, |
|
439 |
|
440 /** |
|
441 * HTTP version 2 |
|
442 */ |
|
443 HTTP_2 |
|
444 } |
|
445 |
|
446 /** |
|
447 * Defines the automatic redirection policy. |
|
448 * |
|
449 * <p> The automatic redirection policy is checked whenever a {@code 3XX} |
|
450 * response code is received. If redirection does not happen automatically, |
|
451 * then the response, containing the {@code 3XX} response code, is returned, |
|
452 * where it can be handled manually. |
|
453 * |
|
454 * <p> {@code Redirect} policy is set via the {@linkplain |
|
455 * HttpClient.Builder#followRedirects(Redirect) Builder.followRedirects} |
|
456 * method. |
|
457 * |
|
458 * @implNote When automatic redirection occurs, the request method of the |
|
459 * redirected request may be modified depending on the specific {@code 30X} |
|
460 * status code, as specified in <a href="https://tools.ietf.org/html/rfc7231"> |
|
461 * RFC 7231</a>. In addition, the {@code 301} and {@code 302} status codes |
|
462 * cause a {@code POST} request to be converted to a {@code GET} in the |
|
463 * redirected request. |
|
464 * |
|
465 * @since 11 |
|
466 */ |
|
467 public enum Redirect { |
|
468 |
|
469 /** |
|
470 * Never redirect. |
|
471 */ |
|
472 NEVER, |
|
473 |
|
474 /** |
|
475 * Always redirect. |
|
476 */ |
|
477 ALWAYS, |
|
478 |
|
479 /** |
|
480 * Always redirect, except from HTTPS URLs to HTTP URLs. |
|
481 */ |
|
482 NORMAL |
|
483 } |
|
484 |
|
485 /** |
|
486 * Sends the given request using this client, blocking if necessary to get |
|
487 * the response. The returned {@link HttpResponse}{@code <T>} contains the |
|
488 * response status, headers, and body ( as handled by given response body |
|
489 * handler ). |
|
490 * |
|
491 * @param <T> the response body type |
|
492 * @param request the request |
|
493 * @param responseBodyHandler the response body handler |
|
494 * @return the response |
|
495 * @throws IOException if an I/O error occurs when sending or receiving |
|
496 * @throws InterruptedException if the operation is interrupted |
|
497 * @throws IllegalArgumentException if the {@code request} argument is not |
|
498 * a request that could have been validly built as specified by {@link |
|
499 * HttpRequest.Builder HttpRequest.Builder}. |
|
500 * @throws SecurityException If a security manager has been installed |
|
501 * and it denies {@link java.net.URLPermission access} to the |
|
502 * URL in the given request, or proxy if one is configured. |
|
503 * See <a href="#securitychecks">security checks</a> for further |
|
504 * information. |
|
505 */ |
|
506 public abstract <T> HttpResponse<T> |
|
507 send(HttpRequest request, HttpResponse.BodyHandler<T> responseBodyHandler) |
|
508 throws IOException, InterruptedException; |
|
509 |
|
510 /** |
|
511 * Sends the given request asynchronously using this client with the given |
|
512 * response body handler. |
|
513 * |
|
514 * <p> Equivalent to: {@code sendAsync(request, responseBodyHandler, null)}. |
|
515 * |
|
516 * @param <T> the response body type |
|
517 * @param request the request |
|
518 * @param responseBodyHandler the response body handler |
|
519 * @return a {@code CompletableFuture<HttpResponse<T>>} |
|
520 * @throws IllegalArgumentException if the {@code request} argument is not |
|
521 * a request that could have been validly built as specified by {@link |
|
522 * HttpRequest.Builder HttpRequest.Builder}. |
|
523 */ |
|
524 public abstract <T> CompletableFuture<HttpResponse<T>> |
|
525 sendAsync(HttpRequest request, |
|
526 BodyHandler<T> responseBodyHandler); |
|
527 |
|
528 /** |
|
529 * Sends the given request asynchronously using this client with the given |
|
530 * response body handler and push promise handler. |
|
531 * |
|
532 * <p> The returned completable future, if completed successfully, completes |
|
533 * with an {@link HttpResponse}{@code <T>} that contains the response status, |
|
534 * headers, and body ( as handled by given response body handler ). |
|
535 * |
|
536 * <p> {@linkplain PushPromiseHandler Push promises} received, if any, are |
|
537 * handled by the given {@code pushPromiseHandler}. A {@code null} valued |
|
538 * {@code pushPromiseHandler} rejects any push promises. |
|
539 * |
|
540 * <p> The returned completable future completes exceptionally with: |
|
541 * <ul> |
|
542 * <li>{@link IOException} - if an I/O error occurs when sending or receiving</li> |
|
543 * <li>{@link SecurityException} - If a security manager has been installed |
|
544 * and it denies {@link java.net.URLPermission access} to the |
|
545 * URL in the given request, or proxy if one is configured. |
|
546 * See <a href="#securitychecks">security checks</a> for further |
|
547 * information.</li> |
|
548 * </ul> |
|
549 * |
|
550 * @param <T> the response body type |
|
551 * @param request the request |
|
552 * @param responseBodyHandler the response body handler |
|
553 * @param pushPromiseHandler push promise handler, may be null |
|
554 * @return a {@code CompletableFuture<HttpResponse<T>>} |
|
555 * @throws IllegalArgumentException if the {@code request} argument is not |
|
556 * a request that could have been validly built as specified by {@link |
|
557 * HttpRequest.Builder HttpRequest.Builder}. |
|
558 */ |
|
559 public abstract <T> CompletableFuture<HttpResponse<T>> |
|
560 sendAsync(HttpRequest request, |
|
561 BodyHandler<T> responseBodyHandler, |
|
562 PushPromiseHandler<T> pushPromiseHandler); |
|
563 |
|
564 /** |
|
565 * Creates a new {@code WebSocket} builder (optional operation). |
|
566 * |
|
567 * <p> <b>Example</b> |
|
568 * <pre>{@code HttpClient client = HttpClient.newHttpClient(); |
|
569 * CompletableFuture<WebSocket> ws = client.newWebSocketBuilder() |
|
570 * .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre> |
|
571 * |
|
572 * <p> Finer control over the WebSocket Opening Handshake can be achieved |
|
573 * by using a custom {@code HttpClient}. |
|
574 * |
|
575 * <p> <b>Example</b> |
|
576 * <pre>{@code InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80); |
|
577 * HttpClient client = HttpClient.newBuilder() |
|
578 * .proxy(ProxySelector.of(addr)) |
|
579 * .build(); |
|
580 * CompletableFuture<WebSocket> ws = client.newWebSocketBuilder() |
|
581 * .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre> |
|
582 * |
|
583 * @implSpec The default implementation of this method throws |
|
584 * {@code UnsupportedOperationException}. Clients obtained through |
|
585 * {@link HttpClient#newHttpClient()} or {@link HttpClient#newBuilder()} |
|
586 * return a {@code WebSocket} builder. |
|
587 * |
|
588 * @implNote Both builder and {@code WebSocket}s created with it operate in |
|
589 * a non-blocking fashion. That is, their methods do not block before |
|
590 * returning a {@code CompletableFuture}. Asynchronous tasks are executed in |
|
591 * this {@code HttpClient}'s executor. |
|
592 * |
|
593 * <p> When a {@code CompletionStage} returned from |
|
594 * {@link WebSocket.Listener#onClose Listener.onClose} completes, |
|
595 * the {@code WebSocket} will send a Close message that has the same code |
|
596 * the received message has and an empty reason. |
|
597 * |
|
598 * @return a {@code WebSocket.Builder} |
|
599 * @throws UnsupportedOperationException |
|
600 * if this {@code HttpClient} does not provide WebSocket support |
|
601 */ |
|
602 public WebSocket.Builder newWebSocketBuilder() { |
|
603 throw new UnsupportedOperationException(); |
|
604 } |
|
605 } |