JDK-8286583 : Add ability to bind to specific local address to HTTP client
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.net
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 19
  • Submitted: 2022-05-11
  • Updated: 2022-05-15
  • Resolved: 2022-05-15
Related Reports
CSR :  
Description
Summary
-------

Introduce an API on `java.net.http.HttpClient.Builder` interface to allow users to specify a particular local address to bind to.

Problem
-------
Applications use `java.net.http.HttpClient`, typically built using a `HttpClient.newBuilder()` to issue HTTP requests. Such requests internally create instance(s) of `java.nio.channels.SocketChannel` to communicate with the target server(s). The sockets of such `SocketChannel` instances currently bind to automatically assigned socket address. Applications do not have control over which address will be chosen to bind to on multi-homed systems. This enhancement proposes to allow applications to optionally choose which address to bind to.


Solution
--------
A new API is introduced on `HttpClient.Builder`:

           public interface Builder {
              ...
     
    +        /**
    +         * Binds the socket to this local address when creating
    +         * connections for sending requests.
    +         *
    +         * <p> If no local address is set or {@code null} is passed
    +         * to this method then sockets created by the
    +         * HTTP client will be bound to an automatically
    +         * assigned socket address.
    +         *
    +         * <p> Common usages of the {@code HttpClient} do not require
    +         * this method to be called. Setting a local address, through this
    +         * method, is only for advanced usages where users of the {@code HttpClient}
    +         * require specific control on which network interface gets used
    +         * for the HTTP communication. Callers of this method are expected to
    +         * be aware of the networking configurations of the system where the
    +         * {@code HttpClient} will be used and care should be taken to ensure the
    +         * correct {@code localAddr} is passed. Failure to do so can result in
    +         * requests sent through the {@code HttpClient} to fail.
    +         *
    +         * @implSpec The default implementation of this method throws
    +         * {@code UnsupportedOperationException}. {@code Builder}s obtained
    +         * through {@link HttpClient#newBuilder()} provide an implementation
    +         * of this method that allows setting the local address.
    +         *
    +         * @param localAddr The local address of the socket. Can be null.
    +         * @return this builder
    +         * @throws UnsupportedOperationException if this builder doesn't support
    +         *         configuring a local address or if the passed {@code localAddr}
    +         *         is not supported by this {@code HttpClient} implementation.
    +         * @since 19
    +         */
    +        default Builder localAddress(InetAddress localAddr) {
    +            throw new UnsupportedOperationException();
    +        }
    +
             /**
              * Returns a new {@link HttpClient} built from the current state of this
              * builder.
              *
    +         * @implSpec If the {@link #localAddress(InetAddress) local address} is
    +         * a non-null address and a security manager is installed, then
    +         * this method calls {@link SecurityManager#checkListen checkListen} to 
    +         * check that the caller has necessary permission to bind to that local address.
    +         *
              * @return a new {@code HttpClient}
              *
              * @throws UncheckedIOException may be thrown if underlying IO resources
              * required by the implementation cannot be allocated. For instance,
              * if the implementation requires a {@link Selector}, and opening
              * one fails due to {@linkplain Selector#open() lack of necessary resources}.
    +         * @throws SecurityException If a security manager has been installed and the
    +         *         security manager's {@link SecurityManager#checkListen checkListen}
    +         *         method disallows binding to the given address.
              */
             public HttpClient build();

Specification
-------------
See solution section also the auto-generated webrev for this enhancement, details the exact changes https://openjdk.github.io/cr/?repo=jdk&pr=6690&range=18#udiff-1-src/java.net.http/share/classes/java/net/http/HttpClient.java


Comments
Moving to Approved.
15-05-2022