http-client-branch: (merge) http-client-branch
authorprappo
Mon, 12 Mar 2018 11:36:51 +0000
branchhttp-client-branch
changeset 56292 b96b5cbb018d
parent 56291 c8c4c707ff3a (current diff)
parent 56275 19e3bbc3e471 (diff)
child 56293 7e21161251dc
http-client-branch: (merge)
--- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java	Fri Mar 09 19:10:01 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java	Mon Mar 12 11:36:51 2018 +0000
@@ -489,15 +489,15 @@
         // To avoid misuse of the property, the delay that can be specified
         // is comprised between [MIN_NODEADLINE, MAX_NODEADLINE], and its default
         // value if unspecified (or <= 0) is DEF_NODEADLINE = 3000ms
-        // The property is -Djdk.httpclient.internal.selector.timeout=<millis>
+        // The property is -Djdk.internal.httpclient.selectorTimeout=<millis>
         private static final int MIN_NODEADLINE = 1000; // ms
         private static final int MAX_NODEADLINE = 1000 * 1200; // ms
         private static final int DEF_NODEADLINE = 3000; // ms
         private static final long NODEADLINE; // default is DEF_NODEADLINE ms
         static {
             // ensure NODEADLINE is initialized with some valid value.
-            long deadline =  Utils.getIntegerNetProperty(
-                "jdk.httpclient.internal.selector.timeout",
+            long deadline =  Utils.getIntegerProperty(
+                "jdk.internal.httpclient.selectorTimeout",
                 DEF_NODEADLINE); // millis
             if (deadline <= 0) deadline = DEF_NODEADLINE;
             deadline = Math.max(deadline, MIN_NODEADLINE);
--- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java	Fri Mar 09 19:10:01 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java	Mon Mar 12 11:36:51 2018 +0000
@@ -90,7 +90,14 @@
     public static final boolean TESTING = DEBUG;
 
     public static final boolean isHostnameVerificationDisabled = // enabled by default
-        getBooleanProperty("jdk.internal.http.disableHostnameVerification", false);
+            hostnameVerificationDisabledValue();
+
+    private static boolean hostnameVerificationDisabledValue() {
+        String prop = getProperty("jdk.internal.httpclient.disableHostnameVerification");
+        if (prop == null)
+            return false;
+        return prop.isEmpty() ?  true : Boolean.parseBoolean(prop);
+    }
 
     /**
      * Allocated buffer size. Must never be higher than 16K. But can be lower
@@ -383,6 +390,16 @@
                 Boolean.parseBoolean(System.getProperty(name, String.valueOf(def))));
     }
 
+    public static String getProperty(String name) {
+        return AccessController.doPrivileged((PrivilegedAction<String>) () ->
+                System.getProperty(name));
+    }
+
+    public static int getIntegerProperty(String name, int defaultValue) {
+        return AccessController.doPrivileged((PrivilegedAction<Integer>) () ->
+                Integer.parseInt(System.getProperty(name, String.valueOf(defaultValue))));
+    }
+
     public static SSLParameters copySSLParameters(SSLParameters p) {
         SSLParameters p1 = new SSLParameters();
         p1.setAlgorithmConstraints(p.getAlgorithmConstraints());
--- a/test/jdk/java/net/httpclient/AsFileDownloadTest.java	Fri Mar 09 19:10:01 2018 +0000
+++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.java	Mon Mar 12 11:36:51 2018 +0000
@@ -208,6 +208,9 @@
             { "111", "attachment; filename=\"bad;"         },  // badly quoted with ';'
             { "112", "attachment; filename=\"bad ;"        },  // badly quoted with ' ;'
             { "113", "attachment; filename*=utf-8''xx.txt "},  // no "filename" param
+
+            { "120", "<<NOT_PRESENT>>"                     },  // header not present
+
     };
 
     @DataProvider(name = "negative")
@@ -343,8 +346,9 @@
                  OutputStream os = t.getResponseBody()) {
                 byte[] bytes = is.readAllBytes();
 
-                t.getResponseHeaders().set("Content-Disposition",
-                        contentDispositionValueFromURI(t.getRequestURI()));
+                String value = contentDispositionValueFromURI(t.getRequestURI());
+                if (!value.equals("<<NOT_PRESENT>>"))
+                    t.getResponseHeaders().set("Content-Disposition", value);
 
                 t.sendResponseHeaders(200, bytes.length);
                 os.write(bytes);
@@ -359,8 +363,9 @@
                  OutputStream os = t.getResponseBody()) {
                 byte[] bytes = is.readAllBytes();
 
-                t.getResponseHeaders().addHeader("Content-Disposition",
-                        contentDispositionValueFromURI(t.getRequestURI()));
+                String value = contentDispositionValueFromURI(t.getRequestURI());
+                if (!value.equals("<<NOT_PRESENT>>"))
+                    t.getResponseHeaders().addHeader("Content-Disposition", value);
 
                 t.sendResponseHeaders(200, bytes.length);
                 os.write(bytes);
--- a/test/jdk/java/net/httpclient/HttpClientBuilderTest.java	Fri Mar 09 19:10:01 2018 +0000
+++ b/test/jdk/java/net/httpclient/HttpClientBuilderTest.java	Mon Mar 12 11:36:51 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import java.io.IOException;
 import java.lang.reflect.Method;
 import java.net.Authenticator;
 import java.net.CookieHandler;
@@ -31,12 +32,16 @@
 import java.net.http.HttpHeaders;
 import java.net.http.HttpRequest;
 import java.net.http.HttpRequest.BodyPublishers;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandler;
 import java.net.http.HttpResponse.BodyHandlers;
+import java.net.http.HttpResponse.PushPromiseHandler;
 import java.time.Duration;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.TreeMap;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLParameters;
@@ -236,6 +241,8 @@
         builder.build();
     }
 
+    // ---
+
     static final URI uri = URI.create("http://foo.com/");
 
     @Test
@@ -282,6 +289,42 @@
         }
     }
 
+    // ---
+
+    static final Class<UnsupportedOperationException> UOE =
+            UnsupportedOperationException.class;
+
+    @Test
+    static void testUnsupportedWebSocket() throws Exception {
+        //  @implSpec The default implementation of this method throws
+        // {@code UnsupportedOperationException}.
+        assertThrows(UOE, () -> (new MockHttpClient()).newWebSocketBuilder());
+    }
+
+    static class MockHttpClient extends HttpClient {
+        @Override public Optional<CookieHandler> cookieHandler() { return null; }
+        @Override public Redirect followRedirects() { return null; }
+        @Override public Optional<ProxySelector> proxy() { return null; }
+        @Override public SSLContext sslContext() { return null; }
+        @Override public SSLParameters sslParameters() { return null; }
+        @Override public Optional<Authenticator> authenticator() { return null; }
+        @Override public Version version() { return null; }
+        @Override public Optional<Executor> executor() { return null; }
+        @Override public <T> HttpResponse<T>
+        send(HttpRequest request, BodyHandler<T> responseBodyHandler)
+                throws IOException, InterruptedException {
+            return null;
+        }
+        @Override public <T> CompletableFuture<HttpResponse<T>>
+        sendAsync(HttpRequest request, BodyHandler<T> responseBodyHandler) {
+            return null;
+        }
+        @Override
+        public <T> CompletableFuture<HttpResponse<T>>
+        sendAsync(HttpRequest x, BodyHandler<T> y, PushPromiseHandler<T> z) {
+            return null;
+        }
+    }
 
     /* ---- standalone entry point ---- */
 
--- a/test/jdk/java/net/httpclient/SmallTimeout.java	Fri Mar 09 19:10:01 2018 +0000
+++ b/test/jdk/java/net/httpclient/SmallTimeout.java	Mon Mar 12 11:36:51 2018 +0000
@@ -42,7 +42,7 @@
  * @test
  * @bug 8178147
  * @summary Ensures that small timeouts do not cause hangs due to race conditions
- * @run main/othervm -Djdk.internal.net.http.common.DEBUG=true SmallTimeout
+ * @run main/othervm -Djdk.internal.httpclient.debug=true SmallTimeout
  */
 
 // To enable logging use. Not enabled by default as it changes the dynamics
--- a/test/jdk/java/net/httpclient/ThrowingSubscribers.java	Fri Mar 09 19:10:01 2018 +0000
+++ b/test/jdk/java/net/httpclient/ThrowingSubscribers.java	Mon Mar 12 11:36:51 2018 +0000
@@ -180,16 +180,13 @@
     public Object[][] noThrows() {
         String[] uris = uris();
         Object[][] result = new Object[uris.length * 2][];
-        //Object[][] result = new Object[uris.length][];
         int i = 0;
         for (boolean sameClient : List.of(false, true)) {
-            //if (!sameClient) continue;
             for (String uri: uris()) {
                 result[i++] = new Object[] {uri, sameClient};
             }
         }
         assert i == uris.length * 2;
-        // assert i == uris.length ;
         return result;
     }
 
@@ -197,21 +194,17 @@
     public Object[][] variants() {
         String[] uris = uris();
         Object[][] result = new Object[uris.length * 2 * 2][];
-        //Object[][] result = new Object[(uris.length/2) * 2 * 2][];
         int i = 0;
         for (Thrower thrower : List.of(
                 new UncheckedIOExceptionThrower(),
                 new UncheckedCustomExceptionThrower())) {
             for (boolean sameClient : List.of(false, true)) {
                 for (String uri : uris()) {
-                    // if (uri.contains("http2") || uri.contains("https2")) continue;
-                    // if (!sameClient) continue;
                     result[i++] = new Object[]{uri, sameClient, thrower};
                 }
             }
         }
         assert i == uris.length * 2 * 2;
-        //assert Stream.of(result).filter(o -> o != null).count() == result.length;
         return result;
     }
 
@@ -367,7 +360,7 @@
                     response = client.sendAsync(req, handler).join();
                 } catch (Error | Exception x) {
                     Throwable cause = findCause(x, thrower);
-                    if (cause == null) throw x;
+                    if (cause == null) throw causeNotFound(where, x);
                     System.out.println(now() + "Got expected exception: " + cause);
                 }
             } else {
@@ -376,7 +369,7 @@
                 } catch (Error | Exception t) {
                     if (thrower.test(t)) {
                         System.out.println(now() + "Got expected exception: " + t);
-                    } else throw t;
+                    } else throw causeNotFound(where, t);
                 }
             }
             if (response != null) {
@@ -399,6 +392,10 @@
         }
     }
 
+    static AssertionError causeNotFound(Where w, Throwable t) {
+        return new AssertionError("Expected exception not found in " + w, t);
+    }
+
     interface Thrower extends Consumer<Where>, Predicate<Throwable> {
 
     }
@@ -408,7 +405,11 @@
     }
 
     final <T,U> U shouldHaveThrown(Where w, HttpResponse<T> resp, Thrower thrower) {
-        throw new RuntimeException("Expected exception not thrown in " + w);
+        String msg = "Expected exception not thrown in " + w
+                + "\n\tReceived: " + resp
+                + "\n\tWith body: " + resp.body();
+        System.out.println(msg);
+        throw new RuntimeException(msg);
     }
 
     final List<String> checkAsLines(Where w, HttpResponse<Stream<String>> resp, Thrower thrower) {
@@ -428,7 +429,7 @@
                 out.println(now() + "Got expected exception in " + w + ": " + cause);
                 return result;
             }
-            throw x;
+            throw causeNotFound(w, x);
         }
         throw new RuntimeException("Expected exception not thrown in " + w);
     }
@@ -455,7 +456,7 @@
                     out.println(now() + "Got expected exception in " + w + ": " + cause);
                     return result;
                 }
-                throw x;
+                throw causeNotFound(w, x);
             }
         }
         return shouldHaveThrown(w, resp, thrower);
--- a/test/jdk/java/net/httpclient/ssltest/CertificateTest.java	Fri Mar 09 19:10:01 2018 +0000
+++ b/test/jdk/java/net/httpclient/ssltest/CertificateTest.java	Mon Mar 12 11:36:51 2018 +0000
@@ -21,25 +21,37 @@
  * questions.
  */
 
+import java.io.File;
 import java.net.URI;
 import java.net.http.HttpClient;
-import java.net.http.HttpClient.Version;
-import java.net.http.HttpResponse.BodyHandler;
-import static java.net.http.HttpResponse.BodyHandlers.ofString;
+import java.net.http.HttpResponse.BodyHandlers;
 import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLParameters;
 
 /*
  * @test
  * @build Server CertificateTest
- * @run main/othervm CertificateTest good
- * @run main/othervm CertificateTest bad
+ * @run main/othervm CertificateTest good.keystore expectSuccess
+ * @run main/othervm CertificateTest bad.keystore expectFailure
+ * @run main/othervm
+ *      -Djdk.internal.httpclient.disableHostnameVerification
+ *       CertificateTest bad.keystore expectSuccess
+ * @run main/othervm
+ *      -Djdk.internal.httpclient.disableHostnameVerification=true
+ *       CertificateTest bad.keystore expectSuccess
+ * @run main/othervm
+ *      -Djdk.internal.httpclient.disableHostnameVerification=false
+ *       CertificateTest bad.keystore expectFailure
+ * @run main/othervm
+ *      -Djdk.internal.httpclient.disableHostnameVerification=xxyyzz
+ *       CertificateTest bad.keystore expectFailure
  */
 
 /**
- * The test runs twice. In both cases it uses a valid self-signed certificate
+ * The test runs a number of times. In all cases it uses a valid self-signed certificate
  * that is installed in the trust store (so is trusted) and the same cert is supplied
  * by the server for its own identity. Two servers on two different ports are used
  * on the remote end.
@@ -51,9 +63,8 @@
 public class CertificateTest {
     static SSLContext ctx;
     static SSLParameters params;
-    static boolean good;
+    static boolean expectSuccess;
     static String trustStoreProp;
-    static String suffix;
     static Server server;
     static int port;
 
@@ -61,12 +72,15 @@
     public static void main(String[] args) throws Exception
     {
         try {
-            if (args[0].equals("good")) {
-                good = true;
-                trustStoreProp = TESTSRC + "/good.keystore";
+            String keystore = args[0];
+            trustStoreProp = TESTSRC + File.separatorChar + keystore;
+
+            String passOrFail = args[1];
+
+            if (passOrFail.equals("expectSuccess")) {
+                expectSuccess = true;
             } else {
-                good = false;
-                trustStoreProp = TESTSRC + "/bad.keystore";
+                expectSuccess = false;
             }
             server = new Server(trustStoreProp);
             port = server.getPort();
@@ -103,17 +117,17 @@
                 .build();
 
         try {
-            HttpResponse<String> response = client.send(request, ofString());
+            HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
             System.out.printf("Status code %d received\n", response.statusCode());
-            if (good && response.statusCode() != 200)
+            if (expectSuccess && response.statusCode() != 200)
                 error = "Test failed: good: status should be 200";
-            else if (!good)
+            else if (!expectSuccess)
                 error = "Test failed: bad: status should not be 200";
-        } catch (Exception e) {
-            System.err.println("Exception good = " + good);
+        } catch (SSLException e) {
+            System.err.println("Caught Exception " + e + ". expectSuccess = " + expectSuccess);
             exception = e;
-            if (good)
-                error = "Test failed: good: got exception";
+            if (expectSuccess)
+                error = "Test failed: expectSuccess:true, but got unexpected exception";
         }
         if (error != null)
             throw new RuntimeException(error, exception);