test/jdk/java/net/httpclient/http2/RedirectTest.java
changeset 48083 b1c1b4ef4be2
parent 47216 71c04702a3d5
child 49765 ee6f7a61f3a5
child 55973 4d9b002587db
equal deleted inserted replaced
48081:89829dd3cc54 48083:b1c1b4ef4be2
    22  */
    22  */
    23 
    23 
    24 /*
    24 /*
    25  * @test
    25  * @test
    26  * @bug 8156514
    26  * @bug 8156514
    27  * @key intermittent
       
    28  * @library /lib/testlibrary server
    27  * @library /lib/testlibrary server
    29  * @build jdk.testlibrary.SimpleSSLContext
    28  * @build jdk.testlibrary.SimpleSSLContext
    30  * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common
    29  * @modules java.base/sun.net.www.http
    31  * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.frame
    30  *          jdk.incubator.httpclient/jdk.incubator.http.internal.common
    32  * @modules jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
    31  *          jdk.incubator.httpclient/jdk.incubator.http.internal.frame
       
    32  *          jdk.incubator.httpclient/jdk.incubator.http.internal.hpack
    33  * @run testng/othervm -Djdk.httpclient.HttpClient.log=frames,ssl,requests,responses,errors RedirectTest
    33  * @run testng/othervm -Djdk.httpclient.HttpClient.log=frames,ssl,requests,responses,errors RedirectTest
    34  */
    34  */
    35 
    35 
    36 import java.net.*;
    36 import java.net.*;
    37 import jdk.incubator.http.*;
    37 import jdk.incubator.http.*;
    38 import static jdk.incubator.http.HttpClient.Version.HTTP_2;
    38 import java.util.Optional;
    39 import java.nio.file.*;
       
    40 import java.util.concurrent.*;
    39 import java.util.concurrent.*;
    41 import java.util.function.*;
    40 import java.util.function.*;
    42 import java.util.Arrays;
    41 import java.util.Arrays;
    43 import java.util.Iterator;
    42 import java.util.Iterator;
    44 import static jdk.incubator.http.HttpRequest.BodyProcessor.fromString;
    43 import org.testng.annotations.Test;
       
    44 import static jdk.incubator.http.HttpClient.Version.HTTP_2;
       
    45 import static jdk.incubator.http.HttpRequest.BodyPublisher.fromString;
    45 import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
    46 import static jdk.incubator.http.HttpResponse.BodyHandler.asString;
    46 
    47 
    47 import org.testng.annotations.Test;
       
    48 
       
    49 @Test
       
    50 public class RedirectTest {
    48 public class RedirectTest {
    51     static int httpPort, altPort;
    49     static int httpPort;
    52     static Http2TestServer httpServer, altServer;
    50     static Http2TestServer httpServer;
    53     static HttpClient client;
    51     static HttpClient client;
    54     static ExecutorService exec;
       
    55 
    52 
    56     static String httpURIString, altURIString1, altURIString2;
    53     static String httpURIString, altURIString1, altURIString2;
       
    54     static URI httpURI, altURI1, altURI2;
    57 
    55 
    58     static Supplier<String> sup(String... args) {
    56     static Supplier<String> sup(String... args) {
    59         Iterator<String> i = Arrays.asList(args).iterator();
    57         Iterator<String> i = Arrays.asList(args).iterator();
    60         // need to know when to stop calling it.
    58         // need to know when to stop calling it.
    61         return () -> i.next();
    59         return () -> i.next();
    62     }
    60     }
    63 
    61 
       
    62     static class Redirector extends Http2RedirectHandler {
       
    63         private InetSocketAddress remoteAddr;
       
    64         private boolean error = false;
       
    65 
       
    66         Redirector(Supplier<String> supplier) {
       
    67             super(supplier);
       
    68         }
       
    69 
       
    70         protected synchronized void examineExchange(Http2TestExchange ex) {
       
    71             InetSocketAddress addr = ex.getRemoteAddress();
       
    72             if (remoteAddr == null) {
       
    73                 remoteAddr = addr;
       
    74                 return;
       
    75             }
       
    76             // check that the client addr/port stays the same, proving
       
    77             // that the connection didn't get dropped.
       
    78             if (!remoteAddr.equals(addr)) {
       
    79                 System.err.printf("Error %s/%s\n", remoteAddr.toString(),
       
    80                         addr.toString());
       
    81                 error = true;
       
    82             }
       
    83         }
       
    84 
       
    85         public synchronized boolean error() {
       
    86             return error;
       
    87         }
       
    88     }
       
    89 
    64     static void initialize() throws Exception {
    90     static void initialize() throws Exception {
    65         try {
    91         try {
    66             client = getClient();
    92             client = getClient();
    67             httpServer = new Http2TestServer(false, 0, exec, null);
    93             httpServer = new Http2TestServer(false, 0, null, null);
    68 
       
    69             httpPort = httpServer.getAddress().getPort();
    94             httpPort = httpServer.getAddress().getPort();
    70             altServer = new Http2TestServer(false, 0, exec, null);
    95 
    71             altPort = altServer.getAddress().getPort();
    96             // urls are accessed in sequence below. The first two are on
    72 
    97             // different servers. Third on same server as second. So, the
    73             // urls are accessed in sequence below
    98             // client should use the same http connection.
    74             // first two on different servers. Third on same server
       
    75             // as second. So, the client should use the same http connection
       
    76             httpURIString = "http://127.0.0.1:" + httpPort + "/foo/";
    99             httpURIString = "http://127.0.0.1:" + httpPort + "/foo/";
    77             altURIString1 = "http://127.0.0.1:" + altPort + "/redir";
   100             httpURI = URI.create(httpURIString);
    78             altURIString2 = "http://127.0.0.1:" + altPort + "/redir/again";
   101             altURIString1 = "http://127.0.0.1:" + httpPort + "/redir";
    79 
   102             altURI1 = URI.create(altURIString1);
    80             httpServer.addHandler(new RedirectHandler(sup(altURIString1)), "/foo");
   103             altURIString2 = "http://127.0.0.1:" + httpPort + "/redir_again";
    81             altServer.addHandler(new RedirectHandler(sup(altURIString2)), "/redir");
   104             altURI2 = URI.create(altURIString2);
    82             altServer.addHandler(new Http2EchoHandler(), "/redir/again");
   105 
       
   106             Redirector r = new Redirector(sup(altURIString1, altURIString2));
       
   107             httpServer.addHandler(r, "/foo");
       
   108             httpServer.addHandler(r, "/redir");
       
   109             httpServer.addHandler(new Http2EchoHandler(), "/redir_again");
    83 
   110 
    84             httpServer.start();
   111             httpServer.start();
    85             altServer.start();
       
    86         } catch (Throwable e) {
   112         } catch (Throwable e) {
    87             System.err.println("Throwing now");
   113             System.err.println("Throwing now");
    88             e.printStackTrace();
   114             e.printStackTrace();
    89             throw e;
   115             throw e;
    90         }
   116         }
    91     }
   117     }
    92 
   118 
    93     @Test(timeOut=3000000)
   119     @Test
    94     public static void test() throws Exception {
   120     public static void test() throws Exception {
    95         try {
   121         try {
    96             initialize();
   122             initialize();
    97             simpleTest();
   123             simpleTest();
    98         } catch (Throwable tt) {
       
    99             System.err.println("tt caught");
       
   100             tt.printStackTrace();
       
   101         } finally {
   124         } finally {
   102             httpServer.stop();
   125             httpServer.stop();
   103             altServer.stop();
       
   104             exec.shutdownNow();
       
   105         }
   126         }
   106     }
   127     }
   107 
   128 
   108     static HttpClient getClient() {
   129     static HttpClient getClient() {
   109         if (client == null) {
   130         if (client == null) {
   110             exec = Executors.newCachedThreadPool();
       
   111             client = HttpClient.newBuilder()
   131             client = HttpClient.newBuilder()
   112                                .executor(exec)
       
   113                                .followRedirects(HttpClient.Redirect.ALWAYS)
   132                                .followRedirects(HttpClient.Redirect.ALWAYS)
   114                                .version(HTTP_2)
   133                                .version(HTTP_2)
   115                                .build();
   134                                .build();
   116         }
   135         }
   117         return client;
   136         return client;
   127                 expected, found);
   146                 expected, found);
   128             throw new RuntimeException("Test failed");
   147             throw new RuntimeException("Test failed");
   129         }
   148         }
   130     }
   149     }
   131 
   150 
       
   151     static void checkURIs(URI expected, URI found) throws Exception {
       
   152         System.out.printf ("Expected: %s, Found: %s\n", expected.toString(), found.toString());
       
   153         if (!expected.equals(found)) {
       
   154             System.err.printf ("Test failed: wrong URI %s/%s\n",
       
   155                 expected.toString(), found.toString());
       
   156             throw new RuntimeException("Test failed");
       
   157         }
       
   158     }
       
   159 
   132     static void checkStrings(String expected, String found) throws Exception {
   160     static void checkStrings(String expected, String found) throws Exception {
   133         if (!expected.equals(found)) {
   161         if (!expected.equals(found)) {
   134             System.err.printf ("Test failed: wrong string %s/%s\n",
   162             System.err.printf ("Test failed: wrong string %s/%s\n",
   135                 expected, found);
   163                 expected, found);
   136             throw new RuntimeException("Test failed");
   164             throw new RuntimeException("Test failed");
   137         }
   165         }
   138     }
   166     }
   139 
   167 
   140     static Void compareFiles(Path path1, Path path2) {
   168     static void check(boolean cond, Object... msg) {
   141         return TestUtil.compareFiles(path1, path2);
   169         if (cond)
   142     }
   170             return;
   143 
   171         StringBuilder sb = new StringBuilder();
   144     static Path tempFile() {
   172         for (Object o : msg)
   145         return TestUtil.tempFile();
   173             sb.append(o);
       
   174         throw new RuntimeException(sb.toString());
   146     }
   175     }
   147 
   176 
   148     static final String SIMPLE_STRING = "Hello world Goodbye world";
   177     static final String SIMPLE_STRING = "Hello world Goodbye world";
   149 
       
   150     static final int FILESIZE = 64 * 1024 + 200;
       
   151 
   178 
   152     static void simpleTest() throws Exception {
   179     static void simpleTest() throws Exception {
   153         URI uri = getURI();
   180         URI uri = getURI();
   154         System.err.println("Request to " + uri);
   181         System.err.println("Request to " + uri);
   155 
   182 
   161         HttpResponse<String> response = cf.join();
   188         HttpResponse<String> response = cf.join();
   162 
   189 
   163         checkStatus(200, response.statusCode());
   190         checkStatus(200, response.statusCode());
   164         String responseBody = response.body();
   191         String responseBody = response.body();
   165         checkStrings(SIMPLE_STRING, responseBody);
   192         checkStrings(SIMPLE_STRING, responseBody);
       
   193         checkURIs(response.uri(), altURI2);
       
   194 
       
   195         // check two previous responses
       
   196         HttpResponse<String> prev = response.previousResponse()
       
   197             .orElseThrow(() -> new RuntimeException("no previous response"));
       
   198         checkURIs(prev.uri(), altURI1);
       
   199 
       
   200         prev = prev.previousResponse()
       
   201             .orElseThrow(() -> new RuntimeException("no previous response"));
       
   202         checkURIs(prev.uri(), httpURI);
       
   203 
       
   204         checkPreviousRedirectResponses(req, response);
   166 
   205 
   167         System.err.println("DONE");
   206         System.err.println("DONE");
   168         Thread.sleep (6000);
   207     }
       
   208 
       
   209     static void checkPreviousRedirectResponses(HttpRequest initialRequest,
       
   210                                                HttpResponse<?> finalResponse) {
       
   211         // there must be at least one previous response
       
   212         finalResponse.previousResponse()
       
   213                 .orElseThrow(() -> new RuntimeException("no previous response"));
       
   214 
       
   215         HttpResponse<?> response = finalResponse;
       
   216         do {
       
   217             URI uri = response.uri();
       
   218             response = response.previousResponse().get();
       
   219             check(300 <= response.statusCode() && response.statusCode() <= 309,
       
   220                     "Expected 300 <= code <= 309, got:" + response.statusCode());
       
   221             check(response.body() == null, "Unexpected body: " + response.body());
       
   222             String locationHeader = response.headers().firstValue("Location")
       
   223                     .orElseThrow(() -> new RuntimeException("no previous Location"));
       
   224             check(uri.toString().endsWith(locationHeader),
       
   225                     "URI: " + uri + ", Location: " + locationHeader);
       
   226         } while (response.previousResponse().isPresent());
       
   227 
       
   228         // initial
       
   229         check(initialRequest.equals(response.request()),
       
   230                 "Expected initial request [%s] to equal last prev req [%s]",
       
   231                 initialRequest, response.request());
   169     }
   232     }
   170 }
   233 }