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

XMLWordPrintable

    • Type: Bug
    • Resolution: Unresolved
    • Priority: P3
    • tbd
    • Affects Version/s: 8, 11
    • Component/s: core-libs
    • Environment:

      OEL 7 and OEL 8 on x86_64

      {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:
            4 Start watching this issue

              Created:
              Updated: