001: /* Licensed to the Apache Software Foundation (ASF) under one or more
002: * contributor license agreements. See the NOTICE file distributed with
003: * this work for additional information regarding copyright ownership.
004: * The ASF licenses this file to You under the Apache License, Version 2.0
005: * (the "License"); you may not use this file except in compliance with
006: * the License. You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package java.net;
017:
018: import java.io.BufferedInputStream;
019: import java.io.File;
020: import java.io.FileInputStream;
021: import java.io.InputStream;
022: import java.io.IOException;
023: import java.security.AccessController;
024: import java.util.ArrayList;
025: import java.util.List;
026: import java.util.Properties;
027:
028: import org.apache.harmony.luni.util.Msg;
029: import org.apache.harmony.luni.util.PriviAction;
030:
031: /**
032: * Default implementation for ProxySelector
033: */
034: @SuppressWarnings("unchecked")
035: class ProxySelectorImpl extends ProxySelector {
036:
037: private static final int HTTP_PROXY_PORT = 80;
038:
039: private static final int HTTPS_PROXY_PORT = 443;
040:
041: private static final int FTP_PROXY_PORT = 80;
042:
043: private static final int SOCKS_PROXY_PORT = 1080;
044:
045: // Net properties read from net.properties file.
046: private static Properties netProps = null;
047:
048: // read net.properties file
049: static {
050: AccessController
051: .doPrivileged(new java.security.PrivilegedAction() {
052: public Object run() {
053: File f = new File(System
054: .getProperty("java.home") //$NON-NLS-1$
055: + File.separator
056: + "lib" + File.separator //$NON-NLS-1$
057: + "net.properties"); //$NON-NLS-1$
058:
059: if (f.exists()) {
060: try {
061: FileInputStream fis = new FileInputStream(
062: f);
063: InputStream is = new BufferedInputStream(
064: fis);
065: netProps = new Properties();
066: netProps.load(is);
067: is.close();
068: } catch (IOException e) {
069: }
070: }
071: return null;
072: }
073: });
074: }
075:
076: public ProxySelectorImpl() {
077: super ();
078: }
079:
080: @Override
081: public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
082: if (null == uri || null == sa || null == ioe) {
083: // "KA001=Argument must not be null"
084: throw new IllegalArgumentException(Msg.getString("KA001")); //$NON-NLS-1$
085: }
086: }
087:
088: @Override
089: public List<Proxy> select(URI uri) {
090: // argument check
091: if (null == uri) {
092: // KA001=Argument must not be null
093: throw new IllegalArgumentException(Msg.getString("KA001")); //$NON-NLS-1$
094: }
095: // check scheme
096: String scheme = uri.getScheme();
097: if (null == scheme) {
098: throw new IllegalArgumentException();
099: }
100:
101: String host = uri.getHost();
102: Proxy proxy = Proxy.NO_PROXY;
103:
104: if ("http".equals(scheme)) { //$NON-NLS-1$
105: proxy = selectHttpProxy(host);
106: } else if ("https".equals(scheme)) { //$NON-NLS-1$
107: proxy = selectHttpsProxy();
108: } else if ("ftp".equals(scheme)) { //$NON-NLS-1$
109: proxy = selectFtpProxy(host);
110: } else if ("socket".equals(scheme)) { //$NON-NLS-1$
111: proxy = selectSocksProxy();
112: }
113: List<Proxy> proxyList = new ArrayList<Proxy>(1);
114: proxyList.add(proxy);
115: return proxyList;
116: }
117:
118: /*
119: * Gets proxy for http request. 1. gets from "http.proxyHost", then gets
120: * port from "http.proxyPort", or from "proxyPort" if "http.proxyPort" is
121: * unavailable. 2. gets from "proxyHost" if 1 is unavailable,then get port
122: * from "proxyPort", or from "http.proxyPort" if "proxyPort" is unavailable.
123: * 3. gets from "socksProxyHost" if 2 is unavailable.
124: */
125:
126: private Proxy selectHttpProxy(String uriHost) {
127: String host;
128: String port = null;
129: Proxy.Type type = Proxy.Type.DIRECT;
130:
131: String nonProxyHosts = getSystemProperty("http.nonProxyHosts"); //$NON-NLS-1$
132: // if host is in non proxy host list, returns Proxy.NO_PROXY
133: if (isNonProxyHost(uriHost, nonProxyHosts)) {
134: return Proxy.NO_PROXY;
135: }
136:
137: host = getSystemProperty("http.proxyHost"); //$NON-NLS-1$
138: if (null != host) {
139: // case 1: http.proxyHost is set, use exact http proxy
140: type = Proxy.Type.HTTP;
141: port = getSystemPropertyOrAlternative("http.proxyPort", //$NON-NLS-1$
142: "proxyPort", String.valueOf(HTTP_PROXY_PORT)); //$NON-NLS-1$
143: } else if ((host = getSystemProperty("proxyHost", null)) != null) { //$NON-NLS-1$
144: // case 2: proxyHost is set, use exact http proxy
145: type = Proxy.Type.HTTP;
146: port = getSystemPropertyOrAlternative("proxyPort", //$NON-NLS-1$
147: "http.proxyPort", String.valueOf(HTTP_PROXY_PORT)); //$NON-NLS-1$
148:
149: } else if ((host = getSystemProperty("socksProxyHost")) != null) { //$NON-NLS-1$
150: // case 3: use socks proxy instead
151: type = Proxy.Type.SOCKS;
152: port = getSystemProperty(
153: "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT)); //$NON-NLS-1$
154: }
155: int defaultPort = (type == Proxy.Type.SOCKS) ? SOCKS_PROXY_PORT
156: : HTTP_PROXY_PORT;
157: return createProxy(type, host, port, defaultPort);
158: }
159:
160: /*
161: * Gets proxy for https request.
162: */
163: private Proxy selectHttpsProxy() {
164: String host;
165: String port = null;
166: Proxy.Type type = Proxy.Type.DIRECT;
167:
168: host = getSystemProperty("https.proxyHost"); //$NON-NLS-1$
169: if (null != host) {
170: // case 1: use exact https proxy
171: type = Proxy.Type.HTTP;
172: port = getSystemProperty(
173: "https.proxyPort", String.valueOf(HTTPS_PROXY_PORT)); //$NON-NLS-1$
174: } else {
175: host = getSystemProperty("socksProxyHost"); //$NON-NLS-1$
176: if (null != host) {
177: // case 2: use socks proxy instead
178: type = Proxy.Type.SOCKS;
179: port = getSystemProperty(
180: "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT)); //$NON-NLS-1$
181: }
182: }
183: int defaultPort = (type == Proxy.Type.SOCKS) ? SOCKS_PROXY_PORT
184: : HTTPS_PROXY_PORT;
185: return createProxy(type, host, port, defaultPort);
186: }
187:
188: /*
189: * Gets proxy for ftp request.
190: */
191: private Proxy selectFtpProxy(String uriHost) {
192: String host;
193: String port = null;
194: Proxy.Type type = Proxy.Type.DIRECT;
195: String nonProxyHosts = getSystemProperty("ftp.nonProxyHosts"); //$NON-NLS-1$
196: // if host is in non proxy host list, returns Proxy.NO_PROXY
197: if (isNonProxyHost(uriHost, nonProxyHosts)) {
198: return Proxy.NO_PROXY;
199: }
200:
201: host = getSystemProperty("ftp.proxyHost"); //$NON-NLS-1$
202: if (null != host) {
203: // case 1: use exact ftp proxy
204: type = Proxy.Type.HTTP;
205: port = getSystemProperty(
206: "ftp.proxyPort", String.valueOf(FTP_PROXY_PORT)); //$NON-NLS-1$
207: } else {
208: host = getSystemProperty("socksProxyHost"); //$NON-NLS-1$
209: if (null != host) {
210: // case 2: use socks proxy instead
211: type = Proxy.Type.SOCKS;
212: port = getSystemProperty(
213: "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT)); //$NON-NLS-1$
214: }
215: }
216: int defaultPort = (type == Proxy.Type.SOCKS) ? SOCKS_PROXY_PORT
217: : FTP_PROXY_PORT;
218: return createProxy(type, host, port, defaultPort);
219: }
220:
221: /*
222: * Gets proxy for socks request.
223: */
224: private Proxy selectSocksProxy() {
225: String host;
226: String port = null;
227: Proxy.Type type = Proxy.Type.DIRECT;
228:
229: host = getSystemProperty("socksProxyHost"); //$NON-NLS-1$
230: if (null != host) {
231: type = Proxy.Type.SOCKS;
232: port = getSystemProperty(
233: "socksProxyPort", String.valueOf(SOCKS_PROXY_PORT)); //$NON-NLS-1$
234: }
235: return createProxy(type, host, port, SOCKS_PROXY_PORT);
236: }
237:
238: /*
239: * checks whether the host needs proxy. return true if it doesn't need a
240: * proxy.
241: */
242: private boolean isNonProxyHost(String host, String nonProxyHosts) {
243: // nonProxyHosts is not set
244: if (null == host || null == nonProxyHosts) {
245: return false;
246: }
247: // Construct regex expression of nonProxyHosts
248: int length = nonProxyHosts.length();
249: char ch;
250: StringBuilder buf = new StringBuilder(length);
251: for (int i = 0; i < nonProxyHosts.length(); i++) {
252: ch = nonProxyHosts.charAt(i);
253: switch (ch) {
254: case '.':
255: buf.append("\\."); //$NON-NLS-1$
256: break;
257: case '*':
258: buf.append(".*"); //$NON-NLS-1$
259: break;
260: default:
261: buf.append(ch);
262: }
263: }
264: String nonProxyHostsReg = buf.toString();
265: // check whether the host is the nonProxyHosts.
266: return host.matches(nonProxyHostsReg);
267: }
268:
269: /*
270: * Create Proxy by "type","host" and "port".
271: */
272: private Proxy createProxy(Proxy.Type type, String host,
273: String port, int defaultPort) {
274: Proxy proxy;
275: if (type == Proxy.Type.DIRECT) {
276: proxy = Proxy.NO_PROXY;
277: } else {
278: int iPort;
279: try {
280: iPort = Integer.valueOf(port).intValue();
281: } catch (NumberFormatException e) {
282: iPort = defaultPort;
283: }
284: proxy = new Proxy(type, InetSocketAddress.createUnresolved(
285: host, 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
305: .doPrivileged(new PriviAction<String>(property));
306: if (null == value || "".equals(value)) { //$NON-NLS-1$
307: value = (netProps != null) ? netProps.getProperty(property,
308: defaultValue) : 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: }
|