通过代理的 Java HttpsURLConnection 在 wget 工作正常时无法工作

标签 java ssl proxy httpsurlconnection

我正在设置来自外部网站的数据源,下面给出的代码适用于开发、QA 环境。它仅在生产中失败。我注意到的一件事是,Authenticator 中的 WriteToLog 没有显示在生产环境的控制台上,而它在它工作的开发和 QA 中显示。这可能是因为缺少一些库。

我在 Java 1.8 上运行。我尝试过使用 System.Setproperties 设置所有变量 https.proxyhost、proxyPort、ProxySet、用户和密码的方法。但这也没有用。设置 https_proxy 环境变量后,wget 和 curl 命令也在生产环境中工作。

try {
  Proxy ProxyName = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ProxyHostName, ProxyPortNum));
  Authenticator Credentials = new Authenticator() {
    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
      WriteToLog.info(ProxyUserId + ProxyUserKey.toCharArray());
      return (new PasswordAuthentication(ProxyUserId, ProxyUserKey.toCharArray()));
    }
  };
Authenticator.setDefault(Credentials);
DataConnection = (HttpsURLConnection) RequestURL.openConnection(ProxyName);
String uname_pwd = ProxyUserId + ":" + ProxyUserKey;
String authString = "Basic " + new sun.misc.BASE64Encoder().encode(uname_pwd.getBytes());
WriteToLog.info(authString);
DataConnection.setRequestProperty("Proxy-Authorization",authString);
WriteToLog.info(DataConnection.getRequestMethod());
return DataConnection.getInputStream();
} catch (IOException ex) {
  WriteToLog.error("HttpsConnectionReturnStream():",ex);
  throw ex;
}

我得到的错误信息是:

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:992)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1512)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
    at com.project.fetch.WebAPIReader.HttpsConnectionReturnStream(WebAPIReader.java:186)
    at com.project.fetch.WebAPIReader.WebAPIRequestTokenSubmit(WebAPIReader.java:200)
    at com.project.run.LaunchApplication.LaunchOperation(LaunchApplication.java:50)
    at com.project.run.LaunchApplication.main(LaunchApplication.java:35)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(InputRecord.java:505)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
    ... 13 more

当我添加 System.setProperty("javax.net.debug","ssl,handshake") 时,我得到了额外的信息:

main, WRITE: TLSv1.2 Handshake, length = 277
main, received EOFException: error
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
main, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure

有人可以帮我弄清楚如何调试或解决这个问题吗?我比较了调试消息返回的 QA 和 Prod 上的安全证书。他们都是匹配的。我也尝试将 Https.protocol 更改为 TLSv1。但那是行不通的。

最佳答案

我尝试硬编码 IP 地址而不是代理服务器的完全限定主机名。之后代码工作得很好。不确定为什么 JVM 在使用 ping、wget 或 curl 从命令行运行时无法解析主机名。

关于通过代理的 Java HttpsURLConnection 在 wget 工作正常时无法工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34978174/

相关文章:

http - 使用代理缓存昂贵的传出 HTTP 请求?

Java > 计算 JSON 响应中 null 和 0 的出现次数

java - JavaFX 中加载器实例化抛出空指针

ASP.NET SSL - 问题是回发,因此 OnInit 等将不起作用

Android SSL 证书固定

docker - Docker通过代理

python - python 请求库中的 https 代理支持

java - gridheight 不会影响我的按钮

java - Hibernate命名查询及其性能优势?

postgresql - 致命 : could not access private key file "/etc/ssl/private/ssl-cert-snakeoil.key": Permission denied