JDK-4697272 : HttpClient should fall back to connecting locally if rejected by instProxy
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 1.4.1
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_2.6
  • CPU: generic
  • Submitted: 2002-06-05
  • Updated: 2003-03-26
  • Resolved: 2003-03-26
Related Reports
Duplicate :  
Description
The java plugin will not connect (an exception will be thrown) to the http URL outside the firewall under the following circumstances:

1. The socks proxy is specified in the PLUGIN CONTROL PANEL 
2. The http proxy is specified in the PLUGIN CONTROL PANEL

However, the plugin will work if both proxies are set using 
-D properties to the java runtime (and not through the control 
panel). Same setup works fine in appletviewer since appletviewer
doesn't have a control panel.

To reproduce:

- please use Netscape 6 with the JDK 1.4 plugin
- set the proxies in the plugin control panel to:
  socks: scaea-socks-1.sun.com port 1080
  http: wcscaa.sfbay.sun.com port 8080
- type http://www.chessclub.com/CoffeeHouse.html in the browser

You will see the following exception in java console:

======================================================================
java.net.SocketException: SOCKS: Connection not allowed by ruleset
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:405)
	at java.net.Socket.connect(Socket.java:425)
	at java.net.Socket.connect(Socket.java:375)
	at sun.net.NetworkClient.doConnect(NetworkClient.java:139)
	at sun.plugin.net.protocol.http.HttpClient.doConnect(HttpClient.java:95)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:366)
	at sun.net.www.http.HttpClient$3.run(HttpClient.java:415)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.net.www.http.HttpClient.privilegedOpenServer(HttpClient.java:412)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:559)
	at sun.net.www.http.HttpClient.<init>(HttpClient.java:292)
	at sun.net.www.http.HttpClient.<init>(HttpClient.java:253)
	at sun.plugin.net.protocol.http.HttpClient.<init>(HttpClient.java:41)
	at sun.plugin.net.protocol.http.HttpClient.New(HttpClient.java:68)
	at sun.plugin.net.protocol.http.HttpURLConnection.privBlock(HttpURLConnection.java:105)
	at sun.plugin.net.protocol.http.HttpURLConnection$PrivilegedBlockAction.run(HttpURLConnection.java:378)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.plugin.net.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:149)
	at sun.plugin.net.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:309)
	at sun.plugin.net.protocol.http.HttpUtils.followRedirects(HttpUtils.java:39)
	at sun.plugin.cache.CachedJarLoader.download(CachedJarLoader.java:311)
	at sun.plugin.cache.CachedJarLoader.load(CachedJarLoader.java:131)
	at sun.plugin.cache.JarCache.get(JarCache.java:177)
	at sun.plugin.net.protocol.jar.CachedJarURLConnection.connect(CachedJarURLConnection.java:71)
	at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFile(CachedJarURLConnection.java:56)
	at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:498)
	at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:459)
	at sun.misc.URLClassPath$2.run(URLClassPath.java:255)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.misc.URLClassPath.getLoader(URLClassPath.java:244)
	at sun.misc.URLClassPath.getLoader(URLClassPath.java:221)
	at sun.misc.URLClassPath.getResource(URLClassPath.java:134)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:190)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:186)
	at sun.applet.AppletClassLoader.findClass(AppletClassLoader.java:132)
	at sun.plugin.security.PluginClassLoader.findClass(PluginClassLoader.java:189)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at sun.applet.AppletClassLoader.loadClass(AppletClassLoader.java:112)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:262)
	at sun.applet.AppletClassLoader.loadCode(AppletClassLoader.java:473)
	at sun.applet.AppletPanel.createApplet(AppletPanel.java:548)
	at sun.plugin.AppletViewer.createApplet(AppletViewer.java:1621)
	at sun.applet.AppletPanel.runLoader(AppletPanel.java:477)
	at sun.applet.AppletPanel.run(AppletPanel.java:290)
	at java.lang.Thread.run(Thread.java:536)
  
=======================================================================

