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

Last change on this file since 14628 was 14273, checked in by stoecker, 6 years ago

fix typos - patch by naoliv - fix #16781 - Thanks a lot

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