httpsurlconnection带有IP问题


String currentUrl = "https://www.test.com/";
conn = (HttpsURLConnection) (currentUrl.openConnection())

如果我使用域,一切正常。

但是,如果我使用域的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请求问题?

如果否,我该如何根据上述内容重复使用连接。

尝试以下:

conn.setHostnameVerifier(new HostnameVerifier() {
   @Override
   public boolean verify(String hostname, SSLSession session) {
         return true;
    }
});

最新更新