ProxySelectorImpl.java revision fdb2704414a9ed92394ada0d1395e4db86889465
1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package java.net; 17 18import java.io.BufferedInputStream; 19import java.io.File; 20import java.io.FileInputStream; 21import java.io.InputStream; 22import java.io.IOException; 23import java.security.AccessController; 24import java.util.ArrayList; 25import java.util.List; 26import java.util.Properties; 27 28import org.apache.harmony.luni.util.Msg; 29import org.apache.harmony.luni.util.PriviAction; 30 31/** 32 * Default implementation for ProxySelector 33 */ 34class ProxySelectorImpl extends ProxySelector { 35 36 private static final int HTTP_PROXY_PORT = 80; 37 38 private static final int HTTPS_PROXY_PORT = 443; 39 40 private static final int FTP_PROXY_PORT = 80; 41 42 private static final int SOCKS_PROXY_PORT = 1080; 43 44 // Net properties read from net.properties file. 45 private static Properties netProps = null; 46 47 // read net.properties file 48 static { 49 AccessController.doPrivileged(new java.security.PrivilegedAction() { 50 public Object run() { 51 File f = new File(System.getProperty("java.home") //$NON-NLS-1$ 52 + File.separator + "lib" + File.separator //$NON-NLS-1$ 53 + "net.properties"); //$NON-NLS-1$ 54 55 if (f.exists()) { 56 try { 57 FileInputStream fis = new FileInputStream(f); 58 // BEGIN android-modified 59 InputStream is = new BufferedInputStream(fis, 8192); 60 // END android-modified 61 netProps = new Properties(); 62 netProps.load(is); 63 is.close(); 64 } catch (IOException e) { 65 } 66 } 67 return null; 68 } 69 }); 70 } 71 72 public ProxySelectorImpl() { 73 super(); 74 } 75 76 @Override 77 public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { 78 if (null == uri || null == sa || null == ioe) { 79 // "KA001=Argument must not be null" 80 throw new IllegalArgumentException(Msg.getString("KA001")); //$NON-NLS-1$ 81 } 82 } 83 84 @Override 85 public List<Proxy> select(URI uri) { 86 // argument check 87 if (null == uri) { 88 // KA001=Argument must not be null 89 throw new IllegalArgumentException(Msg.getString("KA001")); //$NON-NLS-1$ 90 } 91 // check scheme 92 String scheme = uri.getScheme(); 93 if (null == scheme) { 94 throw new IllegalArgumentException(); 95 } 96 97 String host = uri.getHost(); 98 Proxy proxy = Proxy.NO_PROXY; 99 100 if ("http".equals(scheme)) { //$NON-NLS-1$ 101 proxy = selectHttpProxy(host); 102 } else if ("https".equals(scheme)) { //$NON-NLS-1$ 103 proxy = selectHttpsProxy(); 104 } else if ("ftp".equals(scheme)) { //$NON-NLS-1$ 105 proxy = selectFtpProxy(host); 106 } else if ("socket".equals(scheme)) { //$NON-NLS-1$ 107 proxy = selectSocksProxy(); 108 } 109 List<Proxy> proxyList = new ArrayList<Proxy>(1); 110 proxyList.add(proxy); 111 return proxyList; 112 } 113 114 /* 115 * Gets proxy for http request. 1. gets from "http.proxyHost", then gets 116 * port from "http.proxyPort", or from "proxyPort" if "http.proxyPort" is 117 * unavailable. 2. gets from "proxyHost" if 1 is unavailable,then get port 118 * from "proxyPort", or from "http.proxyPort" if "proxyPort" is unavailable. 119 * 3. gets from "socksProxyHost" if 2 is unavailable. 120 */ 121 122 private Proxy selectHttpProxy(String uriHost) { 123 String host; 124 String port = null; 125 Proxy.Type type = Proxy.Type.DIRECT; 126 127 String nonProxyHosts = getSystemProperty("http.nonProxyHosts"); //$NON-NLS-1$ 128 // if host is in non proxy host list, returns Proxy.NO_PROXY 129 if (isNonProxyHost(uriHost, nonProxyHosts)) { 130 return Proxy.NO_PROXY; 131 } 132 133 host = getSystemProperty("http.proxyHost"); //$NON-NLS-1$ 134 if (null != host) { 135 // case 1: http.proxyHost is set, use exact http proxy 136 type = Proxy.Type.HTTP; 137 port = getSystemPropertyOrAlternative("http.proxyPort", //$NON-NLS-1$ 138 "proxyPort", String.valueOf(HTTP_PROXY_PORT)); //$NON-NLS-1$ 139 } else if ((host = getSystemProperty("proxyHost", null)) != null) { //$NON-NLS-1$ 140 // case 2: proxyHost is set, use exact http proxy 141 type = Proxy.Type.HTTP; 142 port = getSystemPropertyOrAlternative("proxyPort", //$NON-NLS-1$ 143 "http.proxyPort", String.valueOf(HTTP_PROXY_PORT)); //$NON-NLS-1$ 144 145 } else if ((host = getSystemProperty("socksProxyHost")) != null) { //$NON-NLS-1$ 146 // case 3: use socks proxy instead 147 type = Proxy.Type.SOCKS; 148 port = getSystemProperty( 149 "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT)); //$NON-NLS-1$ 150 } 151 int defaultPort = (type == Proxy.Type.SOCKS) ? SOCKS_PROXY_PORT 152 : HTTP_PROXY_PORT; 153 return createProxy(type, host, port, defaultPort); 154 } 155 156 /* 157 * Gets proxy for https request. 158 */ 159 private Proxy selectHttpsProxy() { 160 String host; 161 String port = null; 162 Proxy.Type type = Proxy.Type.DIRECT; 163 164 host = getSystemProperty("https.proxyHost"); //$NON-NLS-1$ 165 if (null != host) { 166 // case 1: use exact https proxy 167 type = Proxy.Type.HTTP; 168 port = getSystemProperty( 169 "https.proxyPort", String.valueOf(HTTPS_PROXY_PORT)); //$NON-NLS-1$ 170 } else { 171 host = getSystemProperty("socksProxyHost"); //$NON-NLS-1$ 172 if (null != host) { 173 // case 2: use socks proxy instead 174 type = Proxy.Type.SOCKS; 175 port = getSystemProperty( 176 "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT)); //$NON-NLS-1$ 177 } 178 } 179 int defaultPort = (type == Proxy.Type.SOCKS) ? SOCKS_PROXY_PORT 180 : HTTPS_PROXY_PORT; 181 return createProxy(type, host, port, defaultPort); 182 } 183 184 /* 185 * Gets proxy for ftp request. 186 */ 187 private Proxy selectFtpProxy(String uriHost) { 188 String host; 189 String port = null; 190 Proxy.Type type = Proxy.Type.DIRECT; 191 String nonProxyHosts = getSystemProperty("ftp.nonProxyHosts"); //$NON-NLS-1$ 192 // if host is in non proxy host list, returns Proxy.NO_PROXY 193 if (isNonProxyHost(uriHost, nonProxyHosts)) { 194 return Proxy.NO_PROXY; 195 } 196 197 host = getSystemProperty("ftp.proxyHost"); //$NON-NLS-1$ 198 if (null != host) { 199 // case 1: use exact ftp proxy 200 type = Proxy.Type.HTTP; 201 port = getSystemProperty( 202 "ftp.proxyPort", String.valueOf(FTP_PROXY_PORT)); //$NON-NLS-1$ 203 } else { 204 host = getSystemProperty("socksProxyHost"); //$NON-NLS-1$ 205 if (null != host) { 206 // case 2: use socks proxy instead 207 type = Proxy.Type.SOCKS; 208 port = getSystemProperty( 209 "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT)); //$NON-NLS-1$ 210 } 211 } 212 int defaultPort = (type == Proxy.Type.SOCKS) ? SOCKS_PROXY_PORT 213 : FTP_PROXY_PORT; 214 return createProxy(type, host, port, defaultPort); 215 } 216 217 /* 218 * Gets proxy for socks request. 219 */ 220 private Proxy selectSocksProxy() { 221 String host; 222 String port = null; 223 Proxy.Type type = Proxy.Type.DIRECT; 224 225 host = getSystemProperty("socksProxyHost"); //$NON-NLS-1$ 226 if (null != host) { 227 type = Proxy.Type.SOCKS; 228 port = getSystemProperty( 229 "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT)); //$NON-NLS-1$ 230 } 231 return createProxy(type, host, port, SOCKS_PROXY_PORT); 232 } 233 234 /* 235 * checks whether the host needs proxy. return true if it doesn't need a 236 * proxy. 237 */ 238 private boolean isNonProxyHost(String host, String nonProxyHosts) { 239 // nonProxyHosts is not set 240 if (null == nonProxyHosts) { 241 return false; 242 } 243 // Construct regex expression of nonProxyHosts 244 int length = nonProxyHosts.length(); 245 char ch; 246 StringBuilder buf = new StringBuilder(length); 247 for (int i = 0; i < nonProxyHosts.length(); i++) { 248 ch = nonProxyHosts.charAt(i); 249 switch (ch) { 250 case '.': 251 buf.append("\\."); //$NON-NLS-1$ 252 break; 253 case '*': 254 buf.append(".*"); //$NON-NLS-1$ 255 break; 256 default: 257 buf.append(ch); 258 } 259 } 260 String nonProxyHostsReg = buf.toString(); 261 // check whether the host is the nonProxyHosts. 262 return host.matches(nonProxyHostsReg); 263 } 264 265 /* 266 * Create Proxy by "type","host" and "port". 267 */ 268 private Proxy createProxy(Proxy.Type type, String host, String port, 269 int defaultPort) { 270 Proxy proxy; 271 if (type == Proxy.Type.DIRECT) { 272 proxy = Proxy.NO_PROXY; 273 } else { 274 int iPort; 275 try { 276// BEGIN android-changed 277 iPort = Integer.parseInt(port); 278// END android-changed 279 } catch (NumberFormatException e) { 280 iPort = defaultPort; 281 } 282 proxy = new Proxy(type, InetSocketAddress.createUnresolved(host, 283 iPort)); 284 } 285 return proxy; 286 } 287 288 /* 289 * gets system property, privileged operation. If the value of the property 290 * is null or empty String, it returns defaultValue. 291 */ 292 private String getSystemProperty(final String property) { 293 return getSystemProperty(property, null); 294 } 295 296 /* 297 * gets system property, privileged operation. If the value of the property 298 * is null or empty String, it returns defaultValue. 299 */ 300 private String getSystemProperty(final String property, 301 final String defaultValue) { 302 String value = AccessController.doPrivileged(new PriviAction<String>( 303 property)); 304 if (null == value || "".equals(value)) { //$NON-NLS-1$ 305 value = (netProps != null) 306 ? netProps.getProperty(property, defaultValue) 307 : defaultValue; 308 } 309 return value; 310 } 311 312 /* 313 * gets system property, privileged operation. If the value of "key" 314 * property is null, then retrieve value from "alternative" property. 315 * Finally, if the value is null or empty String, it returns defaultValue. 316 */ 317 private String getSystemPropertyOrAlternative(final String key, 318 final String alternativeKey, final String defaultValue) { 319 String value = getSystemProperty(key); 320 if (value == null) { 321 value = getSystemProperty(alternativeKey); 322 if (null == value) { 323 value = defaultValue; 324 } 325 } 326 return value; 327 } 328} 329