1 /* 2 * Copyright (c) 2003, 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.net; 27 28 import java.io.IOException; 29 import java.util.List; 30 import sun.security.util.SecurityConstants; 31 32 /** 33 * Selects the proxy server to use, if any, when connecting to the 34 * network resource referenced by a URL. A proxy selector is a 35 * concrete sub-class of this class and is registered by invoking the 36 * {@link java.net.ProxySelector#setDefault setDefault} method. The 37 * currently registered proxy selector can be retrieved by calling 38 * {@link java.net.ProxySelector#getDefault getDefault} method. 39 * 40 * <p> When a proxy selector is registered, for instance, a subclass 41 * of URLConnection class should call the {@link #select select} 42 * method for each URL request so that the proxy selector can decide 43 * if a direct, or proxied connection should be used. The {@link 44 * #select select} method returns an iterator over a collection with 45 * the preferred connection approach. 46 * 47 * <p> If a connection cannot be established to a proxy (PROXY or 48 * SOCKS) servers then the caller should call the proxy selector's 49 * {@link #connectFailed connectFailed} method to notify the proxy 50 * selector that the proxy server is unavailable. </p> 51 * 52 * <P>The default proxy selector does enforce a 53 * <a href="doc-files/net-properties.html#Proxies">set of System Properties</a> 54 * related to proxy settings.</P> 55 * 56 * @author Yingxian Wang 57 * @author Jean-Christophe Collet 58 * @since 1.5 59 */ 60 public abstract class ProxySelector { 61 /** 62 * The system wide proxy selector that selects the proxy server to 63 * use, if any, when connecting to a remote object referenced by 64 * an URL. 65 * 66 * @see #setDefault(ProxySelector) 67 */ 68 private static ProxySelector theProxySelector; 69 70 static { 71 try { 72 Class<?> c = Class.forName("sun.net.spi.DefaultProxySelector"); 73 if (c != null && ProxySelector.class.isAssignableFrom(c)) { 74 @SuppressWarnings("deprecation") 75 ProxySelector tmp = (ProxySelector) c.newInstance(); 76 theProxySelector = tmp; 77 } 78 } catch (Exception e) { 79 theProxySelector = null; 80 } 81 } 82 83 /** 84 * Gets the system-wide proxy selector. 85 * 86 * @throws SecurityException 87 * If a security manager has been installed and it denies 88 * {@link NetPermission}{@code ("getProxySelector")} 89 * @see #setDefault(ProxySelector) 90 * @return the system-wide {@code ProxySelector} 91 * @since 1.5 92 */ 93 public static ProxySelector getDefault() { 94 SecurityManager sm = System.getSecurityManager(); 95 if (sm != null) { 96 sm.checkPermission(SecurityConstants.GET_PROXYSELECTOR_PERMISSION); 97 } 98 return theProxySelector; 99 } 100 101 /** 102 * Sets (or unsets) the system-wide proxy selector. 103 * 104 * Note: non-standard protocol handlers may ignore this setting. 105 * 106 * @param ps The HTTP proxy selector, or 107 * {@code null} to unset the proxy selector. 108 * 109 * @throws SecurityException 110 * If a security manager has been installed and it denies 111 * {@link NetPermission}{@code ("setProxySelector")} 112 * 113 * @see #getDefault() 114 * @since 1.5 115 */ 116 public static void setDefault(ProxySelector ps) { 117 SecurityManager sm = System.getSecurityManager(); 118 if (sm != null) { 119 sm.checkPermission(SecurityConstants.SET_PROXYSELECTOR_PERMISSION); 120 } 121 theProxySelector = ps; 122 } 123 124 /** 125 * Selects all the applicable proxies based on the protocol to 126 * access the resource with and a destination address to access 127 * the resource at. 128 * The format of the URI is defined as follow: 129 * <UL> 130 * <LI>http URI for http connections</LI> 131 * <LI>https URI for https connections 132 * <LI>{@code socket://host:port}<br> 133 * for tcp client sockets connections</LI> 134 * </UL> 135 * 136 * @param uri 137 * The URI that a connection is required to 138 * 139 * @return a List of Proxies. Each element in the 140 * the List is of type 141 * {@link java.net.Proxy Proxy}; 142 * when no proxy is available, the list will 143 * contain one element of type 144 * {@link java.net.Proxy Proxy} 145 * that represents a direct connection. 146 * @throws IllegalArgumentException if the argument is null 147 */ 148 public abstract List<Proxy> select(URI uri); 149 150 /** 151 * Called to indicate that a connection could not be established 152 * to a proxy/socks server. An implementation of this method can 153 * temporarily remove the proxies or reorder the sequence of 154 * proxies returned by {@link #select(URI)}, using the address 155 * and the IOException caught when trying to connect. 156 * 157 * @param uri 158 * The URI that the proxy at sa failed to serve. 159 * @param sa 160 * The socket address of the proxy/SOCKS server 161 * 162 * @param ioe 163 * The I/O exception thrown when the connect failed. 164 * @throws IllegalArgumentException if either argument is null 165 */ 166 public abstract void connectFailed(URI uri, SocketAddress sa, IOException ioe); 167 168 /** 169 * Returns a ProxySelector which uses the given proxy address for all HTTP 170 * and HTTPS requests. If proxy is {@code null} then proxying is disabled. 171 * 172 * @param proxyAddress 173 * The address of the proxy 174 * 175 * @return a ProxySelector 176 * 177 * @since 9 178 */ 179 public static ProxySelector of(InetSocketAddress proxyAddress) { 180 return new StaticProxySelector(proxyAddress); 181 } 182 183 static class StaticProxySelector extends ProxySelector { 184 private static final List<Proxy> NO_PROXY_LIST = List.of(Proxy.NO_PROXY); 185 final List<Proxy> list; 186 187 StaticProxySelector(InetSocketAddress address){ 188 Proxy p; 189 if (address == null) { 190 p = Proxy.NO_PROXY; 191 } else { 192 p = new Proxy(Proxy.Type.HTTP, address); 193 } 194 list = List.of(p); 195 } 196 197 @Override 198 public void connectFailed(URI uri, SocketAddress sa, IOException e) { 199 /* ignore */ 200 } 201 202 @Override 203 public synchronized List<Proxy> select(URI uri) { 204 String scheme = uri.getScheme().toLowerCase(); 205 if (scheme.equals("http") || scheme.equals("https")) { 206 return list; 207 } else { 208 return NO_PROXY_LIST; 209 } 210 } 211 } 212 }