Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8286583

Add ability to bind to specific local address to HTTP client

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 19
    • core-libs
    • None
    • source
    • minimal
    • Hide
      This is a new API being introduced on the public HttpClient.Builder interface. We haven't yet seen any existing sub-interfaces/implementations of this public interface in external libraries, so chances of such sub-interfaces/implementation already having a method with this signature (and potentially different semantics) are minimal and thus I believe the impact of this change would be minimal.
      Show
      This is a new API being introduced on the public HttpClient.Builder interface. We haven't yet seen any existing sub-interfaces/implementations of this public interface in external libraries, so chances of such sub-interfaces/implementation already having a method with this signature (and potentially different semantics) are minimal and thus I believe the impact of this change would be minimal.
    • Java API
    • SE

      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

            jpai Jaikiran Pai
            michaelm Michael McMahon
            Daniel Fuchs
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: