Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8243126

[macos]Infinite loop when a Http HEAD request receives a 403 response

XMLWordPrintable

    • x86
    • os_x_10.15

      ADDITIONAL SYSTEM INFORMATION :
      Always reproducible on Mac OS X Catalina 10.15.3 and using AdoptOpenJDK 11.0.7

      A DESCRIPTION OF THE PROBLEM :
      Using the new Java HTTP Client, a simple HTTP HEAD request, using all the defaults, causes the SSL logic in the HTTP Client implementation to enter into an infinite loop and is therefore maxing out the CPU

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the provided executable test case and look for output to standard error to cease after a minute or two.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      This code should print 403 to standard out and then wait. There will be some output to standard error but this will promptly stop.
      ACTUAL -
      This code prints 403 on the console, then there is a pause of a few seconds, and then the debug logs print out continuously to standard error without stopping. The CPU usage is sustained and high.

      ---------- BEGIN SOURCE ----------
      // *** Please enable HTTP client debug logs: -Djdk.internal.httpclient.debug=true ***

      package org.example;

      import java.io.IOException;
      import java.net.URI;
      import java.net.URISyntaxException;
      import java.net.http.HttpClient;
      import java.net.http.HttpRequest;
      import java.net.http.HttpResponse;

      public class HttpClientHeadRequestIssue {

         public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest req = HttpRequest.newBuilder(new URI("<A url that responds with status code 403>"))
                 .method("HEAD", HttpRequest.BodyPublishers.noBody())
                 .build();

            var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
            System.out.println(resp.statusCode());
            Thread.currentThread().join();
         }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      When you build the client, use SSLParameters that specify the protocol as TLSv1.2:

      // *** Please enable HTTP client debug logs: -Djdk.internal.httpclient.debug=true ***

      package org.example;

      import javax.net.ssl.SSLContext;
      import javax.net.ssl.SSLParameters;
      import java.io.IOException;
      import java.net.URI;
      import java.net.URISyntaxException;
      import java.net.http.HttpClient;
      import java.net.http.HttpRequest;
      import java.net.http.HttpResponse;
      import java.security.NoSuchAlgorithmException;

      public class HttpClientHeadRequestIssue {

         public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException, NoSuchAlgorithmException {
            SSLParameters sslParams = SSLContext.getDefault().getDefaultSSLParameters();
            sslParams.setProtocols(new String[] { "TLSv1.2"});

            HttpClient client = HttpClient.newBuilder()
                 .sslParameters(sslParams)
                 .build();
            HttpRequest req = HttpRequest.newBuilder(new URI("https://unclejust-test-app-data.ams3.digitaloceanspaces.com"))
                 .method("HEAD", HttpRequest.BodyPublishers.noBody())
                 .build();

            var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
            System.out.println(resp.statusCode());
            Thread.currentThread().join();
         }
      }


      FREQUENCY : always


            dfuchs Daniel Fuchs
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: