import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509ExtendedTrustManager;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.util.stream.Collectors;

public class IPv6HttpsClientTest {

    private static final int PORT = 443;
    private static final String PATH = "/";
    private static final String IPV6_LITERAL_HOST = "<REACHABLE_IPV6_ADDRESS>";

    public static void main(String[] args) {
        String urlString = "https://[" + IPV6_LITERAL_HOST + "]:" + PORT + PATH;
        HttpsURLConnection connection = null;
        try {
            URL url = new URL(urlString);
            connection = (HttpsURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.setSSLSocketFactory(new TrustAllX509ExtendedTrustManager().createTrustAllSSLContext().getSocketFactory());
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);

            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()))) {
                String responseBody = reader.lines().collect(Collectors.joining("\n"));
                System.out.println("Response Body (first 200 chars): " + responseBody.substring(0, Math.min(responseBody.length(), 200)));
            }
        } catch (SSLHandshakeException e) {
            System.out.println("Connection failed due to exception : " + e);
        } catch (Exception e) {
            System.out.println("Connection failed due to exception : " + e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    public static class TrustAllX509ExtendedTrustManager extends X509ExtendedTrustManager {

        private final X509Certificate[] EMPTY = new X509Certificate[0];

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) { }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) { }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) { }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) { }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) { }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) { }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return EMPTY;
        }

        public SSLContext createTrustAllSSLContext() throws Exception {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{ new TrustAllX509ExtendedTrustManager() }, new java.security.SecureRandom());
            return sc;
        }
    }
}