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

Last change on this file since 12743 was 12620, checked in by Don-vip, 7 years ago

see #15182 - deprecate all Main logging methods and introduce suitable replacements in Logging for most of them

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