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;
}