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

Last change on this file since 12051 was 11100, checked in by Don-vip, 8 years ago

sonar - squid:S2148 - Underscores should be used to make large numbers readable

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