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