Skip to content

Commit d06ebe8

Browse files
committed
Intermediate commit
1 parent ce1f3d7 commit d06ebe8

File tree

2 files changed

+117
-1
lines changed

2 files changed

+117
-1
lines changed

flight/flight-core/src/main/java/org/apache/arrow/flight/grpc/NettyClientBuilder.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ public NettyChannelBuilder build() {
139139
case LocationSchemes.GRPC_INSECURE:
140140
case LocationSchemes.GRPC_TLS:
141141
{
142-
builder = NettyChannelBuilder.forAddress(location.toSocketAddress());
142+
builder =
143+
NettyChannelBuilder.forAddress(
144+
location.getUri().getHost(), location.getUri().getPort());
143145
break;
144146
}
145147
case LocationSchemes.GRPC_DOMAIN_SOCKET:

flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ConnectionTest.java

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,4 +768,118 @@ public void testResultSetsFromDatabaseMetadataClosedOnConnectionClose() throws E
768768
assertTrue(resultSets[i].isClosed());
769769
}
770770
}
771+
772+
/**
773+
* Test that JDBC driver respects JVM proxy settings.
774+
*
775+
* <p>This test verifies that when JVM proxy properties are set, the Flight client attempts to
776+
* connect through the proxy. This will FAIL with the current implementation and PASS when the fix
777+
* is applied.
778+
*
779+
* @throws Exception on error.
780+
*/
781+
@Test
782+
public void testJdbcDriverRespectsProxySettings() throws Exception {
783+
final int targetPort = FLIGHT_SERVER_TEST_EXTENSION.getPort();
784+
785+
String originalHttpsProxyHost = System.getProperty("https.proxyHost");
786+
String originalHttpsProxyPort = System.getProperty("https.proxyPort");
787+
String originalNonProxyHosts = System.getProperty("http.nonProxyHosts");
788+
789+
try (SimpleProxyDetector proxy = new SimpleProxyDetector()) {
790+
proxy.start();
791+
792+
System.setProperty("https.proxyHost", "localhost");
793+
System.setProperty("https.proxyPort", String.valueOf(proxy.getPort()));
794+
// Ensure localhost is not in the non-proxy hosts list
795+
System.setProperty("http.nonProxyHosts", "");
796+
797+
final Properties properties = new Properties();
798+
properties.put(ArrowFlightConnectionProperty.USER.camelName(), userTest);
799+
properties.put(ArrowFlightConnectionProperty.PASSWORD.camelName(), passTest);
800+
properties.put("useEncryption", false);
801+
802+
// Use "example.com" as the target host to trigger proxy usage
803+
// The proxy will receive the connection attempt, proving proxy settings are respected
804+
try (Connection connection =
805+
DriverManager.getConnection(
806+
"jdbc:arrow-flight-sql://example.com:" + targetPort, properties)) {
807+
// Connection will fail, but that's OK - we just want to see if proxy was contacted
808+
} catch (Exception e) {
809+
// Expected - proxy doesn't forward
810+
}
811+
812+
assertTrue(
813+
proxy.wasContacted(),
814+
"JDBC driver should respect JVM proxy settings. "
815+
+ "The proxy did not receive a connection, indicating proxy settings are ignored.");
816+
817+
} finally {
818+
if (originalHttpsProxyHost == null) {
819+
System.clearProperty("https.proxyHost");
820+
} else {
821+
System.setProperty("https.proxyHost", originalHttpsProxyHost);
822+
}
823+
if (originalHttpsProxyPort == null) {
824+
System.clearProperty("https.proxyPort");
825+
} else {
826+
System.setProperty("https.proxyPort", originalHttpsProxyPort);
827+
}
828+
if (originalNonProxyHosts == null) {
829+
System.clearProperty("http.nonProxyHosts");
830+
} else {
831+
System.setProperty("http.nonProxyHosts", originalNonProxyHosts);
832+
}
833+
}
834+
}
835+
836+
/** Simple proxy detector for testing proxy support. */
837+
private static class SimpleProxyDetector implements AutoCloseable {
838+
private final int port;
839+
private final java.util.concurrent.atomic.AtomicBoolean contacted =
840+
new java.util.concurrent.atomic.AtomicBoolean(false);
841+
private final java.util.concurrent.CountDownLatch started =
842+
new java.util.concurrent.CountDownLatch(1);
843+
private Thread thread;
844+
845+
SimpleProxyDetector() throws java.io.IOException {
846+
try (java.net.ServerSocket socket = new java.net.ServerSocket(0)) {
847+
socket.setReuseAddress(true);
848+
this.port = socket.getLocalPort();
849+
}
850+
}
851+
852+
void start() throws InterruptedException {
853+
thread =
854+
new Thread(
855+
() -> {
856+
try (java.net.ServerSocket socket = new java.net.ServerSocket(port)) {
857+
started.countDown();
858+
socket.setSoTimeout(5000);
859+
socket.accept();
860+
contacted.set(true);
861+
} catch (Exception e) {
862+
// Timeout or error
863+
}
864+
});
865+
thread.setDaemon(true);
866+
thread.start();
867+
started.await(5, java.util.concurrent.TimeUnit.SECONDS);
868+
}
869+
870+
int getPort() {
871+
return port;
872+
}
873+
874+
boolean wasContacted() {
875+
return contacted.get();
876+
}
877+
878+
@Override
879+
public void close() {
880+
if (thread != null) {
881+
thread.interrupt();
882+
}
883+
}
884+
}
771885
}

0 commit comments

Comments
 (0)