2016-04-08 2 views
0

У меня есть приложение, которое использует:Ошибка выброшен в OKHttpClient версии 3.2.0 с использованием SPDY версии 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' 

И делает API REST вызовы к серверу. При включении SPDY 3 на OKHttpClient, выдается ошибка:

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) 

Я не могу найти что-нибудь на OKHttpClient правильно позволяет SPDY/3 или код ошибки. На целевом сайте настроен SPDY/3.

Я попытался как конфиги протокол со всеми комбо SPDY3, HTTP/2 & HTTP/1, приложение работает, когда HTTP/1 сконфигурирован, но бросает ошибку, если SPDY/3 включен только:

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(); 
     } 

Я знаю, что у кого-то могут быть идеи, любая помощь будет очень признательна.

+0

Я нашел это в документации [ссылка] (https://square.github.io/okhttp/2.x/okhttp/com/squareup/okhttp/OkHttpClient.html) но без помощи при настройке SPDY/3: Параметры: протоколы - протоколы для использования в порядке предпочтения. Список должен содержать протокол.HTTP_1_1. Он не должен содержать null или Protocol.HTTP_1_0. – DoctorD

ответ

0

По-видимому, новейшая версия OKHttp отказалась от поддержки SPDY/3. Код ошибки вызывается при выборе только протокола SPDY или HTTP2. В документации отмечается, что HTTP1 всегда требуется в качестве прото и дополнительные варианты после. Переключившись на HTTP2 с Android 4.1, и вы найдете дополнительные проблемы с подключением (OKHttp/Android) не поддерживает TLS1.2 из коробки, вам придется создать настраиваемый SSLSocketFactory, чтобы переопределить значения по умолчанию (от 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; 
} 

}

Смежные вопросы