a) You see this exception because the plugin will attempt to make the 
following connection: plugin -> socks proxy -> http proxy -> external URL.
However, socks proxy "scaea-socks-1" doesn't allow connections to inside the firewall (this is a typical config). So, such connection will fail. This is 
CORRECT behavior. 

However, after that the code executed by plugin returns with an error and
the exception above is thrown. This is NOT CORRECT.

b) However, if the proxies are set using -D options (and not through the plugin
control panel), then HttpClient's openServer() will ignore the "connection fail" IOException and will fall back to the following logic:

plugin -> socks proxy -> external URL

to see this, delete the "http proxy" setting in the control panel and set 
it through the -Dhttp.proxyHost option of java runtime, you will see that 
the applet will load or try the following appletviewer command:

appletviewer -J-DsocksProxyHost=scaea-socks-1 -J-Dhttp.proxyHost=wcscaa
-J-Dhttp.proxyPort=8080 http://www.chessclub.com/CoffeeHouse.html

The applet will load as well.

c) In the first case(the erroneous one), HttpClient.openServer() should also behave as in scenario "b)": 

if the http proxy is specified using the Plugin Control Panel (namely "instProxy"), then it should ignore the exception and try direct connection:

plugin -> socks proxy -> external URL

Here's the existing code:

/sun/net/www/http/HttpClient.java:

*************************************************************
protected synchronized void openServer() throws IOException {
.....
	if (url.getProtocol().equals("http") ||
	    url.getProtocol().equals("https") ) {
	    
	    if ((instProxy != null) && !loopback) {
		privilegedOpenServer(instProxy, instProxyPort);
		usingProxy = true;
		return;
	    }

	    String proxyHost = getProxyHost();
	    if ((proxyHost != null) &&
		(!(proxyDisabled ||
		   loopback ||
		   matchNonProxyHosts(urlHost) ||
		   matchNonProxyHosts(host)))) {
		try {
		    int proxyPort = getProxyPort();
		    privilegedOpenServer(proxyHost, proxyPort);
		    instProxy = proxyHost;
		    instProxyPort = proxyPort;
		    usingProxy = true;
		    return;
		} catch (IOException e) {
		    // continue in this case - try locally
		}
	    }
	    // try locally - let Exception get raised
	    openServer(host, port);
	    usingProxy = false;
	    return;
....
******************************************************

Here's how it can be changed to fix the problem:

======================================================
	if (url.getProtocol().equals("http") ||
	    url.getProtocol().equals("https") ) {
	    
	    try {
                if ((instProxy != null) && !loopback) {
		    privilegedOpenServer(instProxy, instProxyPort);
	   	    usingProxy = true;
		    return;
	        }
            } catch (IOException e) {
                // continue in this case - try locally
                // try locally - let Exception get raised
                // this case is not any different from 
                // using -Dhttp.proxyHost below and should 
                // be handled the same way
	        openServer(host, port);
	        usingProxy = false;
	        return;
            }

	    String proxyHost = getProxyHost();
	    if ((proxyHost != null) &&
		(!(proxyDisabled ||
		   loopback ||
		   matchNonProxyHosts(urlHost) ||
		   matchNonProxyHosts(host)))) {
		try {
		    int proxyPort = getProxyPort();
		    privilegedOpenServer(proxyHost, proxyPort);
		    instProxy = proxyHost;
		    instProxyPort = proxyPort;
		    usingProxy = true;
		    return;
		} catch (IOException e) {
		    // continue in this case - try locally
		}
	    }
	    // try locally - let Exception get raised
	    openServer(host, port);
	    usingProxy = false;
	    return;
===============================================================
 


Comments
EVALUATION There shouldn't be a different behavior depending on how the proxies were set. And it seems the proposed fix make sense. We will fix this in Mantis. ###@###.### 2002-06-06 This appears to need the http proxy setting to take precedence over the SOCKS proxy setting (for http) and also the ability to change proxy settings dynamically. These features are covered by 4097826. ###@###.### 2003-03-26
26-03-2003