2016-12-02 2 views
0
String currentUrl = "https://www.test.com/"; 
conn = (HttpsURLConnection) (currentUrl.openConnection()) 

도메인을 사용하는 경우 모든 것이 완벽하게 작동합니다. 내가 도메인의 IP 주소를IP 문제가있는 HttpsURL 연결

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 요청 문제를 해결하려면 무엇입니까?

만약 아니라면, 위에서 언급 한 것에 따라 어떻게 연결을 재사용 할 수 있습니까?

답변

0

이 시도 :

conn.setHostnameVerifier(new HostnameVerifier() { 

    @Override 
    public boolean verify(String hostname, SSLSession session) { 
     return true; 
    } 

});