-
Bug
-
Resolution: Not an Issue
-
P3
-
None
-
8u111
-
generic
-
generic
FULL PRODUCT VERSION :
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Darwin Donalds-MacBook-Pro.local 15.6.0 Darwin Kernel Version 15.6.0: Mon Aug 29 20:21:34 PDT 2016; root:xnu-3248.60.11~1/RELEASE_X86_64 x86_64
A DESCRIPTION OF THE PROBLEM :
If you make an HttpURLConnection to a url that uses the HTTPS protocol, the default Authenticator is not called to retrieve the proxy authentication credentials. This ends up with the proxy returning a 407 http code.
REGRESSION. Last worked in version 8u92
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
have a proxy available to call the ultimate HTTPS url.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
a 200 http code along with the resulting message.
ACTUAL -
407 Proxy Authentication Required
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 Proxy Authentication Required"
at sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:2124)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:183)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1546)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at testProxyAccess.HTTPProxyDemo.getResponse(HTTPProxyDemo.java:35)
at testProxyAccess.HTTPProxyDemo.<init>(HTTPProxyDemo.java:24)
at testProxyAccess.HTTPProxyDemo.main(HTTPProxyDemo.java:15)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package testProxyAccess;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.util.zip.GZIPInputStream;
public class HTTPProxyDemo {
public static void main(String[] args) {
new HTTPProxyDemo();
}
public HTTPProxyDemo(){
StaticaProxyAuthenticator proxy = new StaticaProxyAuthenticator();
Authenticator.setDefault(proxy.getAuth());
String testUrl = "https://httpbin.org/get";
System.out.println(getResponse(proxy, testUrl));
}
public String getResponse(StaticaProxyAuthenticator proxy, String urlToRead) {
String result = "";
try {
URL url = new URL(urlToRead);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Accept-Encoding", "gzip");
conn.setRequestMethod("GET");
InputStream is = conn.getInputStream();
if(conn.getContentEncoding()!=null && conn.getContentEncoding().equalsIgnoreCase("gzip")){
is = new GZIPInputStream(is);
}
byte[] buffer = new byte[1024];
int len;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while (-1 != (len = is.read(buffer))) {
bos.write(buffer, 0, len);
}
result = new String(bos.toByteArray());
is.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
class StaticaProxyAuthenticator extends Authenticator {
private String user, password, host;
private int port;
private ProxyAuthenticator auth;
public StaticaProxyAuthenticator() {
String proxyUrlEnv = "http://proxyuser:proxypw@proxyhost:proxyport";
try {
URL proxyUrl = new URL(proxyUrlEnv);
String authString = proxyUrl.getUserInfo();
user = authString.split(":")[0];
password = authString.split(":")[1];
host = proxyUrl.getHost();
port = proxyUrl.getPort();
auth = new ProxyAuthenticator(user, password);
setProxy();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
private void setProxy() {
System.setProperty("http.proxyHost", host);
System.setProperty("http.proxyPort", String.valueOf(port));
System.setProperty("https.proxyHost", host);
System.setProperty("https.proxyPort", String.valueOf(port));
}
public String getEncodedAuth() {
// If not using Java8 you will have to use another Base64 encoded, e.g.
// apache commons codec.
String encoded = java.util.Base64.getEncoder().encodeToString((user + ":" + password).getBytes());
return encoded;
}
public ProxyAuthenticator getAuth() {
return auth;
}
class ProxyAuthenticator extends Authenticator {
private String user, password;
public ProxyAuthenticator(String user, String password) {
this.user = user;
this.password = password;
}
protected PasswordAuthentication getPasswordAuthentication() {
System.out.println("authenticate");
return new PasswordAuthentication(user, password.toCharArray());
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Revert to older version of JVM
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Darwin Donalds-MacBook-Pro.local 15.6.0 Darwin Kernel Version 15.6.0: Mon Aug 29 20:21:34 PDT 2016; root:xnu-3248.60.11~1/RELEASE_X86_64 x86_64
A DESCRIPTION OF THE PROBLEM :
If you make an HttpURLConnection to a url that uses the HTTPS protocol, the default Authenticator is not called to retrieve the proxy authentication credentials. This ends up with the proxy returning a 407 http code.
REGRESSION. Last worked in version 8u92
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
have a proxy available to call the ultimate HTTPS url.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
a 200 http code along with the resulting message.
ACTUAL -
407 Proxy Authentication Required
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 Proxy Authentication Required"
at sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:2124)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:183)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1546)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at testProxyAccess.HTTPProxyDemo.getResponse(HTTPProxyDemo.java:35)
at testProxyAccess.HTTPProxyDemo.<init>(HTTPProxyDemo.java:24)
at testProxyAccess.HTTPProxyDemo.main(HTTPProxyDemo.java:15)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package testProxyAccess;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.util.zip.GZIPInputStream;
public class HTTPProxyDemo {
public static void main(String[] args) {
new HTTPProxyDemo();
}
public HTTPProxyDemo(){
StaticaProxyAuthenticator proxy = new StaticaProxyAuthenticator();
Authenticator.setDefault(proxy.getAuth());
String testUrl = "https://httpbin.org/get";
System.out.println(getResponse(proxy, testUrl));
}
public String getResponse(StaticaProxyAuthenticator proxy, String urlToRead) {
String result = "";
try {
URL url = new URL(urlToRead);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Accept-Encoding", "gzip");
conn.setRequestMethod("GET");
InputStream is = conn.getInputStream();
if(conn.getContentEncoding()!=null && conn.getContentEncoding().equalsIgnoreCase("gzip")){
is = new GZIPInputStream(is);
}
byte[] buffer = new byte[1024];
int len;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while (-1 != (len = is.read(buffer))) {
bos.write(buffer, 0, len);
}
result = new String(bos.toByteArray());
is.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
class StaticaProxyAuthenticator extends Authenticator {
private String user, password, host;
private int port;
private ProxyAuthenticator auth;
public StaticaProxyAuthenticator() {
String proxyUrlEnv = "http://proxyuser:proxypw@proxyhost:proxyport";
try {
URL proxyUrl = new URL(proxyUrlEnv);
String authString = proxyUrl.getUserInfo();
user = authString.split(":")[0];
password = authString.split(":")[1];
host = proxyUrl.getHost();
port = proxyUrl.getPort();
auth = new ProxyAuthenticator(user, password);
setProxy();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
private void setProxy() {
System.setProperty("http.proxyHost", host);
System.setProperty("http.proxyPort", String.valueOf(port));
System.setProperty("https.proxyHost", host);
System.setProperty("https.proxyPort", String.valueOf(port));
}
public String getEncodedAuth() {
// If not using Java8 you will have to use another Base64 encoded, e.g.
// apache commons codec.
String encoded = java.util.Base64.getEncoder().encodeToString((user + ":" + password).getBytes());
return encoded;
}
public ProxyAuthenticator getAuth() {
return auth;
}
class ProxyAuthenticator extends Authenticator {
private String user, password;
public ProxyAuthenticator(String user, String password) {
this.user = user;
this.password = password;
}
protected PasswordAuthentication getPasswordAuthentication() {
System.out.println("authenticate");
return new PasswordAuthentication(user, password.toCharArray());
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Revert to older version of JVM