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

Last change on this file since 7004 was 6971, checked in by akks, 10 years ago

Add proxy.exceptions advanced parameter (localhost and 127.0.0.1 by default)

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