2
* $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/oac.hc3x/tags/HTTPCLIENT_3_1/src/contrib/org/apache/commons/httpclient/contrib/proxy/PluginProxyUtil.java $
4
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
6
* ====================================================================
8
* Licensed to the Apache Software Foundation (ASF) under one or more
9
* contributor license agreements. See the NOTICE file distributed with
10
* this work for additional information regarding copyright ownership.
11
* The ASF licenses this file to You under the Apache License, Version 2.0
12
* (the "License"); you may not use this file except in compliance with
13
* the License. You may obtain a copy of the License at
15
* http://www.apache.org/licenses/LICENSE-2.0
17
* Unless required by applicable law or agreed to in writing, software
18
* distributed under the License is distributed on an "AS IS" BASIS,
19
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
* See the License for the specific language governing permissions and
21
* limitations under the License.
22
* ====================================================================
24
* This software consists of voluntary contributions made by many
25
* individuals on behalf of the Apache Software Foundation. For more
26
* information on the Apache Software Foundation, please see
27
* <http://www.apache.org/>.
30
package org.apache.commons.httpclient.contrib.proxy;
32
import java.lang.reflect.Array;
33
import java.lang.reflect.Method;
35
import java.util.Properties;
37
import org.apache.commons.httpclient.ProxyHost;
38
import org.apache.commons.logging.Log;
39
import org.apache.commons.logging.LogFactory;
42
* A utility class that gives applets the ability to detect proxy host settings.
43
* This was adapted from a post from Chris Forster on 20030227 to a Sun Java
45
* http://forum.java.sun.com/thread.jspa?threadID=364342&tstart=120
47
* The algorithm - which relies on Sun java plugin internal classes in some
48
* cases - was maintained, but the following changes were made:
50
* 1. Logging was used to allow control of debug type messages.
51
* 2. Reflection is used instead of direct references to Sun internal classes
52
* to avoid the need to have these classes in the CLASSPATH to compile.
53
* 3. Removed the use of global variables to allow this class to be used in
54
* a multi-threaded environment.
55
* 4. Add the use of exception to indicate to the caller when proxy detection
56
* failed as opposed to when no proxy is configured.
59
* DISCLAIMER: HttpClient developers DO NOT actively support this component.
60
* The component is provided as a reference material, which may be inappropriate
61
* for use without additional customization.
64
public class PluginProxyUtil {
66
/** Log object for this class */
67
private static final Log LOG = LogFactory.getLog(PluginProxyUtil.class);
70
* This is used internally to indicate that no proxy detection succeeded
71
* and no proxy setting is to be used - failover is unnecessary
73
private static final ProxyHost NO_PROXY_HOST = new ProxyHost("",80);
76
* The system property that is used to convey proxy information in some VM's
78
private static final String PLUGIN_PROXY_CONFIG_PROP =
79
"javaplugin.proxy.config.list";
82
* Returns the Proxy Host information using settings from the java plugin.
84
* @param sampleURL the url target for which proxy host information is
86
* @return the proxy host info (name and port) or null if a direct
87
* connection is allowed to the target url.
88
* @throws ProxyDetectionException if detection failed
90
public static ProxyHost detectProxy(URL sampleURL)
91
throws ProxyDetectionException
94
ProxyHost result = null;
95
String javaVers = System.getProperty("java.runtime.version");
97
if (LOG.isDebugEnabled()) {
98
LOG.debug("About to attempt auto proxy detection under Java " +
102
// If specific, known detection methods fail may try fallback
104
boolean invokeFailover = false;
106
if (javaVers.startsWith("1.3")) {
107
result = detectProxySettingsJDK13(sampleURL);
108
if (result == null) {
109
invokeFailover = true;
111
} else if (javaVers.startsWith("1.4") || (javaVers.startsWith("1.5") || javaVers.startsWith("1.6"))) {
112
result = detectProxySettingsJDK14_JDK15_JDK16(sampleURL);
113
if (result == null) {
114
invokeFailover = true;
117
if (LOG.isDebugEnabled()) {
118
LOG.debug("Sun Plugin reported java version not 1.3.X, " +
119
"1.4.X, 1.5.X or 1.6.X - trying failover detection...");
121
invokeFailover = true;
123
if (invokeFailover) {
124
if (LOG.isDebugEnabled()) {
125
LOG.debug("Using failover proxy detection...");
127
result = getPluginProxyConfigSettings();
129
if (NO_PROXY_HOST.equals(result)) {
136
* Use Sun-specific internal plugin proxy classes for 1.3.X
137
* Look around for the 1.3.X plugin proxy detection class. Without it,
138
* cannot autodetect...
140
* @param sampleURL the URL to check proxy settings for
141
* @return ProxyHost the host and port of the proxy that should be used
142
* @throws ProxyDetectionException if detection failed
144
private static ProxyHost detectProxySettingsJDK13(URL sampleURL)
145
throws ProxyDetectionException
147
ProxyHost result = null;
149
// Attempt to discover proxy info by asking internal plugin
150
// code to locate proxy path to server sampleURL...
151
Class pluginProxyHandler =
152
Class.forName("sun.plugin.protocol.PluginProxyHandler");
153
Method getDefaultProxyHandlerMethod =
154
pluginProxyHandler.getDeclaredMethod("getDefaultProxyHandler",
156
Object proxyHandlerObj =
157
getDefaultProxyHandlerMethod.invoke(null, null);
158
if (proxyHandlerObj != null) {
159
Class proxyHandlerClass = proxyHandlerObj.getClass();
160
Method getProxyInfoMethod =
161
proxyHandlerClass.getDeclaredMethod("getProxyInfo",
162
new Class[]{URL.class});
163
Object proxyInfoObject =
164
getProxyInfoMethod.invoke(proxyHandlerObj,
165
new Object[] { sampleURL });
166
if (proxyInfoObject != null) {
167
Class proxyInfoClass = proxyInfoObject.getClass();
168
Method getProxyMethod =
169
proxyInfoClass.getDeclaredMethod("getProxy", null);
171
(getProxyMethod.invoke(proxyInfoObject, null) != null);
174
(String)getProxyMethod.invoke(proxyInfoObject, null);
175
Method getProxyPortMethod =
176
proxyInfoClass.getDeclaredMethod("getPort", null);
177
Integer portInteger =
178
(Integer)getProxyPortMethod.invoke(proxyInfoObject, null);
179
int proxyPort = portInteger.intValue();
180
if (LOG.isDebugEnabled()) {
181
LOG.debug("1.3.X: proxy=" + proxyIP+
182
" port=" + proxyPort);
184
result = new ProxyHost(proxyIP, proxyPort);
186
if (LOG.isDebugEnabled()) {
187
LOG.debug("1.3.X reported NULL for " +
188
"proxyInfo.getProxy (no proxy assumed)");
190
result = NO_PROXY_HOST;
193
if (LOG.isDebugEnabled()) {
194
LOG.debug("NULL proxyInfo in 1.3.X auto proxy " +
195
"detection, (no proxy assumed)");
197
result = NO_PROXY_HOST;
200
throw new ProxyDetectionException(
201
"Sun Plugin 1.3.X failed to provide a default proxy handler");
203
} catch (Exception e) {
204
LOG.warn("Sun Plugin 1.3.X proxy detection class not " +
205
"found, will try failover detection, e:"+e);
211
* Returns the proxy information for the specified sampleURL using JRE 1.4
212
* specific plugin classes.
215
* Plugin 1.4 Final added
216
* com.sun.java.browser.net.* classes ProxyInfo & ProxyService...
217
* Use those with JREs => 1.4
219
* @param sampleURL the URL to check proxy settings for
220
* @return ProxyHost the host and port of the proxy that should be used
222
private static ProxyHost detectProxySettingsJDK14_JDK15_JDK16(URL sampleURL) {
223
ProxyHost result = null;
225
// Look around for the 1.4.X plugin proxy detection class...
226
// Without it, cannot autodetect...
227
Class ProxyServiceClass =
228
Class.forName("com.sun.java.browser.net.ProxyService");
229
Method getProxyInfoMethod =
230
ProxyServiceClass.getDeclaredMethod("getProxyInfo",
231
new Class[] {URL.class});
232
Object proxyInfoArrayObj =
233
getProxyInfoMethod.invoke(null, new Object[] {sampleURL});
235
if (proxyInfoArrayObj == null
236
|| Array.getLength(proxyInfoArrayObj) == 0) {
237
if (LOG.isDebugEnabled()) {
238
LOG.debug("1.4.X reported NULL proxy (no proxy assumed)");
240
result = NO_PROXY_HOST;
242
Object proxyInfoObject = Array.get(proxyInfoArrayObj, 0);
243
Class proxyInfoClass = proxyInfoObject.getClass();
244
Method getHostMethod =
245
proxyInfoClass.getDeclaredMethod("getHost",null);
247
(String)getHostMethod.invoke(proxyInfoObject, null);
248
Method getPortMethod =
249
proxyInfoClass.getDeclaredMethod("getPort",null);
250
Integer portInteger =
251
(Integer)getPortMethod.invoke(proxyInfoObject, null);
252
int proxyPort = portInteger.intValue();
253
if (LOG.isDebugEnabled()) {
254
LOG.debug("1.4.X Proxy info geProxy:"+proxyIP+
255
" get Port:"+proxyPort);
257
result = new ProxyHost(proxyIP, proxyPort);
259
} catch (Exception e) {
261
LOG.warn("Sun Plugin 1.4.X proxy detection class not found, " +
262
"will try failover detection, e:"+e);
268
* Returns the proxy host information found by inspecting the system
269
* property "javaplugin.proxy.config.list".
271
* @return ProxyHost the host and port of the proxy that should be used
272
* @throws ProxyDetectionException if an exception is encountered while
273
* parsing the value of
274
* PLUGIN_PROXY_CONFIG_PROP
276
private static ProxyHost getPluginProxyConfigSettings()
277
throws ProxyDetectionException
279
ProxyHost result = null;
281
Properties properties = System.getProperties();
283
properties.getProperty("javaplugin.proxy.config.list");
284
if (LOG.isDebugEnabled()) {
285
LOG.debug("Plugin Proxy Config List Property:"+proxyList);
287
boolean useProxy = (proxyList != null);
289
proxyList = proxyList.toUpperCase();
290
// Using HTTP proxy as proxy for HTTP proxy tunnelled SSL
291
// socket (should be listed FIRST)....
292
// 1/14/03 1.3.1_06 appears to omit HTTP portion of
293
// reported proxy list... Mod to accomodate this...
294
// Expecting proxyList of "HTTP=XXX.XXX.XXX.XXX:Port" OR
295
// "XXX.XXX.XXX.XXX:Port" & assuming HTTP...
297
if (proxyList.indexOf("HTTP=") > -1) {
299
proxyList.substring(proxyList.indexOf("HTTP=")+5,
300
proxyList.indexOf(":"));
302
proxyIP = proxyList.substring(0, proxyList.indexOf(":"));
304
int endOfPort = proxyList.indexOf(",");
305
if (endOfPort < 1) endOfPort = proxyList.length();
307
proxyList.substring(proxyList.indexOf(":")+1,endOfPort);
308
int proxyPort = Integer.parseInt(portString);
309
if (LOG.isDebugEnabled()) {
310
LOG.debug("proxy " + proxyIP+" port " + proxyPort);
312
result = new ProxyHost(proxyIP, proxyPort);
314
LOG.debug("No configured plugin proxy list");
315
result = NO_PROXY_HOST;
317
} catch (Exception e) {
318
if (LOG.isDebugEnabled()) {
319
LOG.debug("Exception during failover auto proxy detection, " +
321
throw new ProxyDetectionException(
322
"Encountered unexpected exception while attempting " +
323
"to parse proxy information stored in "+
324
PLUGIN_PROXY_CONFIG_PROP, e);