Message-ID: From: "chengfeng-xie (@chengfeng-xie)" To: "pgjdbc/pgjdbc" Date: Thu, 30 Apr 2026 08:26:26 +0000 Subject: [pgjdbc/pgjdbc] issue #4044: `HostSpec` handles `127.0.0.1` differently from `DefaultProxySelector` by default under a proxy on macOS List-Id: X-GitHub-Author-Id: 252100028 X-GitHub-Author-Login: chengfeng-xie X-GitHub-Issue: 4044 X-GitHub-Repo: pgjdbc/pgjdbc X-GitHub-State: closed X-GitHub-Type: issue X-GitHub-Url: https://github.com/pgjdbc/pgjdbc/issues/4044 Content-Type: text/plain; charset=utf-8 ## Describe the issue #985 added support for the `socksNonProxyHosts` property to `HostSpec`, but the way it constructs the list of non-proxy hosts differs from that of `DefaultProxySelector`. This can lead to a situation where, for a specific target address, `HostSpec` determines that the connection should go through the proxy, so `PGStream` passes an *unresolved* `InetSocketAddress` to `SocksSocketImpl`, which in turn determines that the target should be connected to directly instead. As a result, an `UnknownHostException` is thrown because the `InetSocketAddress` is still unresolved when it is passed to the underlying `NioSocketImpl`. Suppose a SOCKS proxy `127.0.0.1:1080` is configured on macOS through the GUI and no other changes are made. By default, macOS supplies the value `*.local, 169.254/16` for the option "Bypass proxy settings for these hosts & domains", as shown in the GUI. For that option, the JVM converts it to the system property `socksNonProxyHosts` with the value `local|*.local|169.254/16|*.169.254/16` (the conversion is not perfect, but that is not particularly relevant to this issue). Note that `127.0.0.1` is not included in this list. Now, for `HostSpec`, the relevant code is: https://github.com/pgjdbc/pgjdbc/blob/68c53a435291fea8be40eb1d9c550311743d326d/pgjdbc/src/main/java/org/postgresql/util/HostSpec.java#L74 `DEFAULT_NON_PROXY_HOSTS` matches `127.0.0.1`, but it is not used here because it only serves as a fallback when `socksNonProxyHosts` is not set, which is not the case here. For `DefaultProxySelector` (used by `SocksSocketImpl`), the relevant code is [[1]](https://github.com/adoptium/jdk21u/blob/d8615be992082324aaeb01bd6db275e30485aeea/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java#L268-L274): ```java // ... } else if (!nphosts.isEmpty()) { // add the required default patterns // but only if property no set. If it // is empty, leave empty. nphosts += "|" + NonProxyInfo .defStringVal; } ``` That is, the current property value is merged with the default non-proxy host list. In other words, `127.0.0.1` is always treated as non-proxied under this approach. I think it would be great to align the behavior of `HostSpec` with that of `DefaultProxySelector` so that users do not have to manually set the `socksNonProxyHosts` property as a workaround for each affected project. ## Driver version 42.7.3 ## Java version 21.0.11 ## OS version macOS 26.4 ## PostgreSQL version 18.3 ## To reproduce The following code emulates the case described above: ```java import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; class Main { public static void main(String[] args) throws IOException { System.getProperties().put("socksProxyHost", "127.0.0.1"); System.getProperties().put("socksProxyPort", "1080"); System.getProperties().put("socksNonProxyHosts", "local|*.local|169.254/16|*.169.254/16"); final var address = InetSocketAddress.createUnresolved("127.0.0.1", 1234); try (final var socket = new Socket()) { socket.connect(address); } } } ``` ## Expected behaviour The connection succeeds with no `UnknownHostException` being thrown. ## Logs ``` Exception in thread "main" java.net.UnknownHostException: 127.0.0.1 at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:567) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) at java.base/java.net.Socket.connect(Socket.java:751) at java.base/java.net.Socket.connect(Socket.java:686) at Main.main(example.java:12) ```