diff --git a/src/main/java/org/java_websocket/client/DnsResolver.java b/src/main/java/org/java_websocket/client/DnsResolver.java new file mode 100644 index 00000000..016f811b --- /dev/null +++ b/src/main/java/org/java_websocket/client/DnsResolver.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010-2019 Nathan Rajlich + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.java_websocket.client; + +import java.net.InetAddress; +import java.net.URI; +import java.net.UnknownHostException; + +/** + * Users may implement this interface to override the default DNS lookup offered + * by the OS. + * + * @since 1.4.1 + */ +public interface DnsResolver { + + /** + * Resolves the IP address for the given URI. + * + * This method should never return null. If it's not able to resolve the IP + * address then it should throw an UnknownHostException + * + * @param uri The URI to be resolved + * + * @return The resolved IP address + * + * @throws UnknownHostException if no IP address for the uri could be found. + */ + InetAddress resolve(URI uri) throws UnknownHostException; + +} diff --git a/src/main/java/org/java_websocket/client/WebSocketClient.java b/src/main/java/org/java_websocket/client/WebSocketClient.java index fc86d813..f5cd9b12 100644 --- a/src/main/java/org/java_websocket/client/WebSocketClient.java +++ b/src/main/java/org/java_websocket/client/WebSocketClient.java @@ -28,10 +28,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.Socket; import java.net.URI; +import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.util.Collection; import java.util.Collections; @@ -131,6 +133,14 @@ public abstract class WebSocketClient extends AbstractWebSocket implements Runna */ private int connectTimeout = 0; + /** + * DNS resolver that translates a URI to an InetAddress + * + * @see InetAddress + * @since 1.4.1 + */ + private DnsResolver dnsResolver = null; + /** * Constructs a WebSocketClient instance and sets it to the connect to the * specified URI. The channel does not attampt to connect automatically. The connection @@ -195,6 +205,12 @@ public WebSocketClient( URI serverUri , Draft protocolDraft , Map } this.uri = serverUri; this.draft = protocolDraft; + this.dnsResolver = new DnsResolver() { + @Override + public InetAddress resolve(URI uri) throws UnknownHostException { + return InetAddress.getByName(uri.getHost()); + } + }; if(httpHeaders != null) { headers = new TreeMap(String.CASE_INSENSITIVE_ORDER); headers.putAll(httpHeaders); @@ -266,6 +282,17 @@ public void clearHeaders() { headers = null; } + /** + * Sets a custom DNS resolver. + * + * @param dnsResolver The DnsResolver to use. + * + * @since 1.4.1 + */ + public void setDnsResolver(DnsResolver dnsResolver) { + this.dnsResolver = dnsResolver; + } + /** * Reinitiates the websocket connection. This method does not block. * @since 1.3.8 @@ -431,8 +458,9 @@ public void run() { socket.setTcpNoDelay( isTcpNoDelay() ); socket.setReuseAddress( isReuseAddr() ); - if( !socket.isBound() ) { - socket.connect( new InetSocketAddress( uri.getHost(), getPort() ), connectTimeout ); + if (!socket.isBound()) { + InetSocketAddress addr = new InetSocketAddress(dnsResolver.resolve(uri), this.getPort()); + socket.connect(addr, connectTimeout); } // if the socket is set by others we don't apply any TLS wrapper @@ -509,9 +537,9 @@ private void sendHandshake() throws InvalidHandshakeException { if( part2 != null ) path += '?' + part2; int port = getPort(); - String host = uri.getHost() + ( + String host = uri.getHost() + ( (port != WebSocketImpl.DEFAULT_PORT && port != WebSocketImpl.DEFAULT_WSS_PORT) - ? ":" + port + ? ":" + port : "" ); HandshakeImpl1Client handshake = new HandshakeImpl1Client(); @@ -844,7 +872,7 @@ public InetSocketAddress getLocalSocketAddress() { public InetSocketAddress getRemoteSocketAddress() { return engine.getRemoteSocketAddress(); } - + @Override public String getResourceDescriptor() { return uri.getPath();