1 /* 2 * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 /* 24 * @test 25 * @bug 8035158 26 * @run main/othervm B8035158 27 */ 28 29 import java.net.Proxy; 30 import java.net.ProxySelector; 31 import java.net.URI; 32 import java.util.*; 33 import java.util.concurrent.Callable; 34 35 public class B8035158 { 36 37 public static void main(String[] args) { 38 for (TestCase t : emptyNonProxiesHosts()) t.run(); 39 for (TestCase t : nonEmptyNonProxiesHosts()) t.run(); 40 for (TestCase t : misc()) t.run(); 41 } 42 43 // Setting http.nonProxyHosts to an empty string has an effect of 44 // not including default hosts to the list of exceptions 45 // (i.e. if you want everything to be connected directly rather than 46 // through proxy, you should set this property to an empty string) 47 private static Collection<TestCase> emptyNonProxiesHosts() { 48 List<TestCase> tests = new LinkedList<>(); 49 String[] loopbacks = {"localhost", "[::1]", "[::0]", "0.0.0.0", 50 "127.0.0.0", "127.0.0.1", "127.0.1.0", "127.0.1.1", 51 "127.1.0.0", "127.1.0.1", "127.1.1.0", "127.1.1.1"}; 52 Map<String, String> properties = new HashMap<>(); 53 properties.put("http.proxyHost", "http://proxy.example.com"); 54 properties.put("http.nonProxyHosts", ""); 55 for (String s : loopbacks) { 56 tests.add(new TestCase(properties, "http://" + s, true)); 57 } 58 return tests; 59 } 60 61 // No matter what is set into the http.nonProxyHosts (as far as it is not 62 // an empty string) loopback address aliases must be always connected 63 // directly 64 private static Collection<TestCase> nonEmptyNonProxiesHosts() { 65 List<TestCase> tests = new LinkedList<>(); 66 String[] nonProxyHosts = { 67 "google.com", 68 "localhost", "[::1]", "[::0]", "0.0.0.0", 69 "127.0.0.0", "127.0.0.1", "127.0.1.0", "127.0.1.1", 70 "127.1.0.0", "127.1.0.1", "127.1.1.0", "127.1.1.1"}; 71 String[] loopbacks = {"localhost", "[::1]", "[::0]", "0.0.0.0", 72 "127.0.0.0", "127.0.0.1", "127.0.1.0", "127.0.1.1", 73 "127.1.0.0", "127.1.0.1", "127.1.1.0", "127.1.1.1"}; 74 for (String h : nonProxyHosts) { 75 for (String s : loopbacks) { 76 Map<String, String> properties = new HashMap<>(); 77 properties.put("http.proxyHost", "http://proxy.example.com"); 78 properties.put("http.nonProxyHosts", h); 79 tests.add(new TestCase(properties, "http://" + s, false)); 80 } 81 } 82 return tests; 83 } 84 85 // unsorted tests 86 private static Collection<TestCase> misc() { 87 List<TestCase> t = new LinkedList<>(); 88 t.add(new TestCase("oracle.com", "http://137.254.16.101", true)); 89 t.add(new TestCase("google.com", "http://74.125.200.101", true)); 90 91 t.add(new TestCase("google.com|google.ie", "http://google.co.uk", 92 true)); 93 t.add(new TestCase("google.com|google.ie", "http://google.com", 94 false)); 95 t.add(new TestCase("google.com|google.ie", "http://google.ie", 96 false)); 97 98 t.add(new TestCase("google.com|bing.com|yahoo.com", 99 "http://127.0.0.1", false)); 100 t.add(new TestCase("google.com|bing.com|yahoo.com", 101 "http://google.com", false)); 102 t.add(new TestCase("google.com|bing.com|yahoo.com", 103 "http://bing.com", false)); 104 t.add(new TestCase("google.com|bing.com|yahoo.com", 105 "http://yahoo.com", false)); 106 107 t.add(new TestCase("google.com|bing.com", "http://google.com", false)); 108 t.add(new TestCase("google.com|bing.com", "http://bing.com", false)); 109 t.add(new TestCase("google.com|bing.com", "http://yahoo.com", 110 true)); 111 t.add(new TestCase("google.com|bing.co*", "http://google.com", false)); 112 t.add(new TestCase("google.com|bing.co*", "http://bing.com", false)); 113 t.add(new TestCase("google.com|bing.co*", "http://yahoo.com", 114 true)); 115 t.add(new TestCase("google.com|*ing.com", "http://google.com", false)); 116 t.add(new TestCase("google.com|*ing.com", "http://bing.com", false)); 117 t.add(new TestCase("google.com|*ing.com", "http://yahoo.com", 118 true)); 119 t.add(new TestCase("google.co*|bing.com", "http://google.com", false)); 120 t.add(new TestCase("google.co*|bing.com", "http://bing.com", false)); 121 t.add(new TestCase("google.co*|bing.com", "http://yahoo.com", 122 true)); 123 t.add(new TestCase("google.co*|bing.co*", "http://google.com", false)); 124 t.add(new TestCase("google.co*|bing.co*", "http://bing.com", false)); 125 t.add(new TestCase("google.co*|bing.co*", "http://yahoo.com", 126 true)); 127 t.add(new TestCase("google.co*|*ing.com", "http://google.com", false)); 128 t.add(new TestCase("google.co*|*ing.com", "http://bing.com", false)); 129 t.add(new TestCase("google.co*|*ing.com", "http://yahoo.com", 130 true)); 131 t.add(new TestCase("*oogle.com|bing.com", "http://google.com", false)); 132 t.add(new TestCase("*oogle.com|bing.com", "http://bing.com", false)); 133 t.add(new TestCase("*oogle.com|bing.com", "http://yahoo.com", 134 true)); 135 t.add(new TestCase("*oogle.com|bing.co*", "http://google.com", false)); 136 t.add(new TestCase("*oogle.com|bing.co*", "http://bing.com", false)); 137 t.add(new TestCase("*oogle.com|bing.co*", "http://yahoo.com", 138 true)); 139 t.add(new TestCase("*oogle.com|*ing.com", "http://google.com", false)); 140 t.add(new TestCase("*oogle.com|*ing.com", "http://bing.com", false)); 141 t.add(new TestCase("*oogle.com|*ing.com", "http://yahoo.com", 142 true)); 143 144 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://google.com", false)); 145 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://bing.com", false)); 146 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://yahoo.com", false)); 147 t.add(new TestCase("google.com|bing.com|yahoo.com", 148 "http://duckduckgo.com", true)); 149 150 t.add(new TestCase("p-proxy.com", "http://p-proxy.com", false)); 151 t.add(new TestCase("google.co*|google.ie", "http://google.co.uk", 152 false)); 153 154 t.add(new TestCase("*oracle.com", "http://my.oracle.com", false)); 155 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://127.0.0.1", false)); 156 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://yahoo.com", false)); 157 158 // example from 159 // http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html 160 t.add(new TestCase("localhost|host.example.com", "http://localhost", 161 false)); 162 t.add(new TestCase("localhost|host.example.com", 163 "http://host.example.com", false)); 164 t.add(new TestCase("localhost|host.example.com", 165 "http://google.com", true)); 166 return t; 167 } 168 169 170 private static <T> T withSystemPropertiesSet( 171 Map<String, String> localProperties, 172 Callable<? extends T> code) { 173 Map<String, String> backup = new HashMap<>(); 174 try { 175 backupAndSetProperties(localProperties, backup); 176 return code.call(); 177 } catch (Exception e) { 178 throw new RuntimeException(e); 179 } finally { 180 restoreProperties(backup); 181 } 182 } 183 184 private static void backupAndSetProperties( 185 Map<String, String> localProperties, 186 Map<String, String> oldProperties) { 187 for (Map.Entry<String, String> e : localProperties.entrySet()) { 188 String oldValue = System.setProperty(e.getKey(), e.getValue()); 189 oldProperties.put(e.getKey(), oldValue); 190 } 191 } 192 193 private static void restoreProperties(Map<String, String> oldProperties) { 194 for (Map.Entry<String, String> e : oldProperties.entrySet()) { 195 String oldValue = e.getValue(); 196 String key = e.getKey(); 197 if (oldValue == null) 198 System.getProperties().remove(key); 199 else 200 System.setProperty(key, oldValue); 201 } 202 } 203 204 private static class TestCase { 205 206 final Map<String, String> localProperties; 207 final String urlhost; 208 final boolean expectedProxying; 209 210 TestCase(String nonProxyHosts, String urlhost, 211 boolean expectedProxying) { 212 this(nonProxyHosts, "proxy.example.com", urlhost, 213 expectedProxying); 214 } 215 216 TestCase(String nonProxyHosts, String proxyHost, String urlhost, 217 boolean expectedProxying) { 218 this(new HashMap<String, String>() { 219 { 220 put("http.nonProxyHosts", nonProxyHosts); 221 put("http.proxyHost", proxyHost); 222 } 223 }, urlhost, expectedProxying); 224 } 225 226 TestCase(Map<String, String> localProperties, String urlhost, 227 boolean expectedProxying) { 228 this.localProperties = localProperties; 229 this.urlhost = urlhost; 230 this.expectedProxying = expectedProxying; 231 } 232 233 void run() { 234 System.out.printf("urlhost=%s properties=%s: proxied? %s%n", 235 urlhost, localProperties, expectedProxying); 236 237 List<Proxy> proxies = withSystemPropertiesSet(localProperties, 238 () -> ProxySelector.getDefault().select( 239 URI.create(urlhost)) 240 ); 241 242 verify(proxies); 243 } 244 245 void verify(List<? extends Proxy> proxies) { 246 247 boolean actualProxying = !(proxies.size() == 1 && 248 proxies.get(0).type() == Proxy.Type.DIRECT); 249 250 if (actualProxying != expectedProxying) 251 throw new AssertionError(String.format( 252 "Expected %s connection for %s (given " + 253 "properties=%s). Here's the list of proxies " + 254 "returned: %s", 255 expectedProxying ? "proxied" : "direct", urlhost, 256 localProperties, proxies 257 )); 258 } 259 } 260 }