test/jdk/java/net/httpclient/http2/RedirectTest.java
changeset 48083 b1c1b4ef4be2
parent 47216 71c04702a3d5
child 49765 ee6f7a61f3a5
child 55973 4d9b002587db
--- a/test/jdk/java/net/httpclient/http2/RedirectTest.java	Fri Nov 03 10:01:08 2017 -0700
+++ b/test/jdk/java/net/httpclient/http2/RedirectTest.java	Wed Dec 06 11:11:59 2017 -0800
@@ -24,36 +24,34 @@
 /*
  * @test
  * @bug 8156514
- * @key intermittent
  * @library /lib/testlibrary server
  * @build jdk.testlibrary.SimpleSSLContext
- * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common
- * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.frame
- * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
+ * @modules java.base/sun.net.www.http
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.common
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.frame
+ *          jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
  * @run testng/othervm -Djdk.httpclient.HttpClient.log=frames,ssl,requests,responses,errors RedirectTest
  */
 
 import java.net.*;
 import jdk.incubator.http.*;
-import static jdk.incubator.http.HttpClient.Version.HTTP_2;
-import java.nio.file.*;
+import java.util.Optional;
 import java.util.concurrent.*;
 import java.util.function.*;
 import java.util.Arrays;
 import java.util.Iterator;
-import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
+import org.testng.annotations.Test;
+import static jdk.incubator.http.HttpClient.Version.HTTP_2;
+import static jdk.incubator.http.HttpRequest.BodyPublisher.fromString;
 import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
 
-import org.testng.annotations.Test;
-
-@Test
 public class RedirectTest {
-    static int httpPort, altPort;
-    static Http2TestServer httpServer, altServer;
+    static int httpPort;
+    static Http2TestServer httpServer;
     static HttpClient client;
-    static ExecutorService exec;
 
     static String httpURIString, altURIString1, altURIString2;
+    static URI httpURI, altURI1, altURI2;
 
     static Supplier<String> sup(String... args) {
         Iterator<String> i = Arrays.asList(args).iterator();
@@ -61,28 +59,56 @@
         return () -> i.next();
     }
 
+    static class Redirector extends Http2RedirectHandler {
+        private InetSocketAddress remoteAddr;
+        private boolean error = false;
+
+        Redirector(Supplier<String> supplier) {
+            super(supplier);
+        }
+
+        protected synchronized void examineExchange(Http2TestExchange ex) {
+            InetSocketAddress addr = ex.getRemoteAddress();
+            if (remoteAddr == null) {
+                remoteAddr = addr;
+                return;
+            }
+            // check that the client addr/port stays the same, proving
+            // that the connection didn't get dropped.
+            if (!remoteAddr.equals(addr)) {
+                System.err.printf("Error %s/%s\n", remoteAddr.toString(),
+                        addr.toString());
+                error = true;
+            }
+        }
+
+        public synchronized boolean error() {
+            return error;
+        }
+    }
+
     static void initialize() throws Exception {
         try {
             client = getClient();
-            httpServer = new Http2TestServer(false, 0, exec, null);
-
+            httpServer = new Http2TestServer(false, 0, null, null);
             httpPort = httpServer.getAddress().getPort();
-            altServer = new Http2TestServer(false, 0, exec, null);
-            altPort = altServer.getAddress().getPort();
 
-            // urls are accessed in sequence below
-            // first two on different servers. Third on same server
-            // as second. So, the client should use the same http connection
+            // urls are accessed in sequence below. The first two are on
+            // different servers. Third on same server as second. So, the
+            // client should use the same http connection.
             httpURIString = "http://127.0.0.1:" + httpPort + "/foo/";
-            altURIString1 = "http://127.0.0.1:" + altPort + "/redir";
-            altURIString2 = "http://127.0.0.1:" + altPort + "/redir/again";
+            httpURI = URI.create(httpURIString);
+            altURIString1 = "http://127.0.0.1:" + httpPort + "/redir";
+            altURI1 = URI.create(altURIString1);
+            altURIString2 = "http://127.0.0.1:" + httpPort + "/redir_again";
+            altURI2 = URI.create(altURIString2);
 
-            httpServer.addHandler(new RedirectHandler(sup(altURIString1)), "/foo");
-            altServer.addHandler(new RedirectHandler(sup(altURIString2)), "/redir");
-            altServer.addHandler(new Http2EchoHandler(), "/redir/again");
+            Redirector r = new Redirector(sup(altURIString1, altURIString2));
+            httpServer.addHandler(r, "/foo");
+            httpServer.addHandler(r, "/redir");
+            httpServer.addHandler(new Http2EchoHandler(), "/redir_again");
 
             httpServer.start();
-            altServer.start();
         } catch (Throwable e) {
             System.err.println("Throwing now");
             e.printStackTrace();
@@ -90,26 +116,19 @@
         }
     }
 
-    @Test(timeOut=3000000)
+    @Test
     public static void test() throws Exception {
         try {
             initialize();
             simpleTest();
-        } catch (Throwable tt) {
-            System.err.println("tt caught");
-            tt.printStackTrace();
         } finally {
             httpServer.stop();
-            altServer.stop();
-            exec.shutdownNow();
         }
     }
 
     static HttpClient getClient() {
         if (client == null) {
-            exec = Executors.newCachedThreadPool();
             client = HttpClient.newBuilder()
-                               .executor(exec)
                                .followRedirects(HttpClient.Redirect.ALWAYS)
                                .version(HTTP_2)
                                .build();
@@ -129,6 +148,15 @@
         }
     }
 
+    static void checkURIs(URI expected, URI found) throws Exception {
+        System.out.printf ("Expected: %s, Found: %s\n", expected.toString(), found.toString());
+        if (!expected.equals(found)) {
+            System.err.printf ("Test failed: wrong URI %s/%s\n",
+                expected.toString(), found.toString());
+            throw new RuntimeException("Test failed");
+        }
+    }
+
     static void checkStrings(String expected, String found) throws Exception {
         if (!expected.equals(found)) {
             System.err.printf ("Test failed: wrong string %s/%s\n",
@@ -137,18 +165,17 @@
         }
     }
 
-    static Void compareFiles(Path path1, Path path2) {
-        return TestUtil.compareFiles(path1, path2);
-    }
-
-    static Path tempFile() {
-        return TestUtil.tempFile();
+    static void check(boolean cond, Object... msg) {
+        if (cond)
+            return;
+        StringBuilder sb = new StringBuilder();
+        for (Object o : msg)
+            sb.append(o);
+        throw new RuntimeException(sb.toString());
     }
 
     static final String SIMPLE_STRING = "Hello world Goodbye world";
 
-    static final int FILESIZE = 64 * 1024 + 200;
-
     static void simpleTest() throws Exception {
         URI uri = getURI();
         System.err.println("Request to " + uri);
@@ -163,8 +190,44 @@
         checkStatus(200, response.statusCode());
         String responseBody = response.body();
         checkStrings(SIMPLE_STRING, responseBody);
+        checkURIs(response.uri(), altURI2);
+
+        // check two previous responses
+        HttpResponse<String> prev = response.previousResponse()
+            .orElseThrow(() -> new RuntimeException("no previous response"));
+        checkURIs(prev.uri(), altURI1);
+
+        prev = prev.previousResponse()
+            .orElseThrow(() -> new RuntimeException("no previous response"));
+        checkURIs(prev.uri(), httpURI);
+
+        checkPreviousRedirectResponses(req, response);
 
         System.err.println("DONE");
-        Thread.sleep (6000);
+    }
+
+    static void checkPreviousRedirectResponses(HttpRequest initialRequest,
+                                               HttpResponse<?> finalResponse) {
+        // there must be at least one previous response
+        finalResponse.previousResponse()
+                .orElseThrow(() -> new RuntimeException("no previous response"));
+
+        HttpResponse<?> response = finalResponse;
+        do {
+            URI uri = response.uri();
+            response = response.previousResponse().get();
+            check(300 <= response.statusCode() && response.statusCode() <= 309,
+                    "Expected 300 <= code <= 309, got:" + response.statusCode());
+            check(response.body() == null, "Unexpected body: " + response.body());
+            String locationHeader = response.headers().firstValue("Location")
+                    .orElseThrow(() -> new RuntimeException("no previous Location"));
+            check(uri.toString().endsWith(locationHeader),
+                    "URI: " + uri + ", Location: " + locationHeader);
+        } while (response.previousResponse().isPresent());
+
+        // initial
+        check(initialRequest.equals(response.request()),
+                "Expected initial request [%s] to equal last prev req [%s]",
+                initialRequest, response.request());
     }
 }