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 /* 25 * @test 26 * @bug 8035158 27 * @run main/othervm B8035158 28 */ 29 30 import java.net.Proxy; 31 import java.net.ProxySelector; 32 import java.net.URI; 33 import java.util.*; 34 import java.util.concurrent.Callable; 35 36 public class B8035158 { 37 38 public static void main(String[] args) { 39 for (TestCase t : emptyNonProxiesHosts()) t.run(); 40 for (TestCase t : nonEmptyNonProxiesHosts()) t.run(); 41 for (TestCase t : misc()) t.run(); 42 } 43 44 // Setting http.nonProxyHosts to an empty string has an effect of 45 // not including default hosts to the list of exceptions 46 // (i.e. if you want everything to be connected directly rather than 47 // through proxy, you should set this property to an empty string) 48 private static Collection<TestCase> emptyNonProxiesHosts() { 49 List<TestCase> tests = new LinkedList<>(); 50 String[] loopbacks = {"localhost", "[::1]", "[::0]", "0.0.0.0", 51 "127.0.0.0", "127.0.0.1", "127.0.1.0", "127.0.1.1", 52 "127.1.0.0", "127.1.0.1", "127.1.1.0", "127.1.1.1"}; 53 Map<String, String> properties = new HashMap<>(); 54 properties.put("http.proxyHost", "http://proxy.example.com"); 55 properties.put("http.nonProxyHosts", ""); 56 for (String s : loopbacks) { 57 tests.add(new TestCase(properties, "http://" + s, true)); 58 } 59 return tests; 60 } 61 62 // No matter what is set into the http.nonProxyHosts (as far as it is not 63 // an empty string) loopback address aliases must be always connected 64 // directly 65 private static Collection<TestCase> nonEmptyNonProxiesHosts() { 66 List<TestCase> tests = new LinkedList<>(); 67 String[] nonProxyHosts = { 68 "google.com", 69 "localhost", "[::1]", "[::0]", "0.0.0.0", 70 "127.0.0.0", "127.0.0.1", "127.0.1.0", "127.0.1.1", 71 "127.1.0.0", "127.1.0.1", "127.1.1.0", "127.1.1.1"}; 72 String[] loopbacks = {"localhost", "[::1]", "[::0]", "0.0.0.0", 73 "127.0.0.0", "127.0.0.1", "127.0.1.0", "127.0.1.1", 74 "127.1.0.0", "127.1.0.1", "127.1.1.0", "127.1.1.1"}; 75 for (String h : nonProxyHosts) { 76 for (String s : loopbacks) { 77 Map<String, String> properties = new HashMap<>(); 78 properties.put("http.proxyHost", "http://proxy.example.com"); 79 properties.put("http.nonProxyHosts", h); 80 tests.add(new TestCase(properties, "http://" + s, false)); 81 } 82 } 83 return tests; 84 } 85 86 // unsorted tests 87 private static Collection<TestCase> misc() { 88 List<TestCase> t = new LinkedList<>(); 89 t.add(new TestCase("oracle.com", "http://137.254.16.101", true)); 90 t.add(new TestCase("google.com", "http://74.125.200.101", true)); 91 92 t.add(new TestCase("google.com|google.ie", "http://google.co.uk", 93 true)); 94 t.add(new TestCase("google.com|google.ie", "http://google.com", 95 false)); 96 t.add(new TestCase("google.com|google.ie", "http://google.ie", 97 false)); 98 99 t.add(new TestCase("google.com|bing.com|yahoo.com", 100 "http://127.0.0.1", false)); 101 t.add(new TestCase("google.com|bing.com|yahoo.com", 102 "http://google.com", false)); 103 t.add(new TestCase("google.com|bing.com|yahoo.com", 104 "http://bing.com", false)); 105 t.add(new TestCase("google.com|bing.com|yahoo.com", 106 "http://yahoo.com", false)); 107 108 t.add(new TestCase("google.com|bing.com", "http://google.com", false)); 109 t.add(new TestCase("google.com|bing.com", "http://bing.com", false)); 110 t.add(new TestCase("google.com|bing.com", "http://yahoo.com", 111 true)); 112 t.add(new TestCase("google.com|bing.co*", "http://google.com", false)); 113 t.add(new TestCase("google.com|bing.co*", "http://bing.com", false)); 114 t.add(new TestCase("google.com|bing.co*", "http://yahoo.com", 115 true)); 116 t.add(new TestCase("google.com|*ing.com", "http://google.com", false)); 117 t.add(new TestCase("google.com|*ing.com", "http://bing.com", false)); 118 t.add(new TestCase("google.com|*ing.com", "http://yahoo.com", 119 true)); 120 t.add(new TestCase("google.co*|bing.com", "http://google.com", false)); 121 t.add(new TestCase("google.co*|bing.com", "http://bing.com", false)); 122 t.add(new TestCase("google.co*|bing.com", "http://yahoo.com", 123 true)); 124 t.add(new TestCase("google.co*|bing.co*", "http://google.com", false)); 125 t.add(new TestCase("google.co*|bing.co*", "http://bing.com", false)); 126 t.add(new TestCase("google.co*|bing.co*", "http://yahoo.com", 127 true)); 128 t.add(new TestCase("google.co*|*ing.com", "http://google.com", false)); 129 t.add(new TestCase("google.co*|*ing.com", "http://bing.com", false)); 130 t.add(new TestCase("google.co*|*ing.com", "http://yahoo.com", 131 true)); 132 t.add(new TestCase("*oogle.com|bing.com", "http://google.com", false)); 133 t.add(new TestCase("*oogle.com|bing.com", "http://bing.com", false)); 134 t.add(new TestCase("*oogle.com|bing.com", "http://yahoo.com", 135 true)); 136 t.add(new TestCase("*oogle.com|bing.co*", "http://google.com", false)); 137 t.add(new TestCase("*oogle.com|bing.co*", "http://bing.com", false)); 138 t.add(new TestCase("*oogle.com|bing.co*", "http://yahoo.com", 139 true)); 140 t.add(new TestCase("*oogle.com|*ing.com", "http://google.com", false)); 141 t.add(new TestCase("*oogle.com|*ing.com", "http://bing.com", false)); 142 t.add(new TestCase("*oogle.com|*ing.com", "http://yahoo.com", 143 true)); 144 145 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://google.com", false)); 146 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://bing.com", false)); 147 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://yahoo.com", false)); 148 t.add(new TestCase("google.com|bing.com|yahoo.com", 149 "http://duckduckgo.com", true)); 150 151 t.add(new TestCase("p-proxy.com", "http://p-proxy.com", false)); 152 t.add(new TestCase("google.co*|google.ie", "http://google.co.uk", 153 false)); 154 155 t.add(new TestCase("*oracle.com", "http://my.oracle.com", false)); 156 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://127.0.0.1", false)); 157 t.add(new TestCase("google.com|bing.com|yahoo.com", "http://yahoo.com", false)); 158 159 // example from 160 // http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html 161 t.add(new TestCase("localhost|host.example.com", "http://localhost", 162 false)); 163 t.add(new TestCase("localhost|host.example.com", 164 "http://host.example.com", false)); 165 t.add(new TestCase("localhost|host.example.com", 166 "http://google.com", true)); 167 return t; 168 } 169 170 171 private static <T> T withSystemPropertiesSet( 172 Map<String, String> localProperties, 173 Callable<? extends T> code) { 174 Map<String, String> backup = new HashMap<>(); 175 try { 176 backupAndSetProperties(localProperties, backup); 177 return code.call(); 178 } catch (Exception e) { 179 throw new RuntimeException(e); 180 } finally { 181 restoreProperties(backup); 182 } 183 } 184 185 private static void backupAndSetProperties( 186 Map<String, String> localProperties, 187 Map<String, String> oldProperties) { 188 for (Map.Entry<String, String> e : localProperties.entrySet()) { 189 String oldValue = System.setProperty(e.getKey(), e.getValue()); 190 oldProperties.put(e.getKey(), oldValue); 191 } 192 } 193 194 private static void restoreProperties(Map<String, String> oldProperties) { 195 for (Map.Entry<String, String> e : oldProperties.entrySet()) { 196 String oldValue = e.getValue(); 197 String key = e.getKey(); 198 if (oldValue == null) 199 System.getProperties().remove(key); 200 else 201 System.setProperty(key, oldValue); 202 } 203 } 204 205 private static class TestCase { 206 207 final Map<String, String> localProperties; 208 final String urlhost; 209 final boolean expectedProxying; 210 211 TestCase(String nonProxyHosts, String urlhost, 212 boolean expectedProxying) { 213 this(nonProxyHosts, "proxy.example.com", urlhost, 214 expectedProxying); 215 } 216 217 TestCase(String nonProxyHosts, String proxyHost, String urlhost, 218 boolean expectedProxying) { 219 this(new HashMap<String, String>() { 220 { 221 put("http.nonProxyHosts", nonProxyHosts); 222 put("http.proxyHost", proxyHost); 223 } 224 }, urlhost, expectedProxying); 225 } 226 227 TestCase(Map<String, String> localProperties, String urlhost, 228 boolean expectedProxying) { 229 this.localProperties = localProperties; 230 this.urlhost = urlhost; 231 this.expectedProxying = expectedProxying; 232 } 233 234 void run() { 235 System.out.printf("urlhost=%s properties=%s: proxied? %s%n", 236 urlhost, localProperties, expectedProxying); 237 238 List<Proxy> proxies = withSystemPropertiesSet(localProperties, 239 () -> ProxySelector.getDefault().select( 240 URI.create(urlhost)) 241 ); 242 243 verify(proxies); 244 } 245 246 void verify(List<? extends Proxy> proxies) { 247 248 boolean actualProxying = !(proxies.size() == 1 && 249 proxies.get(0).type() == Proxy.Type.DIRECT); 250 251 if (actualProxying != expectedProxying) 252 throw new AssertionError(String.format( 253 "Expected %s connection for %s (given " + 254 "properties=%s). Here's the list of proxies " + 255 "returned: %s", 256 expectedProxying ? "proxied" : "direct", urlhost, 257 localProperties, proxies 258 )); 259 } 260 } 261 }