1.1.2
ktor-client-okhttp 1.1.2
Android 4.2.2
Caught this crash accidentally, while performing request:
02-10 15:25:12.044 14612-14628/com.example.android.kotlincoroutines D/FA: Connected to remote service
02-10 15:25:12.046 14612-14628/com.example.android.kotlincoroutines V/FA: Processing queued up service tasks: 4
02-10 15:25:12.114 14612-14612/com.example.android.kotlincoroutines I/InputMethodManager: handleMessage: MSG_SET_ACTIVE true, was false
02-10 15:25:13.890 14612-14637/com.example.android.kotlincoroutines I/SurfaceTextureClient: [STC::queueBuffer] (this:0x4e60dab8) fps:12.93, dur:1856.73, max:1397.50, min:7.01
02-10 15:25:16.975 14612-14640/com.example.android.kotlincoroutines I/System.out: [socket][/192.168.1.183:46401] connected
02-10 15:25:16.978 14612-14640/com.example.android.kotlincoroutines W/dalvikvm: VFY: unable to find class referenced in signature (Ljava/nio/file/Path;)
02-10 15:25:16.979 14612-14640/com.example.android.kotlincoroutines W/dalvikvm: VFY: unable to find class referenced in signature ([Ljava/nio/file/OpenOption;)
02-10 15:25:16.981 14612-14640/com.example.android.kotlincoroutines I/dalvikvm: Could not find method java.nio.file.Files.newOutputStream, referenced from method okio.Okio.sink
02-10 15:25:16.982 14612-14640/com.example.android.kotlincoroutines W/dalvikvm: VFY: unable to resolve static method 350: Ljava/nio/file/Files;.newOutputStream (Ljava/nio/file/Path;[Ljava/nio/file/OpenOption;)Ljava/io/OutputStream;
02-10 15:25:16.982 14612-14640/com.example.android.kotlincoroutines D/dalvikvm: VFY: replacing opcode 0x71 at 0x0002
02-10 15:25:16.985 14612-14640/com.example.android.kotlincoroutines W/dalvikvm: VFY: unable to find class referenced in signature (Ljava/nio/file/Path;)
02-10 15:25:16.986 14612-14640/com.example.android.kotlincoroutines W/dalvikvm: VFY: unable to find class referenced in signature ([Ljava/nio/file/OpenOption;)
02-10 15:25:16.987 14612-14640/com.example.android.kotlincoroutines I/dalvikvm: Could not find method java.nio.file.Files.newInputStream, referenced from method okio.Okio.source
02-10 15:25:16.988 14612-14640/com.example.android.kotlincoroutines W/dalvikvm: VFY: unable to resolve static method 349: Ljava/nio/file/Files;.newInputStream (Ljava/nio/file/Path;[Ljava/nio/file/OpenOption;)Ljava/io/InputStream;
02-10 15:25:16.988 14612-14640/com.example.android.kotlincoroutines D/dalvikvm: VFY: replacing opcode 0x71 at 0x0002
02-10 15:25:17.003 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 NativeCrypto_SSL_do_handshake fd=0x1ef00005 shc=0x1f000009 timeout_millis=60000 client_mode=1 npn=0x0
02-10 15:25:17.004 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: doing handshake ++
02-10 15:25:17.004 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback where=0x10 ret=1
02-10 15:25:17.004 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 handshake start in UNKWN before/connect initialization
02-10 15:25:17.005 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback ignored
02-10 15:25:17.005 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback where=0x1001 ret=1
02-10 15:25:17.006 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 SSL_connect:UNKWN before/connect initialization
02-10 15:25:17.006 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback ignored
02-10 15:25:17.007 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback where=0x1001 ret=1
02-10 15:25:17.007 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 SSL_connect:23WCHA SSLv2/v3 write client hello A
02-10 15:25:17.007 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback ignored
02-10 15:25:17.008 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback where=0x1002 ret=-1
02-10 15:25:17.008 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 SSL_connect:error exit in 23RSHA SSLv2/v3 read server hello A
02-10 15:25:17.008 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback ignored
02-10 15:25:17.008 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: doing handshake -- ret=-1
02-10 15:25:17.009 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 NativeCrypto_SSL_do_handshake ret=-1 errno=11 sslError=2 timeout_millis=60000
02-10 15:25:17.009 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: sslSelect type=READ fd=59 appData=0x4f095528 timeout_millis=60000
02-10 15:25:17.017 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: sslSelect READ fd=59 appData=0x4f095528 timeout_millis=60000 => 1
02-10 15:25:17.017 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: doing handshake ++
02-10 15:25:17.017 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback where=0x1002 ret=-1
02-10 15:25:17.017 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 SSL_connect:error exit in 23RSHA SSLv2/v3 read server hello A
02-10 15:25:17.018 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 info_callback ignored
02-10 15:25:17.018 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: doing handshake -- ret=-1
02-10 15:25:17.018 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 NativeCrypto_SSL_do_handshake ret=-1 errno=104 sslError=5 timeout_millis=60000
02-10 15:25:17.018 14612-14640/com.example.android.kotlincoroutines E/NativeCrypto: Unknown error during handshake
02-10 15:25:17.019 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 NativeCrypto_SSL_do_handshake unclean error => 0
02-10 15:25:17.019 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x4f078a38 NativeCrypto_SSL_interrupt
02-10 15:25:17.020 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: sslNotify, appData=0x4f095528 ret=1
02-10 15:25:17.020 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: sslNotify, appData=0x4f095528 ret=1
02-10 15:25:17.021 14612-14640/com.example.android.kotlincoroutines I/System.out: [CDS]close[46401]
02-10 15:25:17.022 14612-14640/com.example.android.kotlincoroutines I/System.out: close [socket][/0.0.0.0:46401]
02-10 15:25:17.022 14612-14640/com.example.android.kotlincoroutines D/NativeCrypto: ssl=0x0 NativeCrypto_SSL_interrupt
02-10 15:25:17.023 14612-14640/com.example.android.kotlincoroutines I/System.out: close [socket][/0.0.0.0:46401]
02-10 15:25:17.065 14612-14612/com.example.android.kotlincoroutines E/AndroidRuntime: FATAL EXCEPTION: main
javax.net.ssl.SSLException: SSL handshake aborted: ssl=0x4f078a38: I/O error during system call, Connection reset by peer
at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java)
at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:318)
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:282)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:167)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:147)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
at java.lang.Thread.run(Thread.java)
02-10 15:25:20.087 14612-14612/com.example.android.kotlincoroutines I/Process: Sending signal. PID: 14612 SIG: 9
Hi @gabin8, thanks for the report.
Could you provide the request URL? It looks like the problem in server certificates.
@e5l
The urls:
https://tls-v1-1.badssl.com:1011/
https://tls-v1-2.badssl.com:1012/
The issue is related to TLS support on Android 4.x.
Android supports TLS v1.1 and v1.2 from API 16, but enables it by default only from API 20.
I followed the article to write extension function for OkHttpBuilder to enable Tls 1.1-1.2 support
Here's the gist of extension file https://gist.github.com/gabin8/9459d0a00ffdf40ed023a0cf85a5d58e
But ktor doesn't work either. The initialization code:
private val client: HttpClient by lazy {
HttpClient {
engine {
OkHttp.create {
config {
OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.retryOnConnectionFailure(true)
.cache(null)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.enableTlsOnPreLollipop()
.build()
}
}
}
}
}
private suspend fun makeRequest(url: String) {
try {
Log.d(TAG, "Started loading $url")
val content = client.get<String>(url)
Log.d(TAG, "Finished loading $url")
responseLiveData.postValue(content)
} catch (e: Exception) {
Log.d(TAG, "Got exception for $url: ${e.message}")
e.printStackTrace()
responseLiveData.postValue(e.message)
}
}
To check that my extension function works fine I've wrote the method using OkHttp library
private fun makeOkHttpRequest(url: String) {
val client = OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.retryOnConnectionFailure(true)
.cache(null)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.enableTlsOnPreLollipop()
.build()
val request = Request.Builder()
.url(url)
.build()
client.newCall(request).enqueue(object: Callback {
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
responseLiveData.postValue(response.body()?.string())
}
})
}
So both snippets are similar , but ktor doesn't work in that case
Still present in 1.1.3
I've created test project that reproduces the issue https://github.com/gabin8/KtorBug946
The video of the bug: https://www.dropbox.com/s/d5sj3q4tk46qglq/ktor_bug_903.mp4?dl=0
It seems that SSLSocketFactory isn't called in ktor-okhttp client at all
The bug is not longer valid, because since version 1.2.0 ktor uses OkHttp client that is no longer available for Android 4.x (okhttp 3.13+)
The OkHttp 3.12.x branch supports Android 2.3+ (API level 9+) and Java 7+