--- old/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClient.java 2017-11-30 04:03:57.177894844 -0800 +++ new/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClient.java 2017-11-30 04:03:56.982877795 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,13 +27,16 @@ import java.io.IOException; import java.net.Authenticator; -import java.net.CookieManager; +import java.net.CookieHandler; import java.net.InetSocketAddress; +import java.net.Proxy; import java.net.ProxySelector; import java.net.URI; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; @@ -60,10 +63,25 @@ /** * Returns a new HttpClient with default settings. * + *
Equivalent to {@code newBuilder().build()}. + * + *
The default settings include: the "GET" request method, a preference + * of {@linkplain HttpClient.Version#HTTP_2 HTTP/2}, a redirection policy of + * {@linkplain Redirect#NEVER NEVER}, the {@linkplain + * ProxySelector#getDefault() default proxy selector}, and the {@linkplain + * SSLContext#getDefault() default SSL context}. + * + * @implNote The system-wide default values are retrieved at the time the + * {@code HttpClient} instance is constructed. Changing the system-wide + * values after an {@code HttpClient} instance has been built, for + * instance, by calling {@link ProxySelector#setDefault(ProxySelector)} + * or {@link SSLContext#setDefault(SSLContext)}, has no effect on already + * built instances. + * * @return a new HttpClient */ public static HttpClient newHttpClient() { - return new HttpClientBuilderImpl().build(); + return newBuilder().build(); } /** @@ -76,55 +94,65 @@ } /** - * A builder of immutable {@link HttpClient}s. {@code HttpClient.Builder}s - * are created by calling {@link HttpClient#newBuilder()}. + * A builder of immutable {@link HttpClient}s. * {@Incubating} * - *
Each of the setter methods in this class modifies the state of the - * builder and returns this (ie. the same instance). The methods are - * not synchronized and should not be called from multiple threads without - * external synchronization. - * - *
{@link #build()} returns a new {@code HttpClient} each time it is - * called. + *
Builders are created by invoking {@linkplain HttpClient#newBuilder() + * newBuilder}. Each of the setter methods modifies the state of the builder + * and returns the same instance. Builders are not thread-safe and should not be + * used concurrently from multiple threads without external synchronization. * * @since 9 */ public abstract static class Builder { + /** + * A proxy selector that always return {@link Proxy#NO_PROXY} implying + * a direct connection. + * This is a convenience object that can be passed to {@link #proxy(ProxySelector)} + * in order to build an instance of {@link HttpClient} that uses no + * proxy. + */ + public static final ProxySelector NO_PROXY = ProxySelector.of(null); + + /** + * Creates a Builder. + */ protected Builder() {} /** - * Sets a cookie manager. + * Sets a cookie handler. * - * @param cookieManager the cookie manager + * @param cookieHandler the cookie handler * @return this builder */ - public abstract Builder cookieManager(CookieManager cookieManager); + public abstract Builder cookieHandler(CookieHandler cookieHandler); /** - * Sets an {@code SSLContext}. If a security manager is set, then the caller - * must have the {@link java.net.NetPermission NetPermission} - * ({@code "setSSLContext"}) + * Sets an {@code SSLContext}. * - *
The effect of not calling this method, is that a default {@link - * javax.net.ssl.SSLContext} is used, which is normally adequate for - * client applications that do not need to specify protocols, or require - * client authentication. + *
If this method is not invoked prior to {@linkplain #build() + * building}, then newly built clients will use the {@linkplain + * SSLContext#getDefault() default context}, which is normally adequate + * for client applications that do not need to specify protocols, or + * require client authentication. * * @param sslContext the SSLContext * @return this builder - * @throws SecurityException if a security manager is set and the - * caller does not have any required permission */ public abstract Builder sslContext(SSLContext sslContext); /** - * Sets an {@code SSLParameters}. If this method is not called, then a default - * set of parameters are used. The contents of the given object are - * copied. Some parameters which are used internally by the HTTP protocol - * implementation (such as application protocol list) should not be set - * by callers, as they are ignored. + * Sets an {@code SSLParameters}. + * + *
If this method is not invoked prior to {@linkplain #build() + * building}, then newly built clients will use a default, + * implementation specific, set of parameters. + * + *
Some parameters which are used internally by the HTTP Client + * implementation (such as the application protocol list) should not be + * set by callers, as they may be ignored. The contents of the given + * object are copied. * * @param sslParameters the SSLParameters * @return this builder @@ -132,10 +160,17 @@ public abstract Builder sslParameters(SSLParameters sslParameters); /** - * Sets the executor to be used for asynchronous tasks. If this method is - * not called, a default executor is set, which is the one returned from {@link - * java.util.concurrent.Executors#newCachedThreadPool() - * Executors.newCachedThreadPool}. + * Sets the executor to be used for asynchronous and dependent tasks. + * + *
If this method is not invoked prior to {@linkplain #build() + * building}, a default executor is created for each newly built {@code + * HttpClient}. The default executor uses a {@linkplain + * Executors#newCachedThreadPool(ThreadFactory) cached thread pool}, + * with a custom thread factory. + * + * @implNote If a security manager has been installed, the thread + * factory creates threads that run with an access control context that + * has no permissions. * * @param executor the Executor * @return this builder @@ -144,8 +179,11 @@ /** * Specifies whether requests will automatically follow redirects issued - * by the server. This setting can be overridden on each request. The - * default value for this setting is {@link Redirect#NEVER NEVER} + * by the server. + * + *
If this method is not invoked prior to {@linkplain #build() + * building}, then newly built clients will use a default redirection + * policy of {@link Redirect#NEVER NEVER}. * * @param policy the redirection policy * @return this builder @@ -153,10 +191,14 @@ public abstract Builder followRedirects(Redirect policy); /** - * Requests a specific HTTP protocol version where possible. If not set, - * the version defaults to {@link HttpClient.Version#HTTP_2}. If - * {@link HttpClient.Version#HTTP_2} is set, then each request will - * attempt to upgrade to HTTP/2. If the upgrade succeeds, then the + * Requests a specific HTTP protocol version where possible. + * + *
If this method is not invoked prior to {@linkplain #build() + * building}, then newly built clients will prefer {@linkplain + * Version#HTTP_2 HTTP/2}. + * + *
If set to {@linkplain Version#HTTP_2 HTTP/2}, then each request
+ * will attempt to upgrade to HTTP/2. If the upgrade succeeds, then the
* response to this request will use HTTP/2 and all subsequent requests
* and responses to the same
* origin server
@@ -180,12 +222,22 @@
public abstract Builder priority(int priority);
/**
- * Sets a {@link java.net.ProxySelector} for this client. If no selector
- * is set, then no proxies are used. If a {@code null} parameter is
- * given then the system wide default proxy selector is used.
+ * Sets a {@link java.net.ProxySelector}.
*
- * @implNote {@link java.net.ProxySelector#of(InetSocketAddress)}
- * provides a {@code ProxySelector} which uses one proxy for all requests.
+ * @apiNote {@link ProxySelector#of(InetSocketAddress)}
+ * provides a {@code ProxySelector} which uses a single proxy for all
+ * requests. The system-wide proxy selector can be retrieved by
+ * {@link ProxySelector#getDefault()}.
+ *
+ * @implNote
+ * If this method is not invoked prior to {@linkplain #build()
+ * building}, then newly built clients will use the {@linkplain
+ * ProxySelector#getDefault() default proxy selector}, which
+ * is normally adequate for client applications. This default
+ * behavior can be turned off by supplying an explicit proxy
+ * selector to this method, such as {@link #NO_PROXY} or one
+ * returned by {@link ProxySelector#of(InetSocketAddress)},
+ * before calling {@link #build()}.
*
* @param selector the ProxySelector
* @return this builder
@@ -201,7 +253,7 @@
public abstract Builder authenticator(Authenticator a);
/**
- * Returns a {@link HttpClient} built from the current state of this
+ * Returns a new {@link HttpClient} built from the current state of this
* builder.
*
* @return this builder
@@ -211,50 +263,58 @@
/**
- * Returns an {@code Optional} which contains this client's {@link
- * CookieManager}. If no {@code CookieManager} was set in this client's builder,
- * then the {@code Optional} is empty.
+ * Returns an {@code Optional} containing this client's {@linkplain
+ * CookieHandler}. If no {@code CookieHandler} was set in this client's
+ * builder, then the {@code Optional} is empty.
*
- * @return an {@code Optional} containing this client's {@code CookieManager}
+ * @return an {@code Optional} containing this client's {@code CookieHandler}
*/
- public abstract Optional Even though this method may return an empty optional, the {@code
+ * HttpClient} may still have an non-exposed {@linkplain
+ * Builder#proxy(ProxySelector) default proxy selector} that is
+ * used for sending HTTP requests.
*
- * @return an {@code Optional} containing this client's proxy selector
+ * @return an {@code Optional} containing the proxy selector supplied
+ * to this client.
*/
public abstract Optional If no {@code SSLContext} was set in this client's builder, then the
+ * {@linkplain SSLContext#getDefault() default context} is returned.
*
* @return this client's SSLContext
- * @throws SecurityException if the caller does not have permission to get
- * the SSLContext
*/
public abstract SSLContext sslContext();
/**
- * Returns an {@code Optional} containing the {@link SSLParameters} set on
- * this client. If no {@code SSLParameters} were set in the client's builder,
- * then the {@code Optional} is empty.
+ * Returns a copy of this client's {@link SSLParameters}.
+ *
+ * If no {@code SSLParameters} were set in the client's builder, then an
+ * implementation specific default set of parameters, that the client will
+ * use, is returned.
*
- * @return an {@code Optional} containing this client's {@code SSLParameters}
+ * @return this client's {@code SSLParameters}
*/
- public abstract Optional Even though this method may return an empty optional, the {@code
+ * HttpClient} may still have an non-exposed {@linkplain
+ * HttpClient.Builder#executor(Executor) default executor} that is used for
+ * executing asynchronous and dependent tasks.
*
- * @return this client's Executor
+ * @return an {@code Optional} containing this client's {@code Executor}
*/
- public abstract Executor executor();
+ public abstract Optional The returned completable future completes exceptionally with:
+ * The returned completable future completes exceptionally with:
+ * Example
* Finer control over the WebSocket Opening Handshake can be achieved
@@ -402,28 +492,33 @@
* HttpClient client = HttpClient.newBuilder()
* .proxy(ProxySelector.of(addr))
* .build();
- * WebSocket.Builder builder = client.newWebSocketBuilder(
- * URI.create("ws://websocket.example.com"),
- * listener);
+ * CompletableFuture A {@code WebSocket.Builder} returned from this method is not safe for
+ * use by multiple threads without external synchronization.
+ *
+ * @implSpec The default implementation of this method throws
+ * {@code UnsupportedOperationException}. Clients obtained through
* {@link HttpClient#newHttpClient()} or {@link HttpClient#newBuilder()}
- * provide WebSocket capability.
+ * return a {@code WebSocket} builder.
*
- * @param uri
- * the WebSocket URI
- * @param listener
- * the listener
+ * @implNote Both builder and {@code WebSocket}s created with it operate in
+ * a non-blocking fashion. That is, their methods do not block before
+ * returning a {@code CompletableFuture}. Asynchronous tasks are executed in
+ * this {@code HttpClient}'s executor.
+ *
+ * When a {@code CompletionStage} returned from
+ * {@link WebSocket.Listener#onClose Listener.onClose} completes,
+ * the {@code WebSocket} will send a Close message that has the same code
+ * the received message has and an empty reason.
*
- * @return a builder of {@code WebSocket} instances
+ * @return a {@code WebSocket.Builder}
* @throws UnsupportedOperationException
* if this {@code HttpClient} does not provide WebSocket support
*/
- public WebSocket.Builder newWebSocketBuilder(URI uri,
- WebSocket.Listener listener)
- {
+ public WebSocket.Builder newWebSocketBuilder() {
throw new UnsupportedOperationException();
}
}
+ *
+ *
* @param
+ *
+ *
* @param a type representing the aggregated results
* @param {@code
* HttpClient client = HttpClient.newHttpClient();
- * WebSocket.Builder builder = client.newWebSocketBuilder(
- * URI.create("ws://websocket.example.com"),
- * listener);
+ * CompletableFuture
*
*