HttpsURLConnection.getServerCertificates() throws "java.lang.IllegalStateException: connection not yet open" for the HEAD method

XMLWordPrintable

    • b08

        {code}
        HttpURLConnection connection = null;
                try
                {
                    connection = (HttpURLConnection) new URL(url).openConnection();
                    connection.setReadTimeout(1500);
                    connection.setConnectTimeout(3000);
                    connection.setRequestMethod("HEAD");
                    connection.setDoInput(true);

                    int responseCode = connection.getResponseCode();

                    boolean isHealthy = responseCode / 100 == 2;

                    Date certificateExpiration = null;

                    
                    if (connection instanceof HttpsURLConnection)
                    {
                        try
                        {
                            Certificate[] certs = ((HttpsURLConnection) connection).getServerCertificates();
                            if (certs != null && certs.length > 0 && certs[0] instanceof X509Certificate)
                            {
                                certificateExpiration = ((X509Certificate) certs[0]).getNotAfter();
                            }
                        }
                        catch (SSLPeerUnverifiedException e)
                        {
                            System.err.println("Error getting server certificates: " + e.getMessage());
                        }
                    }
                    // Consume the input stream to release the connection back to the pool
                    try (InputStream inputStream = connection.getInputStream())
                    {
                        // Do nothing, just consume the stream
                    }
                    catch (IOException e)
                    {
                        // Ignore, we've already got the response code
                    }

                    // If there's an error stream, consume it to release the connection
                    try (InputStream errorStream = connection.getErrorStream())
                    {
                        // Do nothing, just consume the stream
                    }
                    catch (Exception e)
                    {
                        System.err.println("Error consuming error stream: " + e.getMessage());
                    }

                    System.out.println("Healthy: " + isHealthy + " Code: " + responseCode + " Cert expiration: " + certificateExpiration);
                }
                catch (Exception e)
                {
                    System.err.println("Error checking health: " + e.getMessage());
                }
        {code}

        Fails (on an https url) when trying to get the server certificates:

        {code}
        java.lang.IllegalStateException: connection not yet open
        at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getServerCertificates(AbstractDelegateHttpsURLConnection.java:274)
        at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getServerCertificates(HttpsURLConnectionImpl.java:212)
        at Test.checkHealth(Test.java:36)
        at Test.main(Test.java:85)
        {code}

        Adding an explicit call to connect() prior to callin getServerCertificates allows it to succeed, but causes file handle leaks.

              Assignee:
              Daniel Fuchs
              Reporter:
              Brett Okken
              Votes:
              0 Vote for this issue
              Watchers:
              10 Start watching this issue

                Created:
                Updated:
                Resolved: