http-client-branch: changed default protocol version when plain http over proxy requested. http-client-branch
authormichaelm
Mon, 29 Jan 2018 18:12:36 +0000
branchhttp-client-branch
changeset 56043 08e8e41841cf
parent 56042 40d7b06bb6e9
child 56044 a8423a38386e
http-client-branch: changed default protocol version when plain http over proxy requested.
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClient.java
src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/MultiExchange.java
test/jdk/java/net/httpclient/VersionTest.java
--- a/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClient.java	Mon Jan 29 15:18:25 2018 +0000
+++ b/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpClient.java	Mon Jan 29 18:12:36 2018 +0000
@@ -207,6 +207,10 @@
          * will use HTTP/2. If the upgrade fails, then the response will be
          * handled using HTTP/1.1
          *
+         * @implNote Constraints may also affect the selection of protocol version. 
+         * For example, if HTTP/2 is requested through a proxy, and if the implementation
+         * does not support this mode, then HTTP/1.1 may be used
+         *
          * @param version the requested HTTP protocol version
          * @return this builder
          */
@@ -328,9 +332,13 @@
     public abstract Optional<Authenticator> authenticator();
 
     /**
-     * Returns the HTTP protocol version requested for this client. The default
+     * Returns the preferred HTTP protocol version for this client. The default
      * value is {@link HttpClient.Version#HTTP_2}
      *
+     * @implNote Constraints may also affect the selection of protocol version. 
+     * For example, if HTTP/2 is requested through a proxy, and if the implementation
+     * does not support this mode, then HTTP/1.1 may be used
+     *
      * @return the HTTP protocol version requested
      */
     public abstract HttpClient.Version version();
--- a/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/MultiExchange.java	Mon Jan 29 15:18:25 2018 +0000
+++ b/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/MultiExchange.java	Mon Jan 29 18:12:36 2018 +0000
@@ -138,7 +138,10 @@
     }
 
     HttpClient.Version version() {
-        return request.version().orElse(client.version());
+        HttpClient.Version vers = request.version().orElse(client.version());
+        if (vers == HttpClient.Version.HTTP_2 && !request.secure() && request.proxy() != null)
+            vers = HttpClient.Version.HTTP_1_1;
+        return vers;
     }
 
     private synchronized void setExchange(Exchange<T> exchange) {
--- a/test/jdk/java/net/httpclient/VersionTest.java	Mon Jan 29 15:18:25 2018 +0000
+++ b/test/jdk/java/net/httpclient/VersionTest.java	Mon Jan 29 18:12:36 2018 +0000
@@ -25,6 +25,8 @@
  * @test
  * @bug 8175814
  * @modules jdk.incubator.httpclient java.logging jdk.httpserver
+ * @library /lib/testlibrary/ /
+ * @build ProxyServer
  * @run main/othervm -Djdk.httpclient.HttpClient.log=errors,requests,headers,trace VersionTest
  */
 
@@ -36,6 +38,8 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.URI;
+import java.net.InetSocketAddress;
+import java.net.ProxySelector;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
 import java.net.InetSocketAddress;
@@ -52,9 +56,11 @@
  */
 public class VersionTest {
     static HttpServer s1 ;
+    static ProxyServer proxy;
     static ExecutorService executor;
     static int port;
-    static HttpClient client;
+    static InetSocketAddress proxyAddr;
+    static HttpClient client, clientWithProxy;
     static URI uri;
     static volatile boolean error = false;
 
@@ -64,13 +70,20 @@
         client = HttpClient.newBuilder()
                            .executor(executor)
                            .build();
+
+        clientWithProxy = HttpClient.newBuilder()
+                           .executor(executor)
+                           .proxy(ProxySelector.of(proxyAddr))
+                           .build();
+
         // first check that the version is HTTP/2
         if (client.version() != HttpClient.Version.HTTP_2) {
             throw new RuntimeException("Default version not HTTP_2");
         }
         try {
-            test(HTTP_1_1);
-            test(HTTP_2);
+            test(HTTP_1_1, false);
+            test(HTTP_2, false);
+            test(HTTP_2, true);
         } finally {
             s1.stop(0);
             executor.shutdownNow();
@@ -79,12 +92,13 @@
             throw new RuntimeException();
     }
 
-    public static void test(HttpClient.Version version) throws Exception {
+    public static void test(HttpClient.Version version, boolean proxy) throws Exception {
         HttpRequest r = HttpRequest.newBuilder(uri)
                 .version(version)
                 .GET()
                 .build();
-        HttpResponse<Void> resp = client.send(r, discard(null));
+        HttpClient c = proxy ? clientWithProxy : client;
+        HttpResponse<Void> resp = c.send(r, discard(null));
         System.out.printf("Client: response is %d\n", resp.statusCode());
         if (resp.version() != HTTP_1_1) {
             throw new RuntimeException();
@@ -106,6 +120,9 @@
         port = s1.getAddress().getPort();
         uri = new URI("http://127.0.0.1:" + Integer.toString(port) + "/foo");
         System.out.println("HTTP server port = " + port);
+        proxy = new ProxyServer(0, false);
+        int proxyPort = proxy.getPort();
+        proxyAddr = new InetSocketAddress("127.0.0.1", proxyPort);
     }
 }
 
@@ -117,7 +134,10 @@
         if (counter == 1 && h.containsKey("Upgrade")) {
             VersionTest.error = true;
         }
-        if (counter > 1 && !h.containsKey("Upgrade")) {
+        if (counter == 2 && !h.containsKey("Upgrade")) {
+            VersionTest.error = true;
+        }
+        if (counter == 3 && h.containsKey("Upgrade")) {
             VersionTest.error = true;
         }
     }