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

WebEngine redirect loop on HTTP status 302 without "Location" header

XMLWordPrintable

    • web
    • generic
    • generic

      A DESCRIPTION OF THE PROBLEM :
      The JavaFX WebEngine unconditionally runs into a redirect loop when processing a resource with HTTP status code 302 (Found) without appropriate "Location" response header.

      While RFC 9110 states that the server SHOULD generate a "Location" header with a URI reference, it also states that the user agent MAY use this header for automatic redirection. The JavaFX implementation (both the HTTP2Loader and the old URLLoader) unconditionally resend the request to the original URI and run into a redirect loop after 20 attempts. Other user agents such as Google Chrome or Firefox behave as expected and simply display the response body without automatic redirection.

      The behavior is hard to debug since to suitable error information is provided to the application code, just a java.lang.Throwable with message "Unknown error".



      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a JavaFX WebView and load a resource from a rogue web server returning HTTP status 302 without "Location" header via WebView.getEngine().load(url).

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The response body is displayed without redirect.
      ACTUAL -
      The response body is not shown. Registering a ChangeListener on the LoadWorker's exception property reveals a Throwable with the non-descriptive error message "Unknown error".

      ---------- BEGIN SOURCE ----------
      import com.sun.net.httpserver.HttpServer;
      import java.io.IOException;
      import java.net.InetSocketAddress;
      import java.util.concurrent.atomic.AtomicInteger;
      import javafx.application.Application;
      import javafx.scene.Scene;
      import javafx.scene.web.WebEngine;
      import javafx.scene.web.WebView;
      import javafx.stage.Stage;

      /**
       * Starts a rogue HTTP server returning 302 without "Location" header and
       * and launches a JavaFX WebView for viewing the URL.
       */
      public class Main extends Application {

      private static final String HOST = "127.0.0.1";
      private static final int PORT = 8080;

          public static void main(String[] args) throws IOException {
      startRogueServer();
      launch(args);
          }

      private static void startRogueServer() throws IOException {
      System.out.printf("Starting rogue HTTP server on %s:%d%n", HOST, PORT);
      AtomicInteger counter = new AtomicInteger();
      InetSocketAddress addr = new InetSocketAddress(HOST, PORT);
      HttpServer server = HttpServer.create(addr, 0);
      server.createContext("/test", ex -> {
      int count = counter.incrementAndGet();
      System.out.printf("Processing: %s (%d)%n", ex.getRequestURI(), count);
      byte[] data = "TEST".getBytes("UTF-8");
      ex.getResponseHeaders().add("Content-Type", "text/plain");
      ex.sendResponseHeaders(302, data.length);
      ex.getResponseBody().write(data);
      ex.getResponseBody().close();
      });
      server.start();
      System.out.println("Local HTTP server ready");
      }

      @Override
      public void start(Stage stage) throws Exception {
      System.out.println("Starting JavaFX WebView");
      stage.setTitle("WebEngine Redirect w/o Location");
      WebView view = new WebView();
      stage.setScene(new Scene(view, 640, 480));
      stage.show();
      String url = String.format("http://%s:%d/test", HOST, PORT);
      System.out.printf("Loading URL: %s%n", url);
      WebEngine engine = view.getEngine();
      engine.getLoadWorker().exceptionProperty().addListener((obs, prev, next) -> {
      if (next != null) {
      next.printStackTrace(System.err);
      String msg = String.format("Error loading %s: %s", url, next);
      engine.loadContent(msg, "text/plain");
      }
      });
      engine.load(url);
      }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      None.

      FREQUENCY : always


            jbhaskar Jay Bhaskar
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: