2016-04-08 7 views
0

Ich habe eine Anwendung, die verwendet:Fehler geworfen in OKHttpClient Version 3.2.0 mit SPDY Version 3

compile 'com.squareup.okhttp3:okhttp:2.7.0' 
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0' 
compile 'com.squareup.okio:okio:1.6.0' 
compile 'com.squareup.retrofit2:retrofit:2.0.0' 
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3' 

Und macht API REST auf einen Server aufruft. Wenn SPDY 3 auf der OKHttpClient ermöglichen, wird ein Fehler ausgelöst:

04-08 11:01:22.321 10628-10628/dts W/System.err: java.lang.IllegalArgumentException: protocols doesn't contain http/1.1: [spdy/3.1, h2] 
04-08 11:01:22.321 10628-10628/dts W/System.err: at okhttp3.OkHttpClient$Builder.protocols(OkHttpClient.java:672) 

ich nichts auf OKHttpClient finden SPDY/3 oder der Fehler korrekt Code ermöglicht. Auf der Zielwebsite ist SPDY/3 korrekt konfiguriert.

I beide Protokoll configs mit allen Kombinationen von SPDY3 versucht haben, HTTP/2 & HTTP/1 arbeitet Anwendung, wenn HTTP/1 konfiguriert, aber wirft Fehler, wenn SPDY/3 nur dann aktiviert wird:

okHttpClient = new OkHttpClient.Builder() 
        // .protocols(Collections.singletonList(Protocol.SPDY_3)) 
        .protocols(Arrays.asList(Protocol.SPDY_3, Protocol.HTTP_2)) 
        .retryOnConnectionFailure(true) 
        .connectTimeout(25, TimeUnit.SECONDS) 
        .connectionPool(new ConnectionPool(30, 120, TimeUnit.SECONDS)) 
        .connectionSpecs(Collections.singletonList(spec)) 
        .addInterceptor(new AddCookiesInterceptor()) 
        .addInterceptor(new ReceivedCookiesInterceptor()) 
        .cache(new okhttp3.Cache(cacheLocation, (500 * 1024 * 1024))) 
        .build(); 
     } 

Ich weiß, jemand kann Ideen haben, jede Hilfe würde sehr geschätzt werden.

+0

ich dies in der Dokumentation gefunden [link] (https://square.github.io/okhttp/2.x/okhttp/com/squareup/okhttp/OkHttpClient.html) aber ohne Hilfe bei der Konfiguration SPDY/3: Parameter: Protokolle - die Protokolle zu verwenden, in der Reihenfolge der Präferenz. Die Liste muss Protocol.HTTP_1_1 enthalten. Es darf weder null noch Protocol.HTTP_1_0 enthalten. – DoctorD

Antwort

0

Offenbar hat die neueste Version von OKHttp Unterstützung für SPDY/3 fallen gelassen. Der Fehlercode wird ausgelöst, wenn nur Proto SPDY oder HTTP2 ausgewählt wird. In der Dokumentation wird darauf hingewiesen, dass HTTP1 immer als Proto- koll und zusätzliche Auswahl nach benötigt wird. Wenn Sie mit Android 4.1 zu HTTP2 wechseln und weitere Verbindungsprobleme auftreten (OKHttp/Android) unterstützt nicht standardmäßig TLS1.2, müssen Sie eine benutzerdefinierte SSLSocketFactory erstellen, um die Standardeinstellungen zu überschreiben (von here):

public class TLSSocketFactory extends SSLSocketFactory { 

private SSLSocketFactory delegate; 

public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { 
    SSLContext context = SSLContext.getInstance("TLS"); 
    context.init(null, null, null); 
    delegate = context.getSocketFactory(); 
} 

@Override 
public String[] getDefaultCipherSuites() { 
    return new String[]{"TLSv1.2", "TLS_RSA_WITH_AES_128_CBC_SHA"}; 
} 

@Override 
public String[] getSupportedCipherSuites() { 
    return new String[]{"TLSv1.2", "TLS_RSA_WITH_AES_128_CBC_SHA"}; 
} 

@Override 
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { 
    return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose)); 
} 

@Override 
public Socket createSocket(String host, int port) throws IOException, UnknownHostException { 
    return enableTLSOnSocket(delegate.createSocket(host, port)); 
} 

@Override 
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { 
    return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort)); 
} 

@Override 
public Socket createSocket(InetAddress host, int port) throws IOException { 
    return enableTLSOnSocket(delegate.createSocket(host, port)); 
} 

@Override 
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { 
    return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort)); 
} 

private Socket enableTLSOnSocket(Socket socket) { 
    if (socket != null && (socket instanceof SSLSocket)) { 
     ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"}); 
    } 
    return socket; 
} 

}