Path: blob/master/src/java.net.http/share/classes/java/net/http/HttpClient.java
41159 views
/*1* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.net.http;2627import java.io.IOException;28import java.io.UncheckedIOException;29import java.nio.channels.Selector;30import java.net.Authenticator;31import java.net.CookieHandler;32import java.net.InetSocketAddress;33import java.net.Proxy;34import java.net.ProxySelector;35import java.net.URLPermission;36import java.security.AccessController;37import java.security.PrivilegedAction;38import java.time.Duration;39import java.util.Optional;40import java.util.concurrent.CompletableFuture;41import java.util.concurrent.Executor;42import javax.net.ssl.SSLContext;43import javax.net.ssl.SSLParameters;44import java.net.http.HttpResponse.BodyHandler;45import java.net.http.HttpResponse.PushPromiseHandler;46import jdk.internal.net.http.HttpClientBuilderImpl;4748/**49* An HTTP Client.50*51* <p> An {@code HttpClient} can be used to send {@linkplain HttpRequest52* requests} and retrieve their {@linkplain HttpResponse responses}. An {@code53* HttpClient} is created through a {@link HttpClient.Builder builder}.54* The {@link #newBuilder() newBuilder} method returns a builder that creates55* instances of the default {@code HttpClient} implementation.56* The builder can be used to configure per-client state, like: the preferred57* protocol version ( HTTP/1.1 or HTTP/2 ), whether to follow redirects, a58* proxy, an authenticator, etc. Once built, an {@code HttpClient} is immutable,59* and can be used to send multiple requests.60*61* <p> An {@code HttpClient} provides configuration information, and resource62* sharing, for all requests sent through it.63*64* <p> A {@link BodyHandler BodyHandler} must be supplied for each {@link65* HttpRequest} sent. The {@code BodyHandler} determines how to handle the66* response body, if any. Once an {@link HttpResponse} is received, the67* headers, response code, and body (typically) are available. Whether the68* response body bytes have been read or not depends on the type, {@code T}, of69* the response body.70*71* <p> Requests can be sent either synchronously or asynchronously:72* <ul>73* <li>{@link HttpClient#send(HttpRequest, BodyHandler)} blocks74* until the request has been sent and the response has been received.</li>75*76* <li>{@link HttpClient#sendAsync(HttpRequest, BodyHandler)} sends the77* request and receives the response asynchronously. The {@code sendAsync}78* method returns immediately with a {@link CompletableFuture79* CompletableFuture}<{@link HttpResponse}>. The {@code80* CompletableFuture} completes when the response becomes available. The81* returned {@code CompletableFuture} can be combined in different ways to82* declare dependencies among several asynchronous tasks.</li>83* </ul>84*85* <p><b>Synchronous Example</b>86* <pre>{@code HttpClient client = HttpClient.newBuilder()87* .version(Version.HTTP_1_1)88* .followRedirects(Redirect.NORMAL)89* .connectTimeout(Duration.ofSeconds(20))90* .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))91* .authenticator(Authenticator.getDefault())92* .build();93* HttpResponse<String> response = client.send(request, BodyHandlers.ofString());94* System.out.println(response.statusCode());95* System.out.println(response.body()); }</pre>96*97* <p><b>Asynchronous Example</b>98* <pre>{@code HttpRequest request = HttpRequest.newBuilder()99* .uri(URI.create("https://foo.com/"))100* .timeout(Duration.ofMinutes(2))101* .header("Content-Type", "application/json")102* .POST(BodyPublishers.ofFile(Paths.get("file.json")))103* .build();104* client.sendAsync(request, BodyHandlers.ofString())105* .thenApply(HttpResponse::body)106* .thenAccept(System.out::println); }</pre>107*108* <p> <a id="securitychecks"><b>Security checks</b></a>109*110* <p> If a security manager is present then security checks are performed by111* the HTTP Client's sending methods. An appropriate {@link URLPermission} is112* required to access the destination server, and proxy server if one has113* been configured. The form of the {@code URLPermission} required to access a114* proxy has a {@code method} parameter of {@code "CONNECT"} (for all kinds of115* proxying) and a {@code URL} string of the form {@code "socket://host:port"}116* where host and port specify the proxy's address.117*118* @implNote If an explicit {@linkplain HttpClient.Builder#executor(Executor)119* executor} has not been set for an {@code HttpClient}, and a security manager120* has been installed, then the default executor will execute asynchronous and121* dependent tasks in a context that is granted no permissions. Custom122* {@linkplain HttpRequest.BodyPublisher request body publishers}, {@linkplain123* HttpResponse.BodyHandler response body handlers}, {@linkplain124* HttpResponse.BodySubscriber response body subscribers}, and {@linkplain125* WebSocket.Listener WebSocket Listeners}, if executing operations that require126* privileges, should do so within an appropriate {@linkplain127* AccessController#doPrivileged(PrivilegedAction) privileged context}.128*129* @since 11130*/131public abstract class HttpClient {132133/**134* Creates an HttpClient.135*/136protected HttpClient() {}137138/**139* Returns a new {@code HttpClient} with default settings.140*141* <p> Equivalent to {@code newBuilder().build()}.142*143* <p> The default settings include: the "GET" request method, a preference144* of {@linkplain HttpClient.Version#HTTP_2 HTTP/2}, a redirection policy of145* {@linkplain Redirect#NEVER NEVER}, the {@linkplain146* ProxySelector#getDefault() default proxy selector}, and the {@linkplain147* SSLContext#getDefault() default SSL context}.148*149* @implNote The system-wide default values are retrieved at the time the150* {@code HttpClient} instance is constructed. Changing the system-wide151* values after an {@code HttpClient} instance has been built, for152* instance, by calling {@link ProxySelector#setDefault(ProxySelector)}153* or {@link SSLContext#setDefault(SSLContext)}, has no effect on already154* built instances.155*156* @return a new HttpClient157* @throws UncheckedIOException if necessary underlying IO resources required to158* {@linkplain Builder#build() build a new HttpClient} cannot be allocated.159*/160public static HttpClient newHttpClient() {161return newBuilder().build();162}163164/**165* Creates a new {@code HttpClient} builder.166*167* <p> Builders returned by this method create instances168* of the default {@code HttpClient} implementation.169*170* @return an {@code HttpClient.Builder}171*/172public static Builder newBuilder() {173return new HttpClientBuilderImpl();174}175176/**177* A builder of {@linkplain HttpClient HTTP Clients}.178*179* <p> Builders are created by invoking {@link HttpClient#newBuilder()180* newBuilder}. Each of the setter methods modifies the state of the builder181* and returns the same instance. Builders are not thread-safe and should not be182* used concurrently from multiple threads without external synchronization.183*184* @since 11185*/186public interface Builder {187188/**189* A proxy selector that always return {@link Proxy#NO_PROXY} implying190* a direct connection.191*192* <p> This is a convenience object that can be passed to193* {@link #proxy(ProxySelector)} in order to build an instance of194* {@link HttpClient} that uses no proxy.195*/196public static final ProxySelector NO_PROXY = ProxySelector.of(null);197198199/**200* Sets a cookie handler.201*202* @param cookieHandler the cookie handler203* @return this builder204*/205public Builder cookieHandler(CookieHandler cookieHandler);206207/**208* Sets the connect timeout duration for this client.209*210* <p> In the case where a new connection needs to be established, if211* the connection cannot be established within the given {@code212* duration}, then {@link HttpClient#send(HttpRequest,BodyHandler)213* HttpClient::send} throws an {@link HttpConnectTimeoutException}, or214* {@link HttpClient#sendAsync(HttpRequest,BodyHandler)215* HttpClient::sendAsync} completes exceptionally with an216* {@code HttpConnectTimeoutException}. If a new connection does not217* need to be established, for example if a connection can be reused218* from a previous request, then this timeout duration has no effect.219*220* @param duration the duration to allow the underlying connection to be221* established222* @return this builder223* @throws IllegalArgumentException if the duration is non-positive224*/225public Builder connectTimeout(Duration duration);226227/**228* Sets an {@code SSLContext}.229*230* <p> If this method is not invoked prior to {@linkplain #build()231* building}, then newly built clients will use the {@linkplain232* SSLContext#getDefault() default context}, which is normally adequate233* for client applications that do not need to specify protocols, or234* require client authentication.235*236* @param sslContext the SSLContext237* @return this builder238*/239public Builder sslContext(SSLContext sslContext);240241/**242* Sets an {@code SSLParameters}.243*244* <p> If this method is not invoked prior to {@linkplain #build()245* building}, then newly built clients will use a default,246* implementation specific, set of parameters.247*248* <p> Some parameters which are used internally by the HTTP Client249* implementation (such as the application protocol list) should not be250* set by callers, as they may be ignored. The contents of the given251* object are copied.252*253* @param sslParameters the SSLParameters254* @return this builder255*/256public Builder sslParameters(SSLParameters sslParameters);257258/**259* Sets the executor to be used for asynchronous and dependent tasks.260*261* <p> If this method is not invoked prior to {@linkplain #build()262* building}, a default executor is created for each newly built {@code263* HttpClient}.264*265* @implNote The default executor uses a thread pool, with a custom266* thread factory. If a security manager has been installed, the thread267* factory creates threads that run with an access control context that268* has no permissions.269*270* @param executor the Executor271* @return this builder272*/273public Builder executor(Executor executor);274275/**276* Specifies whether requests will automatically follow redirects issued277* by the server.278*279* <p> If this method is not invoked prior to {@linkplain #build()280* building}, then newly built clients will use a default redirection281* policy of {@link Redirect#NEVER NEVER}.282*283* @param policy the redirection policy284* @return this builder285*/286public Builder followRedirects(Redirect policy);287288/**289* Requests a specific HTTP protocol version where possible.290*291* <p> If this method is not invoked prior to {@linkplain #build()292* building}, then newly built clients will prefer {@linkplain293* Version#HTTP_2 HTTP/2}.294*295* <p> If set to {@linkplain Version#HTTP_2 HTTP/2}, then each request296* will attempt to upgrade to HTTP/2. If the upgrade succeeds, then the297* response to this request will use HTTP/2 and all subsequent requests298* and responses to the same299* <a href="https://tools.ietf.org/html/rfc6454#section-4">origin server</a>300* will use HTTP/2. If the upgrade fails, then the response will be301* handled using HTTP/1.1302*303* @implNote Constraints may also affect the selection of protocol version.304* For example, if HTTP/2 is requested through a proxy, and if the implementation305* does not support this mode, then HTTP/1.1 may be used306*307* @param version the requested HTTP protocol version308* @return this builder309*/310public Builder version(HttpClient.Version version);311312/**313* Sets the default priority for any HTTP/2 requests sent from this314* client. The value provided must be between {@code 1} and {@code 256}315* (inclusive).316*317* @param priority the priority weighting318* @return this builder319* @throws IllegalArgumentException if the given priority is out of range320*/321public Builder priority(int priority);322323/**324* Sets a {@link java.net.ProxySelector}.325*326* @apiNote {@link ProxySelector#of(InetSocketAddress) ProxySelector::of}327* provides a {@code ProxySelector} which uses a single proxy for all328* requests. The system-wide proxy selector can be retrieved by329* {@link ProxySelector#getDefault()}.330*331* @implNote332* If this method is not invoked prior to {@linkplain #build() building},333* then newly built clients will use the {@linkplain334* ProxySelector#getDefault() default proxy selector}, which is usually335* adequate for client applications. The default proxy selector supports336* a set of system properties related to337* <a href="{@docRoot}/java.base/java/net/doc-files/net-properties.html#Proxies">338* proxy settings</a>. This default behavior can be disabled by339* supplying an explicit proxy selector, such as {@link #NO_PROXY} or340* one returned by {@link ProxySelector#of(InetSocketAddress)341* ProxySelector::of}, before {@linkplain #build() building}.342*343* @param proxySelector the ProxySelector344* @return this builder345*/346public Builder proxy(ProxySelector proxySelector);347348/**349* Sets an authenticator to use for HTTP authentication.350*351* @param authenticator the Authenticator352* @return this builder353*/354public Builder authenticator(Authenticator authenticator);355356/**357* Returns a new {@link HttpClient} built from the current state of this358* builder.359*360* @return a new {@code HttpClient}361*362* @throws UncheckedIOException may be thrown if underlying IO resources required363* by the implementation cannot be allocated. For instance,364* if the implementation requires a {@link Selector}, and opening365* one fails due to {@linkplain Selector#open() lack of necessary resources}.366*/367public HttpClient build();368}369370371/**372* Returns an {@code Optional} containing this client's {@link373* CookieHandler}. If no {@code CookieHandler} was set in this client's374* builder, then the {@code Optional} is empty.375*376* @return an {@code Optional} containing this client's {@code CookieHandler}377*/378public abstract Optional<CookieHandler> cookieHandler();379380/**381* Returns an {@code Optional} containing the <i>connect timeout duration</i>382* for this client. If the {@linkplain Builder#connectTimeout(Duration)383* connect timeout duration} was not set in the client's builder, then the384* {@code Optional} is empty.385*386* @return an {@code Optional} containing this client's connect timeout387* duration388*/389public abstract Optional<Duration> connectTimeout();390391/**392* Returns the follow redirects policy for this client. The default value393* for client's built by builders that do not specify a redirect policy is394* {@link HttpClient.Redirect#NEVER NEVER}.395*396* @return this client's follow redirects setting397*/398public abstract Redirect followRedirects();399400/**401* Returns an {@code Optional} containing the {@code ProxySelector}402* supplied to this client. If no proxy selector was set in this client's403* builder, then the {@code Optional} is empty.404*405* <p> Even though this method may return an empty optional, the {@code406* HttpClient} may still have a non-exposed {@linkplain407* Builder#proxy(ProxySelector) default proxy selector} that is408* used for sending HTTP requests.409*410* @return an {@code Optional} containing the proxy selector supplied411* to this client.412*/413public abstract Optional<ProxySelector> proxy();414415/**416* Returns this client's {@code SSLContext}.417*418* <p> If no {@code SSLContext} was set in this client's builder, then the419* {@linkplain SSLContext#getDefault() default context} is returned.420*421* @return this client's SSLContext422*/423public abstract SSLContext sslContext();424425/**426* Returns a copy of this client's {@link SSLParameters}.427*428* <p> If no {@code SSLParameters} were set in the client's builder, then an429* implementation specific default set of parameters, that the client will430* use, is returned.431*432* @return this client's {@code SSLParameters}433*/434public abstract SSLParameters sslParameters();435436/**437* Returns an {@code Optional} containing the {@link Authenticator} set on438* this client. If no {@code Authenticator} was set in the client's builder,439* then the {@code Optional} is empty.440*441* @return an {@code Optional} containing this client's {@code Authenticator}442*/443public abstract Optional<Authenticator> authenticator();444445/**446* Returns the preferred HTTP protocol version for this client. The default447* value is {@link HttpClient.Version#HTTP_2}448*449* @implNote Constraints may also affect the selection of protocol version.450* For example, if HTTP/2 is requested through a proxy, and if the451* implementation does not support this mode, then HTTP/1.1 may be used452*453* @return the HTTP protocol version requested454*/455public abstract HttpClient.Version version();456457/**458* Returns an {@code Optional} containing this client's {@link459* Executor}. If no {@code Executor} was set in the client's builder,460* then the {@code Optional} is empty.461*462* <p> Even though this method may return an empty optional, the {@code463* HttpClient} may still have an non-exposed {@linkplain464* HttpClient.Builder#executor(Executor) default executor} that is used for465* executing asynchronous and dependent tasks.466*467* @return an {@code Optional} containing this client's {@code Executor}468*/469public abstract Optional<Executor> executor();470471/**472* The HTTP protocol version.473*474* @since 11475*/476public enum Version {477478/**479* HTTP version 1.1480*/481HTTP_1_1,482483/**484* HTTP version 2485*/486HTTP_2487}488489/**490* Defines the automatic redirection policy.491*492* <p> The automatic redirection policy is checked whenever a {@code 3XX}493* response code is received. If redirection does not happen automatically,494* then the response, containing the {@code 3XX} response code, is returned,495* where it can be handled manually.496*497* <p> {@code Redirect} policy is set through the {@linkplain498* HttpClient.Builder#followRedirects(Redirect) Builder.followRedirects}499* method.500*501* @implNote When automatic redirection occurs, the request method of the502* redirected request may be modified depending on the specific {@code 30X}503* status code, as specified in <a href="https://tools.ietf.org/html/rfc7231">504* RFC 7231</a>. In addition, the {@code 301} and {@code 302} status codes505* cause a {@code POST} request to be converted to a {@code GET} in the506* redirected request.507*508* @since 11509*/510public enum Redirect {511512/**513* Never redirect.514*/515NEVER,516517/**518* Always redirect.519*/520ALWAYS,521522/**523* Always redirect, except from HTTPS URLs to HTTP URLs.524*/525NORMAL526}527528/**529* Sends the given request using this client, blocking if necessary to get530* the response. The returned {@link HttpResponse}{@code <T>} contains the531* response status, headers, and body ( as handled by given response body532* handler ).533*534* <p> If the operation is interrupted, the default {@code HttpClient}535* implementation attempts to cancel the HTTP exchange and536* {@link InterruptedException} is thrown.537* No guarantee is made as to exactly <em>when</em> the cancellation request538* may be taken into account. In particular, the request might still get sent539* to the server, as its processing might already have started asynchronously540* in another thread, and the underlying resources may only be released541* asynchronously.542* <ul>543* <li>With HTTP/1.1, an attempt to cancel may cause the underlying544* connection to be closed abruptly.545* <li>With HTTP/2, an attempt to cancel may cause the stream to be reset,546* or in certain circumstances, may also cause the connection to be547* closed abruptly, if, for instance, the thread is currently trying548* to write to the underlying socket.549* </ul>550*551* @param <T> the response body type552* @param request the request553* @param responseBodyHandler the response body handler554* @return the response555* @throws IOException if an I/O error occurs when sending or receiving556* @throws InterruptedException if the operation is interrupted557* @throws IllegalArgumentException if the {@code request} argument is not558* a request that could have been validly built as specified by {@link559* HttpRequest.Builder HttpRequest.Builder}.560* @throws SecurityException If a security manager has been installed561* and it denies {@link java.net.URLPermission access} to the562* URL in the given request, or proxy if one is configured.563* See <a href="#securitychecks">security checks</a> for further564* information.565*/566public abstract <T> HttpResponse<T>567send(HttpRequest request, HttpResponse.BodyHandler<T> responseBodyHandler)568throws IOException, InterruptedException;569570/**571* Sends the given request asynchronously using this client with the given572* response body handler.573*574* <p> Equivalent to: {@code sendAsync(request, responseBodyHandler, null)}.575*576* @param <T> the response body type577* @param request the request578* @param responseBodyHandler the response body handler579* @return a {@code CompletableFuture<HttpResponse<T>>}580* @throws IllegalArgumentException if the {@code request} argument is not581* a request that could have been validly built as specified by {@link582* HttpRequest.Builder HttpRequest.Builder}.583*/584public abstract <T> CompletableFuture<HttpResponse<T>>585sendAsync(HttpRequest request,586BodyHandler<T> responseBodyHandler);587588/**589* Sends the given request asynchronously using this client with the given590* response body handler and push promise handler.591*592* <p> The returned completable future, if completed successfully, completes593* with an {@link HttpResponse}{@code <T>} that contains the response status,594* headers, and body ( as handled by given response body handler ).595*596* <p> {@linkplain PushPromiseHandler Push promises} received, if any, are597* handled by the given {@code pushPromiseHandler}. A {@code null} valued598* {@code pushPromiseHandler} rejects any push promises.599*600* <p> The returned completable future completes exceptionally with:601* <ul>602* <li>{@link IOException} - if an I/O error occurs when sending or receiving</li>603* <li>{@link SecurityException} - If a security manager has been installed604* and it denies {@link java.net.URLPermission access} to the605* URL in the given request, or proxy if one is configured.606* See <a href="#securitychecks">security checks</a> for further607* information.</li>608* </ul>609*610* <p> The default {@code HttpClient} implementation returns611* {@code CompletableFuture} objects that are <em>cancelable</em>.612* {@code CompletableFuture} objects {@linkplain CompletableFuture#newIncompleteFuture()613* derived} from cancelable futures are themselves <em>cancelable</em>.614* Invoking {@linkplain CompletableFuture#cancel(boolean) cancel(true)}615* on a cancelable future that is not completed, attempts to cancel the HTTP exchange616* in an effort to release underlying resources as soon as possible.617* No guarantee is made as to exactly <em>when</em> the cancellation request618* may be taken into account. In particular, the request might still get sent619* to the server, as its processing might already have started asynchronously620* in another thread, and the underlying resources may only be released621* asynchronously.622* <ul>623* <li>With HTTP/1.1, an attempt to cancel may cause the underlying connection624* to be closed abruptly.625* <li>With HTTP/2, an attempt to cancel may cause the stream to be reset.626* </ul>627*628* @param <T> the response body type629* @param request the request630* @param responseBodyHandler the response body handler631* @param pushPromiseHandler push promise handler, may be null632* @return a {@code CompletableFuture<HttpResponse<T>>}633* @throws IllegalArgumentException if the {@code request} argument is not634* a request that could have been validly built as specified by {@link635* HttpRequest.Builder HttpRequest.Builder}.636*/637public abstract <T> CompletableFuture<HttpResponse<T>>638sendAsync(HttpRequest request,639BodyHandler<T> responseBodyHandler,640PushPromiseHandler<T> pushPromiseHandler);641642/**643* Creates a new {@code WebSocket} builder (optional operation).644*645* <p> <b>Example</b>646* <pre>{@code HttpClient client = HttpClient.newHttpClient();647* CompletableFuture<WebSocket> ws = client.newWebSocketBuilder()648* .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre>649*650* <p> Finer control over the WebSocket Opening Handshake can be achieved651* by using a custom {@code HttpClient}.652*653* <p> <b>Example</b>654* <pre>{@code InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80);655* HttpClient client = HttpClient.newBuilder()656* .proxy(ProxySelector.of(addr))657* .build();658* CompletableFuture<WebSocket> ws = client.newWebSocketBuilder()659* .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre>660*661* @implSpec The default implementation of this method throws662* {@code UnsupportedOperationException}. Clients obtained through663* {@link HttpClient#newHttpClient()} or {@link HttpClient#newBuilder()}664* return a {@code WebSocket} builder.665*666* @implNote Both builder and {@code WebSocket}s created with it operate in667* a non-blocking fashion. That is, their methods do not block before668* returning a {@code CompletableFuture}. Asynchronous tasks are executed in669* this {@code HttpClient}'s executor.670*671* <p> When a {@code CompletionStage} returned from672* {@link WebSocket.Listener#onClose Listener.onClose} completes,673* the {@code WebSocket} will send a Close message that has the same code674* the received message has and an empty reason.675*676* @return a {@code WebSocket.Builder}677* @throws UnsupportedOperationException678* if this {@code HttpClient} does not provide WebSocket support679*/680public WebSocket.Builder newWebSocketBuilder() {681throw new UnsupportedOperationException();682}683}684685686