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