JDK-8173620 : IOException is hidden by HttpConnectSocketImpl.doTunneling
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 8,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2017-01-21
  • Updated: 2019-03-25
  • Resolved: 2019-03-25
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
With "6370908: Add support for HTTP_CONNECT proxy in Socket class"
new code for proxy handling was introduced.

In case an IOException is thrown during tunnel phase (e.g. "HTTP/1.0 407 Proxy Authentication Required") then an Error is thrown.

This is caused by wrong implementation of reflection callings in

java.net.HttpConnectSocketImpl.doTunneling(HttpURLConnection)

as there should the InvokationTargetException be caught and in case it is an IOException it should extract it and throw.

For evaluation see http://stackoverflow.com/questions/40921296/java-proxy-authentication-ioexception-not-being-thrown/

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Connect with a Socket with a proxy which requires an user/password but do not set an java.net.Authenticator.

Proxy tempProxy = new Proxy(Type.HTTP, new InetSocketAddress(config.getProxyHost(), Integer.valueOf(config.getProxyPort())));
Socket tempTargetSocket = new Socket(tempProxy);

tempTargetSocket.connect(new InetSocketAddress(tempHost, Integer.valueOf(tempPort)));



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.0 407 Proxy Authentication Required"
ACTUAL -
java.lang.InternalError: Should not reach here
	at java.net.HttpConnectSocketImpl.doTunneling(HttpConnectSocketImpl.java:181)
	at java.net.HttpConnectSocketImpl.doTunnel(HttpConnectSocketImpl.java:168)
	at java.net.HttpConnectSocketImpl.access$200(HttpConnectSocketImpl.java:44)
	at java.net.HttpConnectSocketImpl$2.run(HttpConnectSocketImpl.java:151)
	at java.net.HttpConnectSocketImpl$2.run(HttpConnectSocketImpl.java:149)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.HttpConnectSocketImpl.privilegedDoTunnel(HttpConnectSocketImpl.java:148)
	at java.net.HttpConnectSocketImpl.connect(HttpConnectSocketImpl.java:111)
	at java.net.Socket.connect(Socket.java:589)
	at java.net.Socket.connect(Socket.java:538)
	at de.quaddy_services.proxy.EscapeProxyWorkerSocket.run(EscapeProxyWorkerSocket.java:89)
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.net.HttpConnectSocketImpl.doTunneling(HttpConnectSocketImpl.java:179)
	... 10 common frames omitted
Caused by: java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.0 407 Proxy Authentication Required"
	at sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:2124)
	... 15 common frames omitted


REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
wrapp each connect with

				try {
					tempTargetSocket.connect(new InetSocketAddress(tempHost, Integer.valueOf(tempPort)));
				} catch (Error e) {
					if (e.getCause() instanceof InvocationTargetException) {
						InvocationTargetException tempInvocationTargetException = (InvocationTargetException)e.getCause();
						if (tempInvocationTargetException.getTargetException() instanceof IOException) {
							// Extract the original IOException, see
							// http://stackoverflow.com/questions/40921296/java-proxy-authentication-ioexception-not-being-thrown/
							throw (IOException)tempInvocationTargetException.getTargetException();
						}
					}
					// rethrow the original error
					throw e;
				}



Comments
JDK-8220493 changed doTunneling to handle the case where HttpConnectSocketImpl.doTunneling throws IOException.
25-03-2019

Tested the issue with the attached test case and ProxyTunnelServer class from the following path: http://hg.openjdk.java.net/jdk8u/jdk8u-dev/jdk/file/4867f8d7fbde/test/sun/net/www/protocol/http Following are the results: JDK 8u121- Fail JDK 9-ea + 153 -Fail Following is the output: Exception in thread "main" java.lang.InternalError: Should not reach here at java.base/java.net.HttpConnectSocketImpl.doTunneling(HttpConnectSocketImpl.java:181) at java.base/java.net.HttpConnectSocketImpl.doTunnel(HttpConnectSocketImpl.java:168) at java.base/java.net.HttpConnectSocketImpl.access$200(HttpConnectSocketImpl.java:44) at java.base/java.net.HttpConnectSocketImpl$2.run(HttpConnectSocketImpl.java:151) at java.base/java.net.HttpConnectSocketImpl$2.run(HttpConnectSocketImpl.java:149) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.net.HttpConnectSocketImpl.privilegedDoTunnel(HttpConnectSocketImpl.java:148) at java.base/java.net.HttpConnectSocketImpl.connect(HttpConnectSocketImpl.java:111) at java.base/java.net.Socket.connect(Socket.java:591) at java.base/java.net.Socket.connect(Socket.java:540) at TunnelThroughProxy.main(TunnelThroughProxy.java:41) Caused by: java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:543) at java.base/java.net.HttpConnectSocketImpl.doTunneling(HttpConnectSocketImpl.java:179) ... 10 more Caused by: java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 Proxy Auth Required" at java.base/sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:2144) ... 15 more
30-01-2017