String currentUrl = "https://www.test.com/";
conn = (HttpsURLConnection) (currentUrl.openConnection())如果我使用domain,一切都会完美地工作。
但是,如果我使用域的ip地址,
String currentUrl = "https://123.123.123.123:443/";
conn = (HttpsURLConnection) (currentUrl.openConnection());问题发生时,我得到了SSLPeerUnverifiedException(Hostname 123.123.123.123 not verified异常,请求失败。
为了解决这个问题,我只提供了一个HostnameVerifier
conn.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
String host = "www.test.com";
return HttpsURLConnection.getDefaultHostnameVerifier().verify(host, session);
}
});此外,我还必须解决SNI情况的相同问题。
因此我提供了一个自定义SSLSocketFactory
MySSLSocketFactory sslSocketFactory = new MySSLSocketFactory(conn);
conn.setSSLSocketFactory(sslSocketFactory);
public class MySSLSocketFactory extends SSLSocketFactory{
private HttpsURLConnection conn;
public HalleySSLSocketFactory(HttpsURLConnection conn) {
this.conn = conn;
}
@Override
public Socket createSocket() throws IOException {
return null;
}
@Override
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
return null;
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost,
int localPort) throws IOException, UnknownHostException {
return null;
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return null;
}
@Override
public Socket createSocket(InetAddress address, int port,
InetAddress localAddress, int localPort) throws IOException {
return null;
}
@Override
public String[] getDefaultCipherSuites() {
return new String[0];
}
@Override
public String[] getSupportedCipherSuites() {
return new String[0];
}
@Override
public Socket createSocket(Socket plainSocket, String host, int port,
boolean autoClose) throws IOException {
String peerHost = this.conn.getRequestProperty("Host");
if (peerHost == null)
peerHost = host;
InetAddress address = plainSocket.getInetAddress();
if (autoClose) {
plainSocket.close();
}
SSLCertificateSocketFactory sslSocketFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory
.getDefault(0);
SSLSocket ssl = (SSLSocket) sslSocketFactory
.createSocket(address, port);
ssl.setEnabledProtocols(ssl.getSupportedProtocols());
// set up SNI before the handshake
try {
java.lang.reflect.Method setHostnameMethod = ssl.getClass()
.getMethod("setHostname", String.class);
setHostnameMethod.invoke(ssl, peerHost);
} catch (Exception e) {
FileLog.w(TAG, "SNI not useable", e);
}
return ssl;
}
}不幸的是,它还有另一个问题,它不能再重用连接,这意味着每个请求都必须进行tcp握手和ssl握手,这将花费大量的时间。
所以我的问题是,有没有办法用HttpsUrlConnection解决直接IP请求的问题?
如果没有,我如何才能按照上面提到的方式重用连接。
发布于 2017-11-29 05:59:30
试试这个:
conn.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});https://stackoverflow.com/questions/40926773
复制相似问题