source: josm/trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java@ 6830

Last change on this file since 6830 was 6714, checked in by Don-vip, 10 years ago

fix #7474 - don't use proxy when connecting to localhost

  • Property svn:eol-style set to native
File size: 8.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.net.InetSocketAddress;
8import java.net.Proxy;
9import java.net.Proxy.Type;
10import java.net.ProxySelector;
11import java.net.SocketAddress;
12import java.net.URI;
13import java.util.Collections;
14import java.util.HashSet;
15import java.util.List;
16import java.util.Set;
17import java.util.TreeSet;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.gui.preferences.server.ProxyPreferencesPanel;
21import org.openstreetmap.josm.gui.preferences.server.ProxyPreferencesPanel.ProxyPolicy;
22
23/**
24 * This is the default proxy selector used in JOSM.
25 *
26 */
27public class DefaultProxySelector extends ProxySelector {
28
29 private static final List<Proxy> NO_PROXY_LIST = Collections.singletonList(Proxy.NO_PROXY);
30
31 /**
32 * The {@link ProxySelector} provided by the JDK will retrieve proxy information
33 * from the system settings, if the system property <tt>java.net.useSystemProxies</tt>
34 * is defined <strong>at startup</strong>. It has no effect if the property is set
35 * later by the application.
36 *
37 * We therefore read the property at class loading time and remember it's value.
38 */
39 private static boolean JVM_WILL_USE_SYSTEM_PROXIES = false;
40 static {
41 String v = System.getProperty("java.net.useSystemProxies");
42 if (v != null && v.equals(Boolean.TRUE.toString())) {
43 JVM_WILL_USE_SYSTEM_PROXIES = true;
44 }
45 }
46
47 /**
48 * The {@link ProxySelector} provided by the JDK will retrieve proxy information
49 * from the system settings, if the system property <tt>java.net.useSystemProxies</tt>
50 * is defined <strong>at startup</strong>. If the property is set later by the application,
51 * this has no effect.
52 *
53 * @return true, if <tt>java.net.useSystemProxies</tt> was set to true at class initialization time
54 *
55 */
56 public static boolean willJvmRetrieveSystemProxies() {
57 return JVM_WILL_USE_SYSTEM_PROXIES;
58 }
59
60 private ProxyPolicy proxyPolicy;
61 private InetSocketAddress httpProxySocketAddress;
62 private InetSocketAddress socksProxySocketAddress;
63 private ProxySelector delegate;
64
65 private final Set<String> errorResources = new HashSet<String>();
66 private final Set<String> errorMessages = new HashSet<String>();
67
68 /**
69 * A typical example is:
70 * <pre>
71 * PropertySelector delegate = PropertySelector.getDefault();
72 * PropertySelector.setDefault(new DefaultPropertySelector(delegate));
73 * </pre>
74 *
75 * @param delegate the proxy selector to delegate to if system settings are used. Usually
76 * this is the proxy selector found by ProxySelector.getDefault() before this proxy
77 * selector is installed
78 */
79 public DefaultProxySelector(ProxySelector delegate) {
80 this.delegate = delegate;
81 initFromPreferences();
82 }
83
84 protected int parseProxyPortValue(String property, String value) {
85 if (value == null) return 0;
86 int port = 0;
87 try {
88 port = Integer.parseInt(value);
89 } catch (NumberFormatException e) {
90 Main.error(tr("Unexpected format for port number in in preference ''{0}''. Got ''{1}''.", property, value));
91 Main.error(tr("The proxy will not be used."));
92 return 0;
93 }
94 if (port <= 0 || port > 65535) {
95 Main.error(tr("Illegal port number in preference ''{0}''. Got {1}.", property, port));
96 Main.error(tr("The proxy will not be used."));
97 return 0;
98 }
99 return port;
100 }
101
102 /**
103 * Initializes the proxy selector from the setting in the preferences.
104 *
105 */
106 public void initFromPreferences() {
107 String value = Main.pref.get(ProxyPreferencesPanel.PROXY_POLICY);
108 if (value.length() == 0) {
109 proxyPolicy = ProxyPolicy.NO_PROXY;
110 } else {
111 proxyPolicy = ProxyPolicy.fromName(value);
112 if (proxyPolicy == null) {
113 Main.warn(tr("Unexpected value for preference ''{0}'' found. Got ''{1}''. Will use no proxy.", ProxyPreferencesPanel.PROXY_POLICY, value));
114 proxyPolicy = ProxyPolicy.NO_PROXY;
115 }
116 }
117 String host = Main.pref.get(ProxyPreferencesPanel.PROXY_HTTP_HOST, null);
118 int port = parseProxyPortValue(ProxyPreferencesPanel.PROXY_HTTP_PORT, Main.pref.get(ProxyPreferencesPanel.PROXY_HTTP_PORT, null));
119 httpProxySocketAddress = null;
120 if (proxyPolicy.equals(ProxyPolicy.USE_HTTP_PROXY)) {
121 if (host != null && !host.trim().isEmpty() && port > 0) {
122 httpProxySocketAddress = new InetSocketAddress(host, port);
123 } else {
124 Main.warn(tr("Unexpected parameters for HTTP proxy. Got host ''{0}'' and port ''{1}''.", host, port));
125 Main.warn(tr("The proxy will not be used."));
126 }
127 }
128
129 host = Main.pref.get(ProxyPreferencesPanel.PROXY_SOCKS_HOST, null);
130 port = parseProxyPortValue(ProxyPreferencesPanel.PROXY_SOCKS_PORT, Main.pref.get(ProxyPreferencesPanel.PROXY_SOCKS_PORT, null));
131 socksProxySocketAddress = null;
132 if (proxyPolicy.equals(ProxyPolicy.USE_SOCKS_PROXY)) {
133 if (host != null && !host.trim().isEmpty() && port > 0) {
134 socksProxySocketAddress = new InetSocketAddress(host,port);
135 } else {
136 Main.warn(tr("Unexpected parameters for SOCKS proxy. Got host ''{0}'' and port ''{1}''.", host, port));
137 Main.warn(tr("The proxy will not be used."));
138 }
139 }
140 }
141
142 @Override
143 public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
144 // Just log something. The network stack will also throw an exception which will be caught somewhere else
145 Main.error(tr("Connection to proxy ''{0}'' for URI ''{1}'' failed. Exception was: {2}", sa.toString(), uri.toString(), ioe.toString()));
146 // Remember errors to give a friendly user message asking to review proxy configuration
147 errorResources.add(uri.toString());
148 errorMessages.add(ioe.toString());
149 }
150
151 /**
152 * Returns the set of current proxy resources that failed to be retrieved.
153 * @return the set of current proxy resources that failed to be retrieved
154 * @since 6523
155 */
156 public final Set<String> getErrorResources() {
157 return new TreeSet<String>(errorResources);
158 }
159
160 /**
161 * Returns the set of current proxy error messages.
162 * @return the set of current proxy error messages
163 * @since 6523
164 */
165 public final Set<String> getErrorMessages() {
166 return new TreeSet<String>(errorMessages);
167 }
168
169 /**
170 * Clear the sets of failed resources and error messages.
171 * @since 6523
172 */
173 public final void clearErrors() {
174 errorResources.clear();
175 errorMessages.clear();
176 }
177
178 /**
179 * Determines if proxy errors have occured.
180 * @return {@code true} if errors have occured, {@code false} otherwise.
181 * @since 6523
182 */
183 public final boolean hasErrors() {
184 return !errorResources.isEmpty();
185 }
186
187 @Override
188 public List<Proxy> select(URI uri) {
189 if (uri != null && "localhost".equals(uri.getHost())) {
190 return NO_PROXY_LIST;
191 }
192 switch(proxyPolicy) {
193 case USE_SYSTEM_SETTINGS:
194 if (!JVM_WILL_USE_SYSTEM_PROXIES) {
195 Main.warn(tr("The JVM is not configured to lookup proxies from the system settings. The property ''java.net.useSystemProxies'' was missing at startup time. Will not use a proxy."));
196 return NO_PROXY_LIST;
197 }
198 // delegate to the former proxy selector
199 return delegate.select(uri);
200 case NO_PROXY:
201 return NO_PROXY_LIST;
202 case USE_HTTP_PROXY:
203 if (httpProxySocketAddress == null)
204 return NO_PROXY_LIST;
205 return Collections.singletonList(new Proxy(Type.HTTP, httpProxySocketAddress));
206 case USE_SOCKS_PROXY:
207 if (socksProxySocketAddress == null)
208 return NO_PROXY_LIST;
209 return Collections.singletonList(new Proxy(Type.SOCKS, socksProxySocketAddress));
210 }
211 // should not happen
212 return null;
213 }
214}
Note: See TracBrowser for help on using the repository browser.