Java HttpsUrlConnection,连接重置

Java HttpsUrlConnection, connection reset

String url1 = "foo1.blabla.com";
String url2 = "foo2_bar.blabla.com";
URLConnection urlConnection = new URL(url1).openConnection();
urlConnection.setDoInput(true);

//Fails
InputStream in = urlConnection.getInputStream();

我们能够毫无问题地连接 url1,但他们最近将 url 更改为 url2,并声称他们只更改了 url 而没有任何更改别的。但是修改后我得到了以下异常:

java.net.SocketException: 连接重置 在 java.net.SocketInputStream.read(SocketInputStream.java:210) 在 java.net.SocketInputStream.read(SocketInputStream.java:141) 在 sun.security.ssl.InputRecord.readFully(InputRecord.java:465) 在 sun.security.ssl.InputRecord.read(InputRecord.java:503) 在 sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975) 在 sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367) 在 sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395) 在 sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379) 在 sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)

What's causing my java.net.SocketException: Connection reset?

java.net.SocketException: Connection reset

并查看以下差异:

for url1(工作正常)

SendHTTPTest.f9() connection opened Allow unsafe renegotiation: false Allow legacy hello messages: true Is initial handshake: true Is secure renegotiation: false main, the previous server name in SNI (type=host_name (0), value=foo1.blabla.com) was replaced with (type=host_name (0), value=foo1.blabla.com) Extension extended_master_secret Extension server_name, server_name: [type=host_name (0), value=foo1.blabla.com] *** main, WRITE: TLSv1.2 Handshake, length = 226 main, READ: TLSv1.2 Handshake, length = 2303 *** ServerHello, TLSv1.2

for url2(连接重置问题)

SendHTTPTest.f9() connection opened main, "foo2_bar.blabla.com" is not a legal HostName for server name indication Allow unsafe renegotiation: false Allow legacy hello messages: true Is initial handshake: true Is secure renegotiation: false main, "foo2_bar.blabla.com" is not a legal HostName for server name indication main, WRITE: TLSv1.2 Handshake, length = 193 main, handling exception: java.net.SocketException: Connection reset main, SEND TLSv1.2 ALERT: fatal, description = unexpected_message main, WRITE: TLSv1.2 Alert, length = 2 main, Exception sending alert: java.net.SocketException: Connection reset by peer: socket write error main, called closeSocket() java.net.SocketException: Connection reset

可能是消息导致 main, "foo2_bar.blabla.com" is not a legal HostName for server name indication 问题,是否与 SNI 相关? url2 中的下划线可能会导致问题?

SNI client-side mystery using Java8

(来自评论解决,搜索)

很多事情都可能导致 SSL/TLS 握手时重置,具体取决于服务器,但现在常见的是 missing Server Name Indication (SNI) .

除了一些旧版本中的错误,Java (JSSE) 在某些情况下无法发送 SNI:

  • 主机名是一个 IP 地址(v4 或 v6)

  • 主机名不包含点,或末尾有点(即 'look like' 不是 DNS 名称)

  • 主机名包含字母、数字和连字符(在 DNS 和 IDN 允许的位置)和点(在 DNS 允许的位置)以外的 ASCII 字符;此限制显然基于 STD3=RFC1123 中引用的 RFC952。 (NonASCII 字符 -- Unicode U+0080 及以上 -- 按照 IDN 规则转换为 punycode,其设计符合限制。)

本例中的问题是第三点;主机名包含一个 ASCII 下划线。