History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/net/spi/DefaultProxySelector.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/net/spi/DefaultProxySelector.java+344−0
@@ -0,0 +1,344 @@
1+/*
2+ * Copyright (c) 2003, 2011, 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 sun.net.spi;
27+
28+import java.net.InetSocketAddress;
29+import java.net.Proxy;
30+import java.net.ProxySelector;
31+import java.net.SocketAddress;
32+import java.net.URI;
33+import java.util.ArrayList;
34+import java.util.List;
35+import java.util.StringTokenizer;
36+import java.io.IOException;
37+import sun.misc.RegexpPool;
38+import java.security.AccessController;
39+import java.security.PrivilegedAction;
40+import sun.net.NetProperties;
41+import sun.net.SocksProxy;
42+
43+/**
44+ * Supports proxy settings using system properties This proxy selector
45+ * provides backward compatibility with the old http protocol handler
46+ * as far as how proxy is set
47+ *
48+ * Most of the implementation copied from the old http protocol handler
49+ *
50+ * Supports http/https/ftp.proxyHost, http/https/ftp.proxyPort,
51+ * proxyHost, proxyPort, and http/https/ftp.nonProxyHost, and socks.
52+ * NOTE: need to do gopher as well
53+ */
54+public class DefaultProxySelector extends ProxySelector {
55+
56+ /**
57+ * This is where we define all the valid System Properties we have to
58+ * support for each given protocol.
59+ * The format of this 2 dimensional array is :
60+ * - 1 row per protocol (http, ftp, ...)
61+ * - 1st element of each row is the protocol name
62+ * - subsequent elements are prefixes for Host & Port properties
63+ * listed in order of priority.
64+ * Example:
65+ * {"ftp", "ftp.proxy", "ftpProxy", "proxy", "socksProxy"},
66+ * means for FTP we try in that oder:
67+ * + ftp.proxyHost & ftp.proxyPort
68+ * + ftpProxyHost & ftpProxyPort
69+ * + proxyHost & proxyPort
70+ * + socksProxyHost & socksProxyPort
71+ *
72+ * Note that the socksProxy should *always* be the last on the list
73+ */
74+ final static String[][] props = {
75+ /*
76+ * protocol, Property prefix 1, Property prefix 2, ...
77+ */
78+ {"http", "http.proxy", "proxy", "socksProxy"},
79+ {"https", "https.proxy", "proxy", "socksProxy"},
80+ {"ftp", "ftp.proxy", "ftpProxy", "proxy", "socksProxy"},
81+ {"gopher", "gopherProxy", "socksProxy"},
82+ {"socket", "socksProxy"}
83+ };
84+
85+ private static final String SOCKS_PROXY_VERSION = "socksProxyVersion";
86+
87+ private static boolean hasSystemProxies = false;
88+
89+ static {
90+ final String key = "java.net.useSystemProxies";
91+ Boolean b = AccessController.doPrivileged(
92+ new PrivilegedAction<Boolean>() {
93+ public Boolean run() {
94+ return NetProperties.getBoolean(key);
95+ }});
96+ if (b != null && b.booleanValue()) {
97+ java.security.AccessController.doPrivileged(
98+ new sun.security.action.LoadLibraryAction("net"));
99+ hasSystemProxies = init();
100+ }
101+ }
102+
103+ /**
104+ * How to deal with "non proxy hosts":
105+ * since we do have to generate a RegexpPool we don't want to do that if
106+ * it's not necessary. Therefore we do cache the result, on a per-protocol
107+ * basis, and change it only when the "source", i.e. the system property,
108+ * did change.
109+ */
110+
111+ static class NonProxyInfo {
112+ // Default value for nonProxyHosts, this provides backward compatibility
113+ // by excluding localhost and its litteral notations.
114+ static final String defStringVal = "localhost|127.*|[::1]";
115+
116+ String hostsSource;
117+ RegexpPool hostsPool;
118+ final String property;
119+ final String defaultVal;
120+ static NonProxyInfo ftpNonProxyInfo = new NonProxyInfo("ftp.nonProxyHosts", null, null, defStringVal);
121+ static NonProxyInfo httpNonProxyInfo = new NonProxyInfo("http.nonProxyHosts", null, null, defStringVal);
122+
123+ NonProxyInfo(String p, String s, RegexpPool pool, String d) {
124+ property = p;
125+ hostsSource = s;
126+ hostsPool = pool;
127+ defaultVal = d;
128+ }
129+ }
130+
131+
132+ /**
133+ * select() method. Where all the hard work is done.
134+ * Build a list of proxies depending on URI.
135+ * Since we're only providing compatibility with the system properties
136+ * from previous releases (see list above), that list will always
137+ * contain 1 single proxy, default being NO_PROXY.
138+ */
139+ public java.util.List<Proxy> select(URI uri) {
140+ if (uri == null) {
141+ throw new IllegalArgumentException("URI can't be null.");
142+ }
143+ String protocol = uri.getScheme();
144+ String host = uri.getHost();
145+
146+ if (host == null) {
147+ // This is a hack to ensure backward compatibility in two
148+ // cases: 1. hostnames contain non-ascii characters,
149+ // internationalized domain names. in which case, URI will
150+ // return null, see BugID 4957669; 2. Some hostnames can
151+ // contain '_' chars even though it's not supposed to be
152+ // legal, in which case URI will return null for getHost,
153+ // but not for getAuthority() See BugID 4913253
154+ String auth = uri.getAuthority();
155+ if (auth != null) {
156+ int i;
157+ i = auth.indexOf('@');
158+ if (i >= 0) {
159+ auth = auth.substring(i+1);
160+ }
161+ i = auth.lastIndexOf(':');
162+ if (i >= 0) {
163+ auth = auth.substring(0,i);
164+ }
165+ host = auth;
166+ }
167+ }
168+
169+ if (protocol == null || host == null) {
170+ throw new IllegalArgumentException("protocol = "+protocol+" host = "+host);
171+ }
172+ List<Proxy> proxyl = new ArrayList<Proxy>(1);
173+
174+ NonProxyInfo pinfo = null;
175+
176+ if ("http".equalsIgnoreCase(protocol)) {
177+ pinfo = NonProxyInfo.httpNonProxyInfo;
178+ } else if ("https".equalsIgnoreCase(protocol)) {
179+ // HTTPS uses the same property as HTTP, for backward
180+ // compatibility
181+ pinfo = NonProxyInfo.httpNonProxyInfo;
182+ } else if ("ftp".equalsIgnoreCase(protocol)) {
183+ pinfo = NonProxyInfo.ftpNonProxyInfo;
184+ }
185+
186+ /**
187+ * Let's check the System properties for that protocol
188+ */
189+ final String proto = protocol;
190+ final NonProxyInfo nprop = pinfo;
191+ final String urlhost = host.toLowerCase();
192+
193+ /**
194+ * This is one big doPrivileged call, but we're trying to optimize
195+ * the code as much as possible. Since we're checking quite a few
196+ * System properties it does help having only 1 call to doPrivileged.
197+ * Be mindful what you do in here though!
198+ */
199+ Proxy p = AccessController.doPrivileged(
200+ new PrivilegedAction<Proxy>() {
201+ public Proxy run() {
202+ int i, j;
203+ String phost = null;
204+ int pport = 0;
205+ String nphosts = null;
206+ InetSocketAddress saddr = null;
207+
208+ // Then let's walk the list of protocols in our array
209+ for (i=0; i<props.length; i++) {
210+ if (props[i][0].equalsIgnoreCase(proto)) {
211+ for (j = 1; j < props[i].length; j++) {
212+ /* System.getProp() will give us an empty
213+ * String, "" for a defined but "empty"
214+ * property.
215+ */
216+ phost = NetProperties.get(props[i][j]+"Host");
217+ if (phost != null && phost.length() != 0)
218+ break;
219+ }
220+ if (phost == null || phost.length() == 0) {
221+ /**
222+ * No system property defined for that
223+ * protocol. Let's check System Proxy
224+ * settings (Gnome & Windows) if we were
225+ * instructed to.
226+ */
227+ if (hasSystemProxies) {
228+ String sproto;
229+ if (proto.equalsIgnoreCase("socket"))
230+ sproto = "socks";
231+ else
232+ sproto = proto;
233+ Proxy sproxy = getSystemProxy(sproto, urlhost);
234+ if (sproxy != null) {
235+ return sproxy;
236+ }
237+ }
238+ return Proxy.NO_PROXY;
239+ }
240+ // If a Proxy Host is defined for that protocol
241+ // Let's get the NonProxyHosts property
242+ if (nprop != null) {
243+ nphosts = NetProperties.get(nprop.property);
244+ synchronized (nprop) {
245+ if (nphosts == null) {
246+ if (nprop.defaultVal != null) {
247+ nphosts = nprop.defaultVal;
248+ } else {
249+ nprop.hostsSource = null;
250+ nprop.hostsPool = null;
251+ }
252+ }
253+ if (nphosts != null) {
254+ if (!nphosts.equals(nprop.hostsSource)) {
255+ RegexpPool pool = new RegexpPool();
256+ StringTokenizer st = new StringTokenizer(nphosts, "|", false);
257+ try {
258+ while (st.hasMoreTokens()) {
259+ pool.add(st.nextToken().toLowerCase(), Boolean.TRUE);
260+ }
261+ } catch (sun.misc.REException ex) {
262+ }
263+ nprop.hostsPool = pool;
264+ nprop.hostsSource = nphosts;
265+ }
266+ }
267+ if (nprop.hostsPool != null &&
268+ nprop.hostsPool.match(urlhost) != null) {
269+ return Proxy.NO_PROXY;
270+ }
271+ }
272+ }
273+ // We got a host, let's check for port
274+
275+ pport = NetProperties.getInteger(props[i][j]+"Port", 0).intValue();
276+ if (pport == 0 && j < (props[i].length - 1)) {
277+ // Can't find a port with same prefix as Host
278+ // AND it's not a SOCKS proxy
279+ // Let's try the other prefixes for that proto
280+ for (int k = 1; k < (props[i].length - 1); k++) {
281+ if ((k != j) && (pport == 0))
282+ pport = NetProperties.getInteger(props[i][k]+"Port", 0).intValue();
283+ }
284+ }
285+
286+ // Still couldn't find a port, let's use default
287+ if (pport == 0) {
288+ if (j == (props[i].length - 1)) // SOCKS
289+ pport = defaultPort("socket");
290+ else
291+ pport = defaultPort(proto);
292+ }
293+ // We did find a proxy definition.
294+ // Let's create the address, but don't resolve it
295+ // as this will be done at connection time
296+ saddr = InetSocketAddress.createUnresolved(phost, pport);
297+ // Socks is *always* the last on the list.
298+ if (j == (props[i].length - 1)) {
299+ int version = NetProperties.getInteger(SOCKS_PROXY_VERSION, 5).intValue();
300+ return SocksProxy.create(saddr, version);
301+ } else {
302+ return new Proxy(Proxy.Type.HTTP, saddr);
303+ }
304+ }
305+ }
306+ return Proxy.NO_PROXY;
307+ }});
308+
309+ proxyl.add(p);
310+
311+ /*
312+ * If no specific property was set for that URI, we should be
313+ * returning an iterator to an empty List.
314+ */
315+ return proxyl;
316+ }
317+
318+ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
319+ if (uri == null || sa == null || ioe == null) {
320+ throw new IllegalArgumentException("Arguments can't be null.");
321+ }
322+ // ignored
323+ }
324+
325+
326+ private int defaultPort(String protocol) {
327+ if ("http".equalsIgnoreCase(protocol)) {
328+ return 80;
329+ } else if ("https".equalsIgnoreCase(protocol)) {
330+ return 443;
331+ } else if ("ftp".equalsIgnoreCase(protocol)) {
332+ return 80;
333+ } else if ("socket".equalsIgnoreCase(protocol)) {
334+ return 1080;
335+ } else if ("gopher".equalsIgnoreCase(protocol)) {
336+ return 80;
337+ } else {
338+ return -1;
339+ }
340+ }
341+
342+ private native static boolean init();
343+ private native Proxy getSystemProxy(String protocol, String host);
344+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t