KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > httpclient > contrib > proxy > PluginProxyUtil


1 /*
2  * $HeadURL: https://svn.apache.org/repos/asf/jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/proxy/PluginProxyUtil.java $
3  * $Revision: 480424 $
4  * $Date: 2006-11-29 05:56:49 +0000 (Wed, 29 Nov 2006) $
5  *
6  * ====================================================================
7  *
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
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
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  * ====================================================================
23  *
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/>.
28  *
29  */

30 package org.apache.commons.httpclient.contrib.proxy;
31
32 import java.lang.reflect.Array JavaDoc;
33 import java.lang.reflect.Method JavaDoc;
34 import java.net.URL JavaDoc;
35 import java.util.Properties JavaDoc;
36
37 import org.apache.commons.httpclient.ProxyHost;
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41 /**
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
44  * forum here:
45  * http://forum.java.sun.com/thread.jspa?threadID=364342&tstart=120
46  *
47  * The algorithm - which relies on Sun java plugin internal classes in some
48  * cases - was maintained, but the following changes were made:
49  *
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.
57  *
58  * <p>
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.
62  * </p>
63  */

64 public class PluginProxyUtil {
65     
66     /** Log object for this class */
67     private static final Log LOG = LogFactory.getLog(PluginProxyUtil.class);
68     
69     /**
70      * This is used internally to indicate that no proxy detection succeeded
71      * and no proxy setting is to be used - failover is unnecessary
72      */

73     private static final ProxyHost NO_PROXY_HOST = new ProxyHost("",80);
74     
75     /**
76      * The system property that is used to convey proxy information in some VM's
77      */

78     private static final String JavaDoc PLUGIN_PROXY_CONFIG_PROP =
79                                                 "javaplugin.proxy.config.list";
80     
81     /**
82      * Returns the Proxy Host information using settings from the java plugin.
83      *
84      * @param sampleURL the url target for which proxy host information is
85      * required
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
89      */

90     public static ProxyHost detectProxy(URL JavaDoc sampleURL)
91         throws ProxyDetectionException
92     {
93         
94         ProxyHost result = null;
95         String JavaDoc javaVers = System.getProperty("java.runtime.version");
96         
97         if (LOG.isDebugEnabled()) {
98             LOG.debug("About to attempt auto proxy detection under Java " +
99                       "version:"+javaVers);
100         }
101         
102         // If specific, known detection methods fail may try fallback
103
// detection method
104
boolean invokeFailover = false;
105      
106         if (javaVers.startsWith("1.3")) {
107             result = detectProxySettingsJDK13(sampleURL);
108             if (result == null) {
109                 invokeFailover = true;
110             }
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;
115             }
116         } else {
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...");
120             }
121             invokeFailover = true;
122         }
123         if (invokeFailover) {
124             if (LOG.isDebugEnabled()) {
125                 LOG.debug("Using failover proxy detection...");
126             }
127             result = getPluginProxyConfigSettings();
128         }
129         if (NO_PROXY_HOST.equals(result)) {
130             result = null;
131         }
132         return result;
133     }
134
135     /**
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...
139      *
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
143      */

144     private static ProxyHost detectProxySettingsJDK13(URL JavaDoc sampleURL)
145         throws ProxyDetectionException
146     {
147         ProxyHost result = null;
148         try {
149             // Attempt to discover proxy info by asking internal plugin
150
// code to locate proxy path to server sampleURL...
151
Class JavaDoc pluginProxyHandler =
152                 Class.forName("sun.plugin.protocol.PluginProxyHandler");
153             Method JavaDoc getDefaultProxyHandlerMethod =
154                 pluginProxyHandler.getDeclaredMethod("getDefaultProxyHandler",
155                                                      null);
156             Object JavaDoc proxyHandlerObj =
157                 getDefaultProxyHandlerMethod.invoke(null, null);
158             if (proxyHandlerObj != null) {
159                 Class JavaDoc proxyHandlerClass = proxyHandlerObj.getClass();
160                 Method JavaDoc getProxyInfoMethod =
161                     proxyHandlerClass.getDeclaredMethod("getProxyInfo",
162                                                         new Class JavaDoc[]{URL JavaDoc.class});
163                 Object JavaDoc proxyInfoObject =
164                     getProxyInfoMethod.invoke(proxyHandlerObj,
165                                               new Object JavaDoc[] { sampleURL });
166                 if (proxyInfoObject != null) {
167                     Class JavaDoc proxyInfoClass = proxyInfoObject.getClass();
168                     Method JavaDoc getProxyMethod =
169                         proxyInfoClass.getDeclaredMethod("getProxy", null);
170                     boolean useProxy =
171                         (getProxyMethod.invoke(proxyInfoObject, null) != null);
172                     if (useProxy) {
173                         String JavaDoc proxyIP =
174                             (String JavaDoc)getProxyMethod.invoke(proxyInfoObject, null);
175                         Method JavaDoc getProxyPortMethod =
176                             proxyInfoClass.getDeclaredMethod("getPort", null);
177                         Integer JavaDoc portInteger =
178                             (Integer JavaDoc)getProxyPortMethod.invoke(proxyInfoObject, null);
179                         int proxyPort = portInteger.intValue();
180                         if (LOG.isDebugEnabled()) {
181                             LOG.debug("1.3.X: proxy=" + proxyIP+
182                                       " port=" + proxyPort);
183                         }
184                         result = new ProxyHost(proxyIP, proxyPort);
185                     } else {
186                         if (LOG.isDebugEnabled()) {
187                             LOG.debug("1.3.X reported NULL for " +
188                                       "proxyInfo.getProxy (no proxy assumed)");
189                         }
190                         result = NO_PROXY_HOST;
191                     }
192                 } else {
193                     if (LOG.isDebugEnabled()) {
194                         LOG.debug("NULL proxyInfo in 1.3.X auto proxy " +
195                                        "detection, (no proxy assumed)");
196                     }
197                     result = NO_PROXY_HOST;
198                 }
199             } else {
200                 throw new ProxyDetectionException(
201                   "Sun Plugin 1.3.X failed to provide a default proxy handler");
202             }
203         } catch (Exception JavaDoc e) {
204             LOG.warn("Sun Plugin 1.3.X proxy detection class not " +
205                      "found, will try failover detection, e:"+e);
206         }
207         return result;
208     }
209     
210     /**
211      * Returns the proxy information for the specified sampleURL using JRE 1.4
212      * specific plugin classes.
213      *
214      * Notes:
215      * Plugin 1.4 Final added
216      * com.sun.java.browser.net.* classes ProxyInfo & ProxyService...
217      * Use those with JREs => 1.4
218      *
219      * @param sampleURL the URL to check proxy settings for
220      * @return ProxyHost the host and port of the proxy that should be used
221      */

222     private static ProxyHost detectProxySettingsJDK14_JDK15_JDK16(URL JavaDoc sampleURL) {
223         ProxyHost result = null;
224         try {
225             // Look around for the 1.4.X plugin proxy detection class...
226
// Without it, cannot autodetect...
227
Class JavaDoc ProxyServiceClass =
228                 Class.forName("com.sun.java.browser.net.ProxyService");
229             Method JavaDoc getProxyInfoMethod =
230                 ProxyServiceClass.getDeclaredMethod("getProxyInfo",
231                                                     new Class JavaDoc[] {URL JavaDoc.class});
232             Object JavaDoc proxyInfoArrayObj =
233                 getProxyInfoMethod.invoke(null, new Object JavaDoc[] {sampleURL});
234             
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)");
239                 }
240                 result = NO_PROXY_HOST;
241             } else {
242                 Object JavaDoc proxyInfoObject = Array.get(proxyInfoArrayObj, 0);
243                 Class JavaDoc proxyInfoClass = proxyInfoObject.getClass();
244                 Method JavaDoc getHostMethod =
245                     proxyInfoClass.getDeclaredMethod("getHost",null);
246                 String JavaDoc proxyIP =
247                     (String JavaDoc)getHostMethod.invoke(proxyInfoObject, null);
248                 Method JavaDoc getPortMethod =
249                     proxyInfoClass.getDeclaredMethod("getPort",null);
250                 Integer JavaDoc portInteger =
251                     (Integer JavaDoc)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);
256                 }
257                 result = new ProxyHost(proxyIP, proxyPort);
258             }
259         } catch (Exception JavaDoc e) {
260             e.printStackTrace();
261             LOG.warn("Sun Plugin 1.4.X proxy detection class not found, " +
262                      "will try failover detection, e:"+e);
263         }
264         return result;
265     }
266     
267     /**
268      * Returns the proxy host information found by inspecting the system
269      * property "javaplugin.proxy.config.list".
270      *
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
275      */

276     private static ProxyHost getPluginProxyConfigSettings()
277         throws ProxyDetectionException
278     {
279         ProxyHost result = null;
280         try {
281             Properties JavaDoc properties = System.getProperties();
282             String JavaDoc proxyList =
283                 properties.getProperty("javaplugin.proxy.config.list");
284             if (LOG.isDebugEnabled()) {
285                 LOG.debug("Plugin Proxy Config List Property:"+proxyList);
286             }
287             boolean useProxy = (proxyList != null);
288             if (useProxy) {
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...
296
String JavaDoc proxyIP="";
297                 if (proxyList.indexOf("HTTP=") > -1) {
298                     proxyIP =
299                         proxyList.substring(proxyList.indexOf("HTTP=")+5,
300                                             proxyList.indexOf(":"));
301                 } else {
302                     proxyIP = proxyList.substring(0, proxyList.indexOf(":"));
303                 }
304                 int endOfPort = proxyList.indexOf(",");
305                 if (endOfPort < 1) endOfPort = proxyList.length();
306                 String JavaDoc portString =
307                     proxyList.substring(proxyList.indexOf(":")+1,endOfPort);
308                 int proxyPort = Integer.parseInt(portString);
309                 if (LOG.isDebugEnabled()) {
310                     LOG.debug("proxy " + proxyIP+" port " + proxyPort);
311                 }
312                 result = new ProxyHost(proxyIP, proxyPort);
313             } else {
314                 LOG.debug("No configured plugin proxy list");
315                 result = NO_PROXY_HOST;
316             }
317         } catch (Exception JavaDoc e) {
318             if (LOG.isDebugEnabled()) {
319                 LOG.debug("Exception during failover auto proxy detection, " +
320                           ", e:"+e);
321                 throw new ProxyDetectionException(
322                         "Encountered unexpected exception while attempting " +
323                         "to parse proxy information stored in "+
324                         PLUGIN_PROXY_CONFIG_PROP, e);
325             }
326         }
327         return result;
328     }
329 }
330
Popular Tags