# HG changeset patch # User chegar # Date 1469182322 -3600 # Node ID 17e283ed590ddf80b42d0ca7ddb7dc2774c90a49 # Parent 8de55c86daa2e1e3db3040401c109f82cecf5cf8 8078568: java/net/URLPermission/URLTest.java fails intermittently with BindException Reviewed-by: dfuchs diff -r 8de55c86daa2 -r 17e283ed590d jdk/test/java/net/URLPermission/URLTest.java --- a/jdk/test/java/net/URLPermission/URLTest.java Fri Jul 22 13:31:58 2016 +0900 +++ b/jdk/test/java/net/URLPermission/URLTest.java Fri Jul 22 11:12:02 2016 +0100 @@ -23,167 +23,194 @@ import java.net.URLPermission; /* - * Run the tests once without security manager and once with - * * @test * @bug 8010464 * @modules jdk.httpserver - * @key intermittent * @library /lib/testlibrary/ * @build jdk.testlibrary.SimpleSSLContext - * @run main/othervm/java.security.policy=policy.1 URLTest one - * @run main/othervm URLTest one - * @run main/othervm/java.security.policy=policy.2 URLTest two - * @run main/othervm URLTest two - * @run main/othervm/java.security.policy=policy.3 URLTest three - * @run main/othervm URLTest three + * @run main/othervm URLTest + * @summary check URLPermission with Http(s)URLConnection */ import java.net.*; import java.io.*; -import java.util.*; +import java.security.*; import java.util.concurrent.*; -import java.util.logging.*; import com.sun.net.httpserver.*; import javax.net.ssl.*; import jdk.testlibrary.SimpleSSLContext; public class URLTest { - static boolean failed = false; + + static boolean failed; public static void main (String[] args) throws Exception { - boolean no = false, yes = true; - - if (System.getSecurityManager() == null) { - yes = false; - } createServers(); - InetSocketAddress addr1 = httpServer.getAddress(); - int port1 = addr1.getPort(); - InetSocketAddress addr2 = httpsServer.getAddress(); - int port2 = addr2.getPort(); - - // each of the following cases is run with a different policy file - switch (args[0]) { - case "one": - String url1 = "http://127.0.0.1:"+ port1 + "/foo.html"; - String url2 = "https://127.0.0.1:"+ port2 + "/foo.html"; - String url3 = "http://127.0.0.1:"+ port1 + "/bar.html"; - String url4 = "https://127.0.0.1:"+ port2 + "/bar.html"; - - // simple positive test. Should succceed - test(url1, "GET", "X-Foo", no); - test(url1, "GET", "Z-Bar", "X-Foo", no); - test(url1, "GET", "X-Foo", "Z-Bar", no); - test(url1, "GET", "Z-Bar", no); - test(url2, "POST", "X-Fob", no); - - // reverse the methods, should fail - test(url1, "POST", "X-Foo", yes); - test(url2, "GET", "X-Fob", yes); + try { + // Verify without a Security Manager + test1(); + test2(); + test3(); - // different URLs, should fail - test(url3, "GET", "X-Foo", yes); - test(url4, "POST", "X-Fob", yes); - break; - - case "two": - url1 = "http://127.0.0.1:"+ port1 + "/foo.html"; - url2 = "https://127.0.0.1:"+ port2 + "/foo.html"; - url3 = "http://127.0.0.1:"+ port1 + "/bar.html"; - url4 = "https://127.0.0.1:"+ port2 + "/bar.html"; + // Set the security manager. Each test will set its own policy. + Policy.setPolicy(new CustomPolicy()); + System.setSecurityManager(new SecurityManager()); + System.out.println("\n Security Manager has been set."); - // simple positive test. Should succceed - test(url1, "GET", "X-Foo", no); - test(url2, "POST", "X-Fob", no); - test(url3, "GET", "X-Foo", no); - test(url4, "POST", "X-Fob", no); - break; + test1(); + test2(); + test3(); - case "three": - url1 = "http://127.0.0.1:"+ port1 + "/foo.html"; - url2 = "https://127.0.0.1:"+ port2 + "/a/c/d/e/foo.html"; - url3 = "http://127.0.0.1:"+ port1 + "/a/b/c"; - url4 = "https://127.0.0.1:"+ port2 + "/a/b/c"; - - test(url1, "GET", "X-Foo", yes); - test(url2, "POST", "X-Zxc", no); - test(url3, "DELETE", "Y-Foo", no); - test(url4, "POST", "Y-Foo", yes); - break; - } - shutdown(); - if (failed) { - throw new RuntimeException("Test failed"); + if (failed) + throw new RuntimeException("Test failed"); + } finally { + shutdown(); } } - public static void test ( - String u, String method, - String header, boolean exceptionExpected - ) - throws Exception - { - test(u, method, header, null, exceptionExpected); + static void test1() throws IOException { + System.out.println("\n--- Test 1 ---"); + + boolean expectException = false; + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + expectException = true; + Policy.setPolicy(new CustomPolicy( + new URLPermission("http://127.0.0.1:"+httpPort+"/foo.html", "GET:X-Foo,Z-Bar"), + new URLPermission("https://127.0.0.1:"+httpsPort+"/foo.html", "POST:X-Fob,T-Bar"))); + } + + String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; + String url2 = "https://127.0.0.1:"+httpsPort+"/foo.html"; + String url3 = "http://127.0.0.1:"+httpPort+"/bar.html"; + String url4 = "https://127.0.0.1:"+httpsPort+"/bar.html"; + + // simple positive test. Should succeed + test(url1, "GET", "X-Foo"); + test(url1, "GET", "Z-Bar", "X-Foo"); + test(url1, "GET", "X-Foo", "Z-Bar"); + test(url1, "GET", "Z-Bar"); + test(url2, "POST", "X-Fob"); + + // reverse the methods, should fail + test(url1, "POST", "X-Foo", expectException); + test(url2, "GET", "X-Fob", expectException); + + // different URLs, should fail + test(url3, "GET", "X-Foo", expectException); + test(url4, "POST", "X-Fob", expectException); } - public static void test ( - String u, String method, - String header1, String header2, boolean exceptionExpected - ) - throws Exception + static void test2() throws IOException { + System.out.println("\n--- Test 2 ---"); + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + Policy.setPolicy(new CustomPolicy( + new URLPermission("http://127.0.0.1:"+httpPort+"/*", "GET:X-Foo"), + new URLPermission("https://127.0.0.1:"+httpsPort+"/*", "POST:X-Fob"))); + } + + String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; + String url2 = "https://127.0.0.1:"+httpsPort+"/foo.html"; + String url3 = "http://127.0.0.1:"+httpPort+"/bar.html"; + String url4 = "https://127.0.0.1:"+httpsPort+"/bar.html"; + + // simple positive test. Should succeed + test(url1, "GET", "X-Foo"); + test(url2, "POST", "X-Fob"); + test(url3, "GET", "X-Foo"); + test(url4, "POST", "X-Fob"); + } + + static void test3() throws IOException { + System.out.println("\n--- Test 3 ---"); + + boolean expectException = false; + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + expectException = true; + Policy.setPolicy(new CustomPolicy( + new URLPermission("http://127.0.0.1:"+httpPort+"/a/b/-", "DELETE,GET:X-Foo,Y-Foo"), + new URLPermission("https://127.0.0.1:"+httpsPort+"/a/c/-", "POST:*"))); + } + + String url1 = "http://127.0.0.1:"+httpPort+"/foo.html"; + String url2 = "https://127.0.0.1:"+httpsPort+"/a/c/d/e/foo.html"; + String url3 = "http://127.0.0.1:"+httpPort+"/a/b/c"; + String url4 = "https://127.0.0.1:"+httpsPort+"/a/b/c"; + + test(url1, "GET", "X-Foo", expectException); + test(url2, "POST", "X-Zxc"); + test(url3, "DELETE", "Y-Foo"); + test(url4, "POST", "Y-Foo", expectException); + } + + // Convenience methods to simplify previous explicit test scenarios. + static void test(String u, String method, String header) throws IOException { + test(u, method, header, null, false); + } + + static void test(String u, String method, String header, boolean expectException) + throws IOException + { + test(u, method, header, null, expectException); + } + + static void test(String u, String method, String header1, String header2) + throws IOException + { + test(u, method, header1, header2, false); + } + + static void test(String u, + String method, + String header1, + String header2, + boolean expectException) + throws IOException { URL url = new URL(u); - System.out.println ("url=" + u + " method="+method + " header1="+header1 - +" header2 = " + header2 - +" exceptionExpected="+exceptionExpected); + System.out.println("url=" + u + " method=" + method + + " header1=" + header1 + " header2=" + header2 + + " expectException=" + expectException); HttpURLConnection urlc = (HttpURLConnection)url.openConnection(); if (urlc instanceof HttpsURLConnection) { HttpsURLConnection ssl = (HttpsURLConnection)urlc; - ssl.setHostnameVerifier(new HostnameVerifier() { - public boolean verify(String host, SSLSession sess) { - return true; - } - }); - ssl.setSSLSocketFactory (ctx.getSocketFactory()); + ssl.setHostnameVerifier((host, sess) -> true); + ssl.setSSLSocketFactory(ctx.getSocketFactory()); } urlc.setRequestMethod(method); - if (header1 != null) { + if (header1 != null) urlc.addRequestProperty(header1, "foo"); - } - if (header2 != null) { + if (header2 != null) urlc.addRequestProperty(header2, "bar"); - } + try { - int g = urlc.getResponseCode(); - if (exceptionExpected) { + int code = urlc.getResponseCode(); + if (expectException) { failed = true; - System.out.println ("FAIL"); + System.out.println("FAIL"); return; } - if (g != 200) { - String s = Integer.toString(g); - throw new RuntimeException("unexpected response "+ s); - } + if (code != 200) + throw new RuntimeException("Unexpected response " + code); + InputStream is = urlc.getInputStream(); - int c,count=0; - byte[] buf = new byte[1024]; - while ((c=is.read(buf)) != -1) { - count += c; - } + is.readAllBytes(); is.close(); } catch (RuntimeException e) { - if (! (e instanceof SecurityException) && - !(e.getCause() instanceof SecurityException) || - !exceptionExpected) - { - System.out.println ("FAIL"); - //e.printStackTrace(); + if (!expectException || !(e.getCause() instanceof SecurityException)) { + System.out.println ("FAIL. Unexpected: " + e.getMessage()); + e.printStackTrace(); failed = true; + return; + } else { + System.out.println("Got expected exception: " + e.getMessage()); } } - System.out.println ("OK"); + System.out.println ("PASS"); } static HttpServer httpServer; @@ -191,33 +218,31 @@ static HttpContext c, cs; static ExecutorService e, es; static SSLContext ctx; - - // These ports need to be hard-coded until we support port number - // ranges in the permission class - - static final int PORT1 = 12567; - static final int PORT2 = 12568; + static int httpPort; + static int httpsPort; static void createServers() throws Exception { - InetSocketAddress addr1 = new InetSocketAddress (PORT1); - InetSocketAddress addr2 = new InetSocketAddress (PORT2); - httpServer = HttpServer.create (addr1, 0); - httpsServer = HttpsServer.create (addr2, 0); + InetSocketAddress any = new InetSocketAddress(0); + httpServer = HttpServer.create(any, 0); + httpsServer = HttpsServer.create(any, 0); - MyHandler h = new MyHandler(); + OkHandler h = new OkHandler(); - c = httpServer.createContext ("/", h); - cs = httpsServer.createContext ("/", h); + c = httpServer.createContext("/", h); + cs = httpsServer.createContext("/", h); e = Executors.newCachedThreadPool(); es = Executors.newCachedThreadPool(); - httpServer.setExecutor (e); - httpsServer.setExecutor (es); + httpServer.setExecutor(e); + httpsServer.setExecutor(es); ctx = new SimpleSSLContext().get(); httpsServer.setHttpsConfigurator(new HttpsConfigurator (ctx)); httpServer.start(); httpsServer.start(); + + httpPort = httpServer.getAddress().getPort(); + httpsPort = httpsServer.getAddress().getPort(); } static void shutdown() { @@ -227,15 +252,38 @@ es.shutdown(); } - static class MyHandler implements HttpHandler { - - MyHandler() { - } - + static class OkHandler implements HttpHandler { public void handle(HttpExchange x) throws IOException { x.sendResponseHeaders(200, -1); x.close(); } } + static class CustomPolicy extends Policy { + final PermissionCollection perms = new Permissions(); + CustomPolicy(Permission... permissions) { + java.util.Arrays.stream(permissions).forEach(perms::add); + + // needed for the HTTP(S) server + perms.add(new SocketPermission("localhost:1024-", "listen,resolve,accept")); + // needed by the test to reset the policy, per testX method + perms.add(new SecurityPermission("setPolicy")); + // needed to shutdown the ThreadPoolExecutor ( used by the servers ) + perms.add(new RuntimePermission("modifyThread")); + // needed by the client code forHttpsURLConnection.setSSLSocketFactory + perms.add(new RuntimePermission("setFactory")); + } + + public PermissionCollection getPermissions(ProtectionDomain domain) { + return perms; + } + + public PermissionCollection getPermissions(CodeSource codesource) { + return perms; + } + + public boolean implies(ProtectionDomain domain, Permission perm) { + return perms.implies(perm); + } + } } diff -r 8de55c86daa2 -r 17e283ed590d jdk/test/java/net/URLPermission/policy.1 --- a/jdk/test/java/net/URLPermission/policy.1 Fri Jul 22 13:31:58 2016 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -// -// Copyright (c) 2013, 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 -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// - -grant { - permission java.net.URLPermission "http://127.0.0.1:12567/foo.html", "GET:X-Foo,Z-Bar"; - permission java.net.URLPermission "https://127.0.0.1:12568/foo.html", "POST:X-Fob,T-Bar"; - - // needed for HttpServer - permission "java.net.SocketPermission" "localhost:1024-", "listen,resolve,accept"; - permission "java.util.PropertyPermission" "test.src", "read"; - permission java.io.FilePermission "${test.src}/../../../lib/testlibrary/jdk/testlibrary/testkeys", "read"; - - //permission "java.util.logging.LoggingPermission" "control"; - //permission "java.io.FilePermission" "/tmp/-", "read,write"; - permission "java.lang.RuntimePermission" "modifyThread"; - permission "java.lang.RuntimePermission" "setFactory"; - permission "java.util.PropertyPermission" "test.src.path", "read"; -}; - diff -r 8de55c86daa2 -r 17e283ed590d jdk/test/java/net/URLPermission/policy.2 --- a/jdk/test/java/net/URLPermission/policy.2 Fri Jul 22 13:31:58 2016 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -// -// Copyright (c) 2013, 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 -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// - -grant { - permission java.net.URLPermission "http://127.0.0.1:12567/*", "GET:X-Foo"; - permission java.net.URLPermission "https://127.0.0.1:12568/*", "POST:X-Fob"; - - // needed for HttpServer - permission "java.net.SocketPermission" "localhost:1024-", "listen,resolve,accept"; - permission "java.util.PropertyPermission" "test.src", "read"; - permission java.io.FilePermission "${test.src}/../../../lib/testlibrary/jdk/testlibrary/testkeys", "read"; - - //permission "java.util.logging.LoggingPermission" "control"; - //permission "java.io.FilePermission" "/tmp/-", "read,write"; - permission "java.lang.RuntimePermission" "modifyThread"; - permission "java.lang.RuntimePermission" "setFactory"; - permission "java.util.PropertyPermission" "test.src.path", "read"; -}; - diff -r 8de55c86daa2 -r 17e283ed590d jdk/test/java/net/URLPermission/policy.3 --- a/jdk/test/java/net/URLPermission/policy.3 Fri Jul 22 13:31:58 2016 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -// -// Copyright (c) 2013, 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 -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// - -grant { - permission java.net.URLPermission "http://127.0.0.1:12567/a/b/-", "DELETE,GET:X-Foo,Y-Foo"; - permission java.net.URLPermission "https://127.0.0.1:12568/a/c/-", "POST:*"; - - // needed for HttpServer - permission "java.net.SocketPermission" "localhost:1024-", "listen,resolve,accept"; - permission "java.util.PropertyPermission" "test.src", "read"; - permission java.io.FilePermission "${test.src}/../../../lib/testlibrary/jdk/testlibrary/testkeys", "read"; - - //permission "java.util.logging.LoggingPermission" "control"; - //permission "java.io.FilePermission" "/tmp/-", "read,write"; - permission "java.lang.RuntimePermission" "modifyThread"; - permission "java.lang.RuntimePermission" "setFactory"; - permission "java.util.PropertyPermission" "test.src.path", "read"; -